File indexing completed on 2024-05-12 03:45:46

0001 /*
0002     SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "polynode.h"
0007 
0008 #include <QPolygon>
0009 #include <QSGFlatColorMaterial>
0010 #include <QSGGeometry>
0011 #include <QSGGeometryNode>
0012 
0013 extern "C" {
0014 #include "libtess/tessellate.h"
0015 }
0016 
0017 PolyNode::PolyNode() : m_geometryNode(new QSGGeometryNode), m_material(new QSGFlatColorMaterial)
0018 {
0019     m_geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
0020     m_geometryNode->setGeometry(m_geometry);
0021     m_geometryNode->setFlag(QSGNode::OwnsGeometry);
0022 
0023     m_geometryNode->setOpaqueMaterial(m_material);
0024     m_geometryNode->setFlag(QSGNode::OwnsMaterial);
0025 
0026     appendChildNode(m_geometryNode);
0027 }
0028 
0029 void PolyNode::setColor(QColor color)
0030 {
0031     if (color != m_material->color())
0032     {
0033         m_material->setColor(color);
0034         m_geometryNode->markDirty(QSGNode::DirtyMaterial);
0035     }
0036 }
0037 
0038 void PolyNode::setLineWidth(int width)
0039 {
0040     if (width != m_geometry->lineWidth())
0041     {
0042         m_geometry->setLineWidth(width);
0043         m_geometryNode->markDirty(QSGNode::DirtyGeometry);
0044     }
0045 }
0046 
0047 void PolyNode::updateGeometry(const QPolygonF &polygon, bool filled)
0048 {
0049     if (!filled)
0050     {
0051         m_geometry->setDrawingMode(GL_LINE_STRIP);
0052         int size = polygon.size();
0053         m_geometry->allocate(size);
0054 
0055         QSGGeometry::Point2D *vertex = m_geometry->vertexDataAsPoint2D();
0056 
0057         for (int i = 0; i < size; ++i)
0058         {
0059             vertex[i].x = polygon[i].x();
0060             vertex[i].y = polygon[i].y();
0061         }
0062     }
0063     else
0064     {
0065         m_geometry->setDrawingMode(GL_TRIANGLES);
0066 
0067         double *coordinates_out;
0068         int *tris_out;
0069         int nverts, ntris, i;
0070         QPolygonF pol = polygon;
0071         int polySize = pol.size() * 2;
0072         std::vector<double> vertices_array(polySize);
0073 
0074         for (int i = 0; i < polySize; i += 2)
0075         {
0076             vertices_array[i]     = pol[i / 2].x();
0077             vertices_array[i + 1] = pol[i / 2].y();
0078         }
0079 
0080         const double *contours_array[] = { &vertices_array[0], &vertices_array[0] + polySize };
0081         int contours_size              = 2;
0082 
0083         tessellate(&coordinates_out, &nverts, &tris_out, &ntris, contours_array, contours_array + contours_size);
0084 
0085         m_geometry->allocate(3 * ntris);
0086         QSGGeometry::Point2D *vertex = m_geometry->vertexDataAsPoint2D();
0087 
0088         for (i = 0; i < 3 * ntris; ++i)
0089         {
0090             //int tris = tris_out[i];
0091             vertex[i].x = coordinates_out[tris_out[i] * 2];
0092             vertex[i].y = coordinates_out[tris_out[i] * 2 + 1];
0093         }
0094         free(coordinates_out);
0095         if (tris_out)
0096             free(tris_out);
0097     }
0098     m_geometryNode->markDirty(QSGNode::DirtyGeometry);
0099 }