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 }