diff --git a/src/core/CSGTreeEvaluator.cc b/src/core/CSGTreeEvaluator.cc index 9798f3450bc..6c9c04e5a37 100644 --- a/src/core/CSGTreeEvaluator.cc +++ b/src/core/CSGTreeEvaluator.cc @@ -10,12 +10,14 @@ #include "printutils.h" #include "GeometryEvaluator.h" #include "PolySet.h" +#include "PolySetBuilder.h" #include #include #include #include #include +#include /*! \class CSGTreeEvaluator @@ -168,16 +170,60 @@ Response CSGTreeEvaluator::visit(State& state, const class ListNode& node) } +std::shared_ptr polygon2dToPolySet(const Polygon2d &p2d) { + auto ps = p2d.tessellate(); + // Estimating num vertices and polygons + PolySetBuilder builder(ps->vertices.size() * 2, + ps->indices.size() * 2 + ps->vertices.size(), + 2, p2d.is_convex()); + builder.setConvexity(p2d.getConvexity()); + + // Create bottom face. + for (const auto& poly : ps->indices) { + builder.appendPoly(poly.size()); + // Flip vertex ordering for bottom polygon + for (const auto& ind: boost::adaptors::reverse(poly)) { + builder.appendVertex(ps->vertices[ind] - Vector3d(0, 0, 0.5)); + } + } + + // Create top face. + for (const auto& poly : ps->indices) { + builder.appendPoly(poly.size()); + for (const auto& ind: poly) { + builder.appendVertex(ps->vertices[ind] + Vector3d(0, 0, 0.5)); + } + } + + // Create sides + for (const auto& o : p2d.outlines()) { + for (size_t i = 0; i < o.vertices.size(); ++i) { + const Vector2d &prev = o.vertices[i]; + const Vector2d &curr = o.vertices[(i+1)%o.vertices.size()]; + builder.appendPoly({ + Vector3d(prev[0], prev[1], -0.5), + Vector3d(curr[0], curr[1], -0.5), + Vector3d(curr[0], curr[1], 0.5), + Vector3d(prev[0], prev[1], 0.5), + }); + } + } + + auto polyset = builder.build(); + return polyset; +} + + std::shared_ptr CSGTreeEvaluator::evaluateCSGNodeFromGeometry( State& state, const std::shared_ptr& geom, const ModuleInstantiation *modinst, const AbstractNode& node) { assert(geom); - // We cannot render Polygon2d directly, so we preprocess (tessellate) it here + // We cannot render Polygon2d directly, so we convert it to a PolySet here std::shared_ptr ps; if (!geom->isEmpty()) { if (auto p2d = std::dynamic_pointer_cast(geom)) { - ps = p2d->tessellate(); + ps = polygon2dToPolySet(*p2d); } // 3D PolySets are tessellated before inserting into Geometry cache, inside GeometryEvaluator::evaluateGeometry else { diff --git a/src/core/Selection.h b/src/core/Selection.h index df554793bca..f942a529923 100644 --- a/src/core/Selection.h +++ b/src/core/Selection.h @@ -25,13 +25,15 @@ */ #pragma once -#include -#include +#include "linalg.h" -enum { SELECTION_POINT, SELECTION_LINE}; +enum class SelectionType { + SELECTION_POINT, + SELECTION_LINE +}; struct SelectedObject { - int type; + SelectionType type; Vector3d p1; Vector3d p2; }; diff --git a/src/core/SurfaceNode.cc b/src/core/SurfaceNode.cc index c0ca27591d4..a6fb942d495 100644 --- a/src/core/SurfaceNode.cc +++ b/src/core/SurfaceNode.cc @@ -221,7 +221,8 @@ std::unique_ptr SurfaceNode::createGeometry() const double ox = center ? -(columns - 1) / 2.0 : 0; double oy = center ? -(lines - 1) / 2.0 : 0; - PolySetBuilder builder(0, (lines - 1) * (columns - 1) * 4 + (lines - 1) * 2 + (columns - 1) * 2 + 1); + int num_indices = (lines - 1) * (columns - 1) * 4 + (lines - 1) * 2 + (columns - 1) * 2 + 1; + PolySetBuilder builder(0, num_indices); builder.setConvexity(convexity); // the bulk of the heightmap for (int i = 1; i < lines; ++i) diff --git a/src/core/node.h b/src/core/node.h index 4ac0a292958..119280ef4fd 100644 --- a/src/core/node.h +++ b/src/core/node.h @@ -41,10 +41,6 @@ class AbstractNode : public BaseVisitable, public std::enable_shared_from_thisname(); } - /*! Should return a Geometry instance describing the node. Returns nullptr if smth. - goes wrong. This is only called by PolySetEvaluator, to make sure polysets - are inserted into the cache*/ - virtual class Geometry *evaluate_geometry(class PolySetEvaluator *) const { return nullptr; } const std::vector>& getChildren() const { return this->children; diff --git a/src/core/primitives.cc b/src/core/primitives.cc index 7461146b677..54bb05fbbce 100644 --- a/src/core/primitives.cc +++ b/src/core/primitives.cc @@ -130,7 +130,7 @@ std::unique_ptr CubeNode::createGeometry() const int cubeCorners=8; int cubeFaces=6; int dimension=3; - PolySetBuilder builder(cubeCorners,cubeFaces,dimension,true); + PolySetBuilder builder(cubeCorners, cubeFaces, dimension, true); int corner[cubeCorners]; for(int i=0;i SphereNode::createGeometry() const auto fragments = Calc::get_fragments_from_r(r, fn, fs, fa); int rings = (fragments + 1) / 2; - PolySetBuilder builder(0,rings * fragments + 2,3,true); + PolySetBuilder builder(0, rings * fragments + 2, 3, true); // Uncomment the following three lines to enable experimental sphere tessellation // if (rings % 2 == 0) rings++; // To ensure that the middle ring is at phi == 0 degrees @@ -307,7 +307,7 @@ std::unique_ptr CylinderNode::createGeometry() const generate_circle(circle1.data(), r1, fragments); generate_circle(circle2.data(), r2, fragments); - PolySetBuilder builder(0,fragments * 2 + 2,3,true); + PolySetBuilder builder(0, fragments * 2 + 2, 3, true); for (int i = 0; i < fragments; ++i) { int j = (i + 1) % fragments; diff --git a/src/geometry/GeometryEvaluator.cc b/src/geometry/GeometryEvaluator.cc index 5da2c509a89..7c57e1c6190 100644 --- a/src/geometry/GeometryEvaluator.cc +++ b/src/geometry/GeometryEvaluator.cc @@ -49,6 +49,11 @@ GeometryEvaluator::GeometryEvaluator(const Tree& tree) : tree(tree) { } /*! Set allownef to false to force the result to _not_ be a Nef polyhedron + + There are some guarantees on the returned geometry: + * 2D and 3D geometry cannot be mixed; we will return either _only_ 2D or _only_ 3D geometries + * PolySet geometries are always 3D. 2D Polysets are only created for special-purpose rendering operations downstream from here. + * Needs validation: Implementation-specific geometries shouldn't be mixed (Nef polyhedron, Manifold, CGAL Hybrid polyhedrons) */ std::shared_ptr GeometryEvaluator::evaluateGeometry(const AbstractNode& node, bool allownef) @@ -1047,7 +1052,6 @@ static Outline2d splitOutlineByFn( return o2; } - /*! Input to extrude should be sanitized. This means non-intersecting, correct winding order etc., the input coming from a library like Clipper. @@ -1058,7 +1062,7 @@ static std::unique_ptr extrudePolygon(const LinearExtrudeNode& node, c boost::tribool isConvex{poly.is_convex()}; // Twist or non-uniform scale makes convex polygons into unknown polyhedrons if (isConvex && non_linear) isConvex = unknown; - PolySetBuilder builder(0,0,3,isConvex); + PolySetBuilder builder(0, 0, 3, isConvex); builder.setConvexity(node.convexity); if (node.height <= 0) return std::make_unique(3); diff --git a/src/geometry/PolySet.cc b/src/geometry/PolySet.cc index f889972c5ff..bcfd83bddc1 100644 --- a/src/geometry/PolySet.cc +++ b/src/geometry/PolySet.cc @@ -50,10 +50,6 @@ PolySet::PolySet(unsigned int dim, boost::tribool convex) : dim(dim), convex(con { } -PolySet::PolySet(Polygon2d origin) : polygon(std::move(origin)), dim(2), convex(unknown), dirty(true) -{ -} - std::unique_ptr PolySet::copy() const { return std::make_unique(*this); } @@ -65,7 +61,6 @@ std::string PolySet::dump() const << "\n dimensions:" << this->dim << "\n convexity:" << this->convexity << "\n num polygons: " << indices.size() - << "\n num outlines: " << polygon.outlines().size() << "\n polygons data:"; for (const auto& polygon : indices) { out << "\n polygon begin:"; @@ -73,8 +68,6 @@ std::string PolySet::dump() const out << "\n vertex:" << this->vertices[v].transpose(); } } - out << "\n outlines data:"; - out << polygon.dump(); out << "\nPolySet end"; return out.str(); } @@ -97,7 +90,6 @@ size_t PolySet::memsize() const size_t mem = 0; for (const auto& p : this->indices) mem += p.size() * sizeof(int); for (const auto& p : this->vertices) mem += p.size() * sizeof(Vector3d); - mem += this->polygon.memsize() - sizeof(this->polygon); mem += sizeof(PolySet); return mem; } diff --git a/src/geometry/PolySet.h b/src/geometry/PolySet.h index 2568e63b213..9277713b9a3 100644 --- a/src/geometry/PolySet.h +++ b/src/geometry/PolySet.h @@ -19,9 +19,6 @@ class PolySet : public Geometry std::vector vertices; PolySet(unsigned int dim, boost::tribool convex = unknown); - PolySet(Polygon2d origin); - - const Polygon2d& getPolygon() const { return polygon; } size_t memsize() const override; BoundingBox getBoundingBox() const override; @@ -40,7 +37,6 @@ class PolySet : public Geometry bool isTriangular = false; private: - Polygon2d polygon; unsigned int dim; mutable boost::tribool convex; mutable BoundingBox bbox; diff --git a/src/geometry/PolySetBuilder.cc b/src/geometry/PolySetBuilder.cc index 74d3d9ad4bd..eb4affba60e 100644 --- a/src/geometry/PolySetBuilder.cc +++ b/src/geometry/PolySetBuilder.cc @@ -38,18 +38,12 @@ #endif PolySetBuilder::PolySetBuilder(int vertices_count, int indices_count, int dim, boost::tribool convex) - : dim_(dim), convex_(convex) + : convex_(convex), dim_(dim) { if (vertices_count != 0) vertices_.reserve(vertices_count); if (indices_count != 0) indices_.reserve(indices_count); } -PolySetBuilder::PolySetBuilder(const Polygon2d& polygon2d) - : polygon2d_(polygon2d), dim_(2), convex_(unknown) -{ -} - - void PolySetBuilder::setConvexity(int convexity){ convexity_ = convexity; } @@ -94,7 +88,7 @@ void PolySetBuilder::appendGeometry(const std::shared_ptr& geom) append(*mani->toPolySet()); #endif } else if (std::dynamic_pointer_cast(geom)) { // NOLINT(bugprone-branch-clone) - assert(false && "Unsupported file format"); + assert(false && "Unsupported geometry"); } else { // NOLINT(bugprone-branch-clone) assert(false && "Not implemented"); } @@ -148,12 +142,7 @@ void PolySetBuilder::append(const PolySet& ps) std::unique_ptr PolySetBuilder::build() { std::unique_ptr polyset; - if (!polygon2d_.isEmpty()) { - polyset = std::make_unique(polygon2d_); - } - else { - polyset = std::make_unique(dim_, convex_); - } + polyset = std::make_unique(dim_, convex_); vertices_.copy(std::back_inserter(polyset->vertices)); polyset->indices = std::move(indices_); polyset->setConvexity(convexity_); diff --git a/src/geometry/PolySetBuilder.h b/src/geometry/PolySetBuilder.h index a6705ce5ca5..fc5cc4d4791 100644 --- a/src/geometry/PolySetBuilder.h +++ b/src/geometry/PolySetBuilder.h @@ -13,7 +13,6 @@ class PolySetBuilder { public: PolySetBuilder(int vertices_count = 0, int indices_count = 0, int dim = 3, boost::tribool convex = unknown); - PolySetBuilder(const Polygon2d& polygon2d); void setConvexity(int n); int vertexIndex(const Vector3d& coord); int numVertices() const; @@ -30,7 +29,6 @@ class PolySetBuilder private: Reindexer vertices_; PolygonIndices indices_; - Polygon2d polygon2d_; int convexity_{1}; int dim_; boost::tribool convex_; diff --git a/src/geometry/cgal/Polygon2d-CGAL.cc b/src/geometry/cgal/Polygon2d-CGAL.cc index b0578720eb2..3430c9f0974 100644 --- a/src/geometry/cgal/Polygon2d-CGAL.cc +++ b/src/geometry/cgal/Polygon2d-CGAL.cc @@ -88,11 +88,11 @@ mark_domains(CDT& cdt) /*! Triangulates this polygon2d and returns a 2D-in-3D PolySet. - */ +*/ std::unique_ptr Polygon2d::tessellate() const { PRINTDB("Polygon2d::tessellate(): %d outlines", this->outlines().size()); - PolySetBuilder builder(*this); + PolySetBuilder builder(0, 0, 2, unknown); Polygon2DCGAL::CDT cdt; // Uses a constrained Delaunay triangulator. diff --git a/src/geometry/cgal/cgalutils-mesh.cc b/src/geometry/cgal/cgalutils-mesh.cc index 11da1dd1de0..c2e30b763af 100644 --- a/src/geometry/cgal/cgalutils-mesh.cc +++ b/src/geometry/cgal/cgalutils-mesh.cc @@ -44,7 +44,7 @@ template bool createMeshFromPolySet(const PolySet& ps, CGAL_DoubleMesh& mesh); template std::unique_ptr createPolySetFromMesh(const TriangleMesh& mesh) { - PolySetBuilder builder(0,mesh.number_of_faces()+ mesh.number_of_faces()); + PolySetBuilder builder(0, mesh.number_of_faces()+ mesh.number_of_faces()); for (const auto& f : mesh.faces()) { builder.appendPoly(mesh.degree(f)); diff --git a/src/geometry/cgal/cgalutils-polyhedron.cc b/src/geometry/cgal/cgalutils-polyhedron.cc index 640dcfd565b..c7ca46283bc 100644 --- a/src/geometry/cgal/cgalutils-polyhedron.cc +++ b/src/geometry/cgal/cgalutils-polyhedron.cc @@ -285,7 +285,7 @@ std::unique_ptr createPolySetFromPolyhedron(const Polyhedron& p) using FCI = typename Polyhedron::Facet_const_iterator; using HFCC = typename Polyhedron::Halfedge_around_facet_const_circulator; - PolySetBuilder builder(0,p.size_of_facets()); + PolySetBuilder builder(0, p.size_of_facets()); for (FCI fi = p.facets_begin(); fi != p.facets_end(); ++fi) { HFCC hc = fi->facet_begin(); diff --git a/src/geometry/cgal/cgalutils.cc b/src/geometry/cgal/cgalutils.cc index 295011b99e9..aef325fc1b2 100644 --- a/src/geometry/cgal/cgalutils.cc +++ b/src/geometry/cgal/cgalutils.cc @@ -376,7 +376,7 @@ std::unique_ptr createPolySetFromNefPolyhedron3(const CGAL::Nef_polyhed LOG(message_group::Error, "Non-manifold mesh created: %1$d unconnected edges", unconnected2); } - PolySetBuilder builder(verts.size(),allTriangles.size()); + PolySetBuilder builder(verts.size(), allTriangles.size()); std::vector indMap; indMap.reserve(verts.size()); for (const auto &v : verts) { diff --git a/src/glview/GLView.cc b/src/glview/GLView.cc index 45e54a42aab..a183555067d 100644 --- a/src/glview/GLView.cc +++ b/src/glview/GLView.cc @@ -397,7 +397,7 @@ void GLView::showObject(const SelectedObject &obj, const Vector3d &eyedir) { auto vd = cam.zoomValue()/200.0; switch(obj.type) { - case SELECTION_POINT: + case SelectionType::SELECTION_POINT: { double n=1/sqrt(3); // create an octaeder @@ -421,7 +421,7 @@ void GLView::showObject(const SelectedObject &obj, const Vector3d &eyedir) glEnd(); } break; - case SELECTION_LINE: + case SelectionType::SELECTION_LINE: { Vector3d diff=obj.p2-obj.p1; Vector3d wdir=eyedir.cross(diff).normalized()*vd/2.0; diff --git a/src/glview/LegacyRendererUtils.cc b/src/glview/LegacyRendererUtils.cc index 0284b76d171..e75602db948 100644 --- a/src/glview/LegacyRendererUtils.cc +++ b/src/glview/LegacyRendererUtils.cc @@ -84,159 +84,28 @@ static void gl_draw_triangle(const Renderer::shaderinfo_t *shaderinfo, const Vec } } -void render_surface(const PolySet& ps, Renderer::csgmode_e csgmode, const Transform3d& m, const Renderer::shaderinfo_t *shaderinfo) +void render_surface(const PolySet& ps, const Transform3d& m, const Renderer::shaderinfo_t *shaderinfo) { PRINTD("render_surface"); bool mirrored = m.matrix().determinant() < 0; - if (ps.getDimension() == 2) { - // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0); + for (const auto& poly : ps.indices) { glBegin(GL_TRIANGLES); - - // Render top+bottom - for (double z : {-zbase / 2, zbase / 2}) { - for (const auto& poly : ps.indices) { - if (poly.size() == 3) { - if (z < 0) { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(2)], ps.vertices[poly.at(1)], true, true, true, z, mirrored); - } else { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(2)], true, true, true, z, mirrored); - } - } else if (poly.size() == 4) { - if (z < 0) { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(3)], ps.vertices[poly.at(1)], false, true, true, z, mirrored); - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(2)], ps.vertices[poly.at(1)], ps.vertices[poly.at(3)], false, true, true, z, mirrored); - } else { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(3)], false, true, true, z, mirrored); - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(2)], ps.vertices[poly.at(3)], ps.vertices[poly.at(1)], false, true, true, z, mirrored); - } - } else { - Vector3d center = Vector3d::Zero(); - for (const auto& point : poly) { - center[0] += ps.vertices[point][0]; - center[1] += ps.vertices[point][1]; - } - center /= poly.size(); - for (size_t j = 1; j <= poly.size(); ++j) { - if (z < 0) { - gl_draw_triangle(shaderinfo, center, ps.vertices[poly.at(j % poly.size())], ps.vertices[poly.at(j - 1)], - true, false, false, z, mirrored); - } else { - gl_draw_triangle(shaderinfo, center, ps.vertices[poly.at(j - 1)], ps.vertices[poly.at(j % poly.size())], - true, false, false, z, mirrored); - } - } - } - } - } - - // Render sides - if (ps.getPolygon().outlines().size() > 0) { - for (const Outline2d& o : ps.getPolygon().outlines()) { - for (size_t j = 1; j <= o.vertices.size(); ++j) { - Vector3d p1(o.vertices[j - 1][0], o.vertices[j - 1][1], -zbase / 2); - Vector3d p2(o.vertices[j - 1][0], o.vertices[j - 1][1], zbase / 2); - Vector3d p3(o.vertices[j % o.vertices.size()][0], o.vertices[j % o.vertices.size()][1], -zbase / 2); - Vector3d p4(o.vertices[j % o.vertices.size()][0], o.vertices[j % o.vertices.size()][1], zbase / 2); - gl_draw_triangle(shaderinfo, p2, p1, p3, true, false, true, 0, mirrored); - gl_draw_triangle(shaderinfo, p2, p3, p4, true, true, false, 0, mirrored); - } - } + if (poly.size() == 3) { + gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(2)], true, true, true, 0, mirrored); + } else if (poly.size() == 4) { + gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(3)], false, true, true, 0, mirrored); + gl_draw_triangle(shaderinfo, ps.vertices[poly.at(2)], ps.vertices[poly.at(3)], ps.vertices[poly.at(1)], false, true, true, 0, mirrored); } else { - // If we don't have borders, use the polygons as borders. - // FIXME: When is this used? - const std::vector *borders_p = &ps.indices; - for (const auto& poly : *borders_p) { - for (size_t j = 1; j <= poly.size(); ++j) { - Vector3d p1 = ps.vertices[poly.at(j - 1)], p2 = ps.vertices[poly.at(j - 1)]; - Vector3d p3 = ps.vertices[poly.at(j % poly.size())], p4 = ps.vertices[poly.at(j % poly.size())]; - p1[2] -= zbase / 2, p2[2] += zbase / 2; - p3[2] -= zbase / 2, p4[2] += zbase / 2; - gl_draw_triangle(shaderinfo, p2, p1, p3, true, false, true, 0, mirrored); - gl_draw_triangle(shaderinfo, p2, p3, p4, true, true, false, 0, mirrored); - } + Vector3d center = Vector3d::Zero(); + for (const auto& point : poly) { + center += ps.vertices[point]; } - } - glEnd(); - } else if (ps.getDimension() == 3) { - for (const auto& poly : ps.indices) { - glBegin(GL_TRIANGLES); - if (poly.size() == 3) { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(2)], true, true, true, 0, mirrored); - } else if (poly.size() == 4) { - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(0)], ps.vertices[poly.at(1)], ps.vertices[poly.at(3)], false, true, true, 0, mirrored); - gl_draw_triangle(shaderinfo, ps.vertices[poly.at(2)], ps.vertices[poly.at(3)], ps.vertices[poly.at(1)], false, true, true, 0, mirrored); - } else { - Vector3d center = Vector3d::Zero(); - for (const auto& point : poly) { - center += ps.vertices[point]; - } - center /= poly.size(); - for (size_t j = 1; j <= poly.size(); ++j) { - gl_draw_triangle(shaderinfo, center, ps.vertices[poly.at(j - 1)], ps.vertices[poly.at(j % poly.size())], true, false, false, 0, mirrored); - } + center /= poly.size(); + for (size_t j = 1; j <= poly.size(); ++j) { + gl_draw_triangle(shaderinfo, center, ps.vertices[poly.at(j - 1)], ps.vertices[poly.at(j % poly.size())], true, false, false, 0, mirrored); } - glEnd(); } - } else { - assert(false && "Cannot render object with no dimension"); - } -} - -/*! This is used in throwntogether and CGAL mode - - csgmode is set to CSGMODE_NONE in CGAL mode. In this mode a pure 2D rendering is performed. - - For some reason, this is not used to render edges in Preview mode - */ -void render_edges(const PolySet& ps, Renderer::csgmode_e csgmode) -{ - glDisable(GL_LIGHTING); - if (ps.getDimension() == 2) { - if (csgmode == Renderer::CSGMODE_NONE) { - // Render only outlines - for (const Outline2d& o : ps.getPolygon().outlines()) { - glBegin(GL_LINE_LOOP); - for (const Vector2d& v : o.vertices) { - glVertex3d(v[0], v[1], 0); - } - glEnd(); - } - } else { - // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0); - - for (const Outline2d& o : ps.getPolygon().outlines()) { - // Render top+bottom outlines - for (double z : { -zbase / 2, zbase / 2}) { - glBegin(GL_LINE_LOOP); - for (const Vector2d& v : o.vertices) { - glVertex3d(v[0], v[1], z); - } - glEnd(); - } - // Render sides - glBegin(GL_LINES); - for (const Vector2d& v : o.vertices) { - glVertex3d(v[0], v[1], -zbase / 2); - glVertex3d(v[0], v[1], +zbase / 2); - } - glEnd(); - } - } - } else if (ps.getDimension() == 3) { - for (const auto& polygon : ps.indices) { - const IndexedFace *poly = &polygon; - glBegin(GL_LINE_LOOP); - for (const auto& ind : *poly) { - Vector3d p=ps.vertices[ind]; - glVertex3d(p[0], p[1], p[2]); - } - glEnd(); - } - } else { - assert(false && "Cannot render object with no dimension"); + glEnd(); } - glEnable(GL_LIGHTING); } diff --git a/src/glview/LegacyRendererUtils.h b/src/glview/LegacyRendererUtils.h index cca71b53911..4d4217f69e0 100644 --- a/src/glview/LegacyRendererUtils.h +++ b/src/glview/LegacyRendererUtils.h @@ -6,5 +6,4 @@ #include "PolySet.h" #include "Renderer.h" -void render_surface(const PolySet& geom, Renderer::csgmode_e csgmode, const Transform3d& m, const Renderer::shaderinfo_t *shaderinfo = nullptr); -void render_edges(const PolySet& geom, Renderer::csgmode_e csgmode); +void render_surface(const PolySet& geom, const Transform3d& m, const Renderer::shaderinfo_t *shaderinfo = nullptr); diff --git a/src/glview/Renderer.cc b/src/glview/Renderer.cc index 9952f7f5886..10d235d0422 100644 --- a/src/glview/Renderer.cc +++ b/src/glview/Renderer.cc @@ -107,7 +107,7 @@ Renderer::Renderer() PRINTDB("OpenGL Program Validation results:\n%s", logbuffer); } - renderer_shader.progid = edgeshader_prog; // 0 + renderer_shader.progid = edgeshader_prog; renderer_shader.type = EDGE_RENDERING; renderer_shader.data.csg_rendering.color_area = glGetUniformLocation(edgeshader_prog, "color1"); // 1 renderer_shader.data.csg_rendering.color_edge = glGetUniformLocation(edgeshader_prog, "color2"); // 2 diff --git a/src/glview/VBORenderer.cc b/src/glview/VBORenderer.cc index 7a79755e996..a06f7c4b367 100644 --- a/src/glview/VBORenderer.cc +++ b/src/glview/VBORenderer.cc @@ -67,35 +67,34 @@ bool VBORenderer::getShaderColor(Renderer::ColorMode colormode, const Color4f& c return false; } -size_t VBORenderer::getSurfaceBufferSize(const std::shared_ptr& products, bool highlight_mode, bool background_mode, bool unique_geometry) const +size_t VBORenderer::getSurfaceBufferSize(const std::shared_ptr& products, bool unique_geometry) const { size_t buffer_size = 0; if (unique_geometry) this->geomVisitMark.clear(); for (const auto& product : products->products) { for (const auto& csgobj : product.intersections) { - buffer_size += getSurfaceBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::INTERSECTION); + buffer_size += getSurfaceBufferSize(csgobj); } for (const auto& csgobj : product.subtractions) { - buffer_size += getSurfaceBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE); + buffer_size += getSurfaceBufferSize(csgobj); } } return buffer_size; } -size_t VBORenderer::getSurfaceBufferSize(const CSGChainObject& csgobj, bool highlight_mode, bool background_mode, const OpenSCADOperator type, bool unique_geometry) const +size_t VBORenderer::getSurfaceBufferSize(const CSGChainObject& csgobj, bool unique_geometry) const { size_t buffer_size = 0; if (unique_geometry && this->geomVisitMark[std::make_pair(csgobj.leaf->polyset.get(), &csgobj.leaf->matrix)]++ > 0) return 0; - csgmode_e csgmode = get_csgmode(highlight_mode, background_mode, type); if (csgobj.leaf->polyset) { - buffer_size += getSurfaceBufferSize(*csgobj.leaf->polyset, csgmode); + buffer_size += getSurfaceBufferSize(*csgobj.leaf->polyset); } return buffer_size; } -size_t VBORenderer::getSurfaceBufferSize(const PolySet& polyset, csgmode_e csgmode) const +size_t VBORenderer::getSurfaceBufferSize(const PolySet& polyset) const { size_t buffer_size = 0; for (const auto& poly : polyset.indices) { @@ -104,72 +103,28 @@ size_t VBORenderer::getSurfaceBufferSize(const PolySet& polyset, csgmode_e csgmo } else if (poly.size() == 4) { buffer_size += 2; } else { + // poly.size() because we'll render a triangle fan from the centroid buffer_size += poly.size(); } } - if (polyset.getDimension() == 2) { - if (csgmode != CSGMODE_NONE) { - buffer_size *= 2; // top and bottom - // sides - if (polyset.getPolygon().outlines().size() > 0) { - for (const Outline2d& o : polyset.getPolygon().outlines()) { - buffer_size += o.vertices.size() * 2; - } - } else { - for (const auto& poly : polyset.indices) { - buffer_size += poly.size() * 2; - } - } - } - } return buffer_size * 3; } -size_t VBORenderer::getEdgeBufferSize(const std::shared_ptr& products, bool highlight_mode, bool background_mode, bool unique_geometry) const +size_t VBORenderer::getEdgeBufferSize(const PolySet& polyset) const { size_t buffer_size = 0; - if (unique_geometry) this->geomVisitMark.clear(); - - for (const auto& product : products->products) { - for (const auto& csgobj : product.intersections) { - buffer_size += getEdgeBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::INTERSECTION, unique_geometry); - } - for (const auto& csgobj : product.subtractions) { - buffer_size += getEdgeBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE, unique_geometry); - } + for (const auto& polygon : polyset.indices) { + buffer_size += polygon.size(); } return buffer_size; } -size_t VBORenderer::getEdgeBufferSize(const CSGChainObject& csgobj, bool highlight_mode, bool background_mode, const OpenSCADOperator type, bool unique_geometry) const +size_t VBORenderer::getEdgeBufferSize(const Polygon2d& polygon) const { size_t buffer_size = 0; - if (unique_geometry && this->geomVisitMark[std::make_pair(csgobj.leaf->polyset.get(), &csgobj.leaf->matrix)]++ > 0) return 0; - csgmode_e csgmode = get_csgmode(highlight_mode, background_mode, type); - - if (csgobj.leaf->polyset) { - buffer_size += getEdgeBufferSize(*csgobj.leaf->polyset, csgmode); - } - return buffer_size; -} - -size_t VBORenderer::getEdgeBufferSize(const PolySet& polyset, csgmode_e csgmode) const -{ - size_t buffer_size = 0; - if (polyset.getDimension() == 2) { - // Render only outlines - for (const Outline2d& o : polyset.getPolygon().outlines()) { - buffer_size += o.vertices.size(); - if (csgmode != CSGMODE_NONE) { - buffer_size += o.vertices.size(); - // Render sides - buffer_size += o.vertices.size() * 2; - } - } - } else if (polyset.getDimension() == 3) { - for (const auto& polygon : polyset.indices) { - buffer_size += polygon.size(); - } + // Render only outlines + for (const Outline2d& o : polygon.outlines()) { + buffer_size += o.vertices.size(); } return buffer_size; } @@ -315,71 +270,65 @@ void VBORenderer::create_surface(const PolySet& ps, VertexArray& vertex_array, bool mirrored = m.matrix().determinant() < 0; size_t triangle_count = 0; - if (ps.getDimension() == 2) { - create_polygons(ps, vertex_array, csgmode, m, color); - } else if (ps.getDimension() == 3) { - auto& vertex_states = vertex_array.states(); - std::unordered_map vert_mult_map; - size_t last_size = vertex_array.verticesOffset(); + auto& vertex_states = vertex_array.states(); + std::unordered_map vert_mult_map; + size_t last_size = vertex_array.verticesOffset(); - size_t elements_offset = 0; - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } + size_t elements_offset = 0; + if (vertex_array.useElements()) { + elements_offset = vertex_array.elementsOffset(); + vertex_array.elementsMap().clear(); + } - for (const auto& poly : ps.indices) { - if (poly.size() == 3) { - Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); + for (const auto& poly : ps.indices) { + if (poly.size() == 3) { + Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); - create_triangle(vertex_array, color, p0, p1, p2, - 0, 0, poly.size(), 3, false, mirrored); + create_triangle(vertex_array, color, p0, p1, p2, + 0, 0, poly.size(), 3, false, mirrored); + triangle_count++; + } else if (poly.size() == 4) { + Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); + Vector3d p3 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(3)], m); + + create_triangle(vertex_array, color, p0, p1, p3, + 0, 0, poly.size(), 3, false, mirrored); + create_triangle(vertex_array, color, p2, p3, p1, + 1, 0, poly.size(), 3, false, mirrored); + triangle_count += 2; + } else { + Vector3d center = Vector3d::Zero(); + for (const auto& idx : poly) { + center += ps.vertices[idx]; + } + center /= poly.size(); + for (size_t i = 1; i <= poly.size(); i++) { + Vector3d p0 = uniqueMultiply(vert_mult_map, center, m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i % poly.size())], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i - 1)], m); + + create_triangle(vertex_array, color, p0, p2, p1, + i - 1, 0, poly.size(), 3, false, mirrored); triangle_count++; - } else if (poly.size() == 4) { - Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); - Vector3d p3 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(3)], m); - - create_triangle(vertex_array, color, p0, p1, p3, - 0, 0, poly.size(), 3, false, mirrored); - create_triangle(vertex_array, color, p2, p3, p1, - 1, 0, poly.size(), 3, false, mirrored); - triangle_count += 2; - } else { - Vector3d center = Vector3d::Zero(); - for (const auto& point : poly) { - center += ps.vertices[point]; - } - center /= poly.size(); - for (size_t i = 1; i <= poly.size(); i++) { - Vector3d p0 = uniqueMultiply(vert_mult_map, center, m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i % poly.size())], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i - 1)], m); - - create_triangle(vertex_array, color, p0, p2, p1, - i - 1, 0, poly.size(), 3, false, mirrored); - triangle_count++; - } } } - - GLenum elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr vs = vertex_array.createVertexState( - GL_TRIANGLES, triangle_count * 3, elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(vs)); - vertex_array.addAttributePointers(last_size); - } else { - assert(false && "Cannot render object with no dimension"); } + + GLenum elements_type = 0; + if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); + std::shared_ptr vs = vertex_array.createVertexState( + GL_TRIANGLES, triangle_count * 3, elements_type, + vertex_array.writeIndex(), elements_offset); + vertex_states.emplace_back(std::move(vs)); + vertex_array.addAttributePointers(last_size); } -void VBORenderer::create_edges(const PolySet& ps, - VertexArray& vertex_array, csgmode_e csgmode, +void VBORenderer::create_edges(const Polygon2d& polygon, + VertexArray& vertex_array, const Transform3d& m, const Color4f& color) const { @@ -390,111 +339,34 @@ void VBORenderer::create_edges(const PolySet& ps, auto& vertex_states = vertex_array.states(); std::unordered_map vert_mult_map; - if (ps.getDimension() == 2) { - if (csgmode == Renderer::CSGMODE_NONE) { - // Render only outlines - for (const Outline2d& o : ps.getPolygon().outlines()) { - size_t last_size = vertex_array.verticesOffset(); - size_t elements_offset = 0; - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } - for (const Vector2d& v : o.vertices) { - Vector3d p0 = uniqueMultiply(vert_mult_map, Vector3d(v[0], v[1], 0.0), m); - - create_vertex(vertex_array, color, {p0}, {}, 0, 0, 0.0, o.vertices.size(), 2, true, false); - } - - GLenum elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr line_loop = vertex_array.createVertexState( - GL_LINE_LOOP, o.vertices.size(), elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(line_loop)); - vertex_array.addAttributePointers(last_size); - } - } else { - // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0.0); - for (const Outline2d& o : ps.getPolygon().outlines()) { - size_t last_size = vertex_array.verticesOffset(); - size_t elements_offset = 0; - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } - - // Render top+bottom outlines - for (double z : {-zbase / 2, zbase / 2}) { - for (const Vector2d& v : o.vertices) { - Vector3d p0 = uniqueMultiply(vert_mult_map, Vector3d(v[0], v[1], z), m); - - create_vertex(vertex_array, color, {p0}, {}, 0, 0, 0.0, o.vertices.size() * 2, 2, true, false); - } - } - - GLenum elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr line_loop = vertex_array.createVertexState( - GL_LINE_LOOP, o.vertices.size() * 2, elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(line_loop)); - vertex_array.addAttributePointers(last_size); - - last_size = vertex_array.verticesOffset(); - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } - // Render sides - for (const Vector2d& v : o.vertices) { - Vector3d p0 = uniqueMultiply(vert_mult_map, Vector3d(v[0], v[1], -zbase / 2), m); - Vector3d p1 = uniqueMultiply(vert_mult_map, Vector3d(v[0], v[1], +zbase / 2), m); - - create_vertex(vertex_array, color, {p0, p1}, {}, 0, 0, 0.0, o.vertices.size(), 2, true, false); - create_vertex(vertex_array, color, {p0, p1}, {}, 1, 0, 0.0, o.vertices.size(), 2, true, false); - } - - elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr lines = vertex_array.createVertexState( - GL_LINES, o.vertices.size() * 2, elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(lines)); - vertex_array.addAttributePointers(last_size); - } + // Render only outlines + for (const Outline2d& o : polygon.outlines()) { + size_t last_size = vertex_array.verticesOffset(); + size_t elements_offset = 0; + if (vertex_array.useElements()) { + elements_offset = vertex_array.elementsOffset(); + vertex_array.elementsMap().clear(); } - } else if (ps.getDimension() == 3) { - for (const auto& polygon : ps.indices) { - size_t last_size = vertex_array.verticesOffset(); - size_t elements_offset = 0; - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } - for (const auto& vertex : polygon) { - Vector3d p = uniqueMultiply(vert_mult_map, ps.vertices[vertex], m); + for (const Vector2d& v : o.vertices) { + Vector3d p0 = uniqueMultiply(vert_mult_map, Vector3d(v[0], v[1], 0.0), m); - create_vertex(vertex_array, color, {p}, {}, 0, 0, 0.0, polygon.size(), 2, true, false); - } - - GLenum elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr line_loop = vertex_array.createVertexState( - GL_LINE_LOOP, polygon.size(), elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(line_loop)); - vertex_array.addAttributePointers(last_size); + create_vertex(vertex_array, color, {p0}, {}, 0, 0, 0.0, o.vertices.size(), 2, true, false); } - } else { - assert(false && "Cannot render object with no dimension"); + + GLenum elements_type = 0; + if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); + std::shared_ptr line_loop = vertex_array.createVertexState( + GL_LINE_LOOP, o.vertices.size(), elements_type, + vertex_array.writeIndex(), elements_offset); + vertex_states.emplace_back(std::move(line_loop)); + vertex_array.addAttributePointers(last_size); } } void VBORenderer::create_polygons(const PolySet& ps, VertexArray& vertex_array, - csgmode_e csgmode, const Transform3d& m, const Color4f& color) const + const Transform3d& m, const Color4f& color) const { + assert(ps.getDimension() == 2); std::shared_ptr vertex_data = vertex_array.data(); if (!vertex_data) return; @@ -502,195 +374,64 @@ void VBORenderer::create_polygons(const PolySet& ps, VertexArray& vertex_array, auto& vertex_states = vertex_array.states(); std::unordered_map vert_mult_map; - if (ps.getDimension() == 2) { - PRINTD("create_polygons 2D"); - bool mirrored = m.matrix().determinant() < 0; - size_t triangle_count = 0; - size_t last_size = vertex_array.verticesOffset(); - size_t elements_offset = 0; - if (vertex_array.useElements()) { - elements_offset = vertex_array.elementsOffset(); - vertex_array.elementsMap().clear(); - } + PRINTD("create_polygons 2D"); + bool mirrored = m.matrix().determinant() < 0; + size_t triangle_count = 0; + size_t last_size = vertex_array.verticesOffset(); + size_t elements_offset = 0; + if (vertex_array.useElements()) { + elements_offset = vertex_array.elementsOffset(); + vertex_array.elementsMap().clear(); + } - if (csgmode == Renderer::CSGMODE_NONE) { - PRINTD("create_polygons CSGMODE_NONE"); - for (const auto& poly : ps.indices) { - if (poly.size() == 3) { - Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); - - create_triangle(vertex_array, color, p0, p1, p2, - 0, 0, poly.size(), 2, false, mirrored); - triangle_count++; - } else if (poly.size() == 4) { - Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); - Vector3d p3 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(3)], m); - - create_triangle(vertex_array, color, p0, p1, p3, - 0, 0, poly.size(), 2, false, mirrored); - create_triangle(vertex_array, color, p2, p3, p1, - 1, 0, poly.size(), 2, false, mirrored); - triangle_count += 2; - } else { - Vector3d center = Vector3d::Zero(); - for (const auto& point : poly) { - center[0] += ps.vertices[point][0]; - center[1] += ps.vertices[point][1]; - } - center[0] /= poly.size(); - center[1] /= poly.size(); - - for (size_t i = 1; i <= poly.size(); i++) { - Vector3d p0 = uniqueMultiply(vert_mult_map, center, m); - Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i % poly.size())], m); - Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i - 1)], m); - - create_triangle(vertex_array, color, p0, p2, p1, - i - 1, 0, poly.size(), 2, false, mirrored); - triangle_count++; - } - } - } + for (const auto& poly : ps.indices) { + if (poly.size() == 3) { + Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); + + create_triangle(vertex_array, color, p0, p1, p2, + 0, 0, poly.size(), 2, false, mirrored); + triangle_count++; + } else if (poly.size() == 4) { + Vector3d p0 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(0)], m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(1)], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(2)], m); + Vector3d p3 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(3)], m); + + create_triangle(vertex_array, color, p0, p1, p3, + 0, 0, poly.size(), 2, false, mirrored); + create_triangle(vertex_array, color, p2, p3, p1, + 1, 0, poly.size(), 2, false, mirrored); + triangle_count += 2; } else { - PRINTD("create_polygons 1mm thick"); - // Render 2D objects 1mm thick, but differences slightly larger - double zbase = 1 + ((csgmode & CSGMODE_DIFFERENCE_FLAG) ? 0.1 : 0.0); - // Render top+bottom - for (double z : { -zbase / 2, zbase / 2}) { - for (const auto& poly : ps.indices) { - if (poly.size() == 3) { - Vector3d p0 = ps.vertices[poly.at(0)]; p0[2] += z; - Vector3d p1 = ps.vertices[poly.at(1)]; p1[2] += z; - Vector3d p2 = ps.vertices[poly.at(2)]; p2[2] += z; - - p0 = uniqueMultiply(vert_mult_map, p0, m); - p1 = uniqueMultiply(vert_mult_map, p1, m); - p2 = uniqueMultiply(vert_mult_map, p2, m); - - if (z < 0) { - create_triangle(vertex_array, color, p0, p2, p1, - 0, z, poly.size(), 2, false, mirrored); - } else { - create_triangle(vertex_array, color, p0, p1, p2, - 0, z, poly.size(), 2, false, mirrored); - } - triangle_count++; - } else if (poly.size() == 4) { - Vector3d p0 = ps.vertices[poly.at(0)]; p0[2] += z; - Vector3d p1 = ps.vertices[poly.at(1)]; p1[2] += z; - Vector3d p2 = ps.vertices[poly.at(2)]; p2[2] += z; - Vector3d p3 = ps.vertices[poly.at(3)]; p3[2] += z; - - p0 = uniqueMultiply(vert_mult_map, p0, m); - p1 = uniqueMultiply(vert_mult_map, p1, m); - p2 = uniqueMultiply(vert_mult_map, p2, m); - p3 = uniqueMultiply(vert_mult_map, p3, m); - - if (z < 0) { - create_triangle(vertex_array, color, p0, p3, p1, - 0, z, poly.size(), 2, false, mirrored); - create_triangle(vertex_array, color, p2, p1, p3, - 1, z, poly.size(), 2, false, mirrored); - } else { - create_triangle(vertex_array, color, p0, p1, p3, - 0, z, poly.size(), 2, false, mirrored); - create_triangle(vertex_array, color, p2, p3, p1, - 1, z, poly.size(), 2, false, mirrored); - } - triangle_count += 2; - } else { - Vector3d center = Vector3d::Zero(); - for (const auto& point : poly) { - center[0] += ps.vertices[point][0]; - center[1] += ps.vertices[point][1]; - } - center[0] /= poly.size(); - center[1] /= poly.size(); - - for (size_t i = 1; i <= poly.size(); i++) { - Vector3d p0 = center; p0[2] += z; - Vector3d p1 = ps.vertices[poly.at(i % poly.size())]; p1[2] += z; - Vector3d p2 = ps.vertices[poly.at(i - 1)]; p2[2] += z; - - p0 = uniqueMultiply(vert_mult_map, p0, m); - p1 = uniqueMultiply(vert_mult_map, p1, m); - p2 = uniqueMultiply(vert_mult_map, p2, m); - - if (z < 0) { - create_triangle(vertex_array, color, p0, p1, p2, - i - 1, z, poly.size(), 2, false, mirrored); - } else { - create_triangle(vertex_array, color, p0, p2, p1, - i - 1, z, poly.size(), 2, false, mirrored); - } - triangle_count++; - } - } - } + Vector3d center = Vector3d::Zero(); + for (const auto& point : poly) { + center[0] += ps.vertices[point][0]; + center[1] += ps.vertices[point][1]; } + center[0] /= poly.size(); + center[1] /= poly.size(); - // Render sides - if (ps.getPolygon().outlines().size() > 0) { - PRINTD("Render outlines as sides"); - for (const Outline2d& o : ps.getPolygon().outlines()) { - for (size_t i = 1; i <= o.vertices.size(); i++) { - Vector3d p1 = Vector3d(o.vertices[i - 1][0], o.vertices[i - 1][1], -zbase / 2); - Vector3d p2 = Vector3d(o.vertices[i - 1][0], o.vertices[i - 1][1], zbase / 2); - Vector3d p3 = Vector3d(o.vertices[i % o.vertices.size()][0], o.vertices[i % o.vertices.size()][1], -zbase / 2); - Vector3d p4 = Vector3d(o.vertices[i % o.vertices.size()][0], o.vertices[i % o.vertices.size()][1], zbase / 2); - - p1 = uniqueMultiply(vert_mult_map, p1, m); - p2 = uniqueMultiply(vert_mult_map, p2, m); - p3 = uniqueMultiply(vert_mult_map, p3, m); - p4 = uniqueMultiply(vert_mult_map, p4, m); - - create_triangle(vertex_array, color, p2, p1, p3, - 0, 0, o.vertices.size(), 2, true, mirrored); - create_triangle(vertex_array, color, p2, p3, p4, - 1, 0, o.vertices.size(), 2, true, mirrored); - triangle_count += 2; - } - } - } else { - // If we don't have borders, use the polygons as borders. - // FIXME: When is this used? - PRINTD("Render sides with polygons"); - for (const auto& poly : ps.indices) { - for (size_t i = 1; i <= poly.size(); i++) { - Vector3d p1 = ps.vertices[poly.at(i - 1)]; p1[2] -= zbase / 2; - Vector3d p2 = ps.vertices[poly.at(i - 1)]; p2[2] += zbase / 2; - Vector3d p3 = ps.vertices[poly.at(i % poly.size())]; p3[2] -= zbase / 2; - Vector3d p4 = ps.vertices[poly.at(i % poly.size())]; p4[2] += zbase / 2; - - p1 = uniqueMultiply(vert_mult_map, p1, m); - p2 = uniqueMultiply(vert_mult_map, p2, m); - p3 = uniqueMultiply(vert_mult_map, p3, m); - p4 = uniqueMultiply(vert_mult_map, p4, m); - - create_triangle(vertex_array, color, p2, p1, p3, - 0, 0, poly.size(), 2, true, mirrored); - create_triangle(vertex_array, color, p2, p3, p4, - 1, 0, poly.size(), 2, true, mirrored); - triangle_count += 2; - } - } + for (size_t i = 1; i <= poly.size(); i++) { + Vector3d p0 = uniqueMultiply(vert_mult_map, center, m); + Vector3d p1 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i % poly.size())], m); + Vector3d p2 = uniqueMultiply(vert_mult_map, ps.vertices[poly.at(i - 1)], m); + + create_triangle(vertex_array, color, p0, p2, p1, + i - 1, 0, poly.size(), 2, false, mirrored); + triangle_count++; } } - - GLenum elements_type = 0; - if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); - std::shared_ptr vs = vertex_array.createVertexState( - GL_TRIANGLES, triangle_count * 3, elements_type, - vertex_array.writeIndex(), elements_offset); - vertex_states.emplace_back(std::move(vs)); - vertex_array.addAttributePointers(last_size); - } else { - assert(false && "Cannot render object with no dimension"); } + + GLenum elements_type = 0; + if (vertex_array.useElements()) elements_type = vertex_array.elementsData()->glType(); + std::shared_ptr vs = vertex_array.createVertexState( + GL_TRIANGLES, triangle_count * 3, elements_type, + vertex_array.writeIndex(), elements_offset); + vertex_states.emplace_back(std::move(vs)); + vertex_array.addAttributePointers(last_size); } void VBORenderer::add_shader_data(VertexArray& vertex_array) diff --git a/src/glview/VBORenderer.h b/src/glview/VBORenderer.h index 700f8b7526b..e7cb251b185 100644 --- a/src/glview/VBORenderer.h +++ b/src/glview/VBORenderer.h @@ -24,21 +24,20 @@ class VBORenderer : public Renderer VBORenderer(); void resize(int w, int h) override; virtual bool getShaderColor(Renderer::ColorMode colormode, const Color4f& col, Color4f& outcolor) const; - virtual size_t getSurfaceBufferSize(const std::shared_ptr& products, bool highlight_mode, bool background_mode, bool unique_geometry = false) const; - virtual size_t getSurfaceBufferSize(const CSGChainObject& csgobj, bool highlight_mode, bool background_mode, const OpenSCADOperator type = OpenSCADOperator::UNION, bool unique_geometry = false) const; - virtual size_t getSurfaceBufferSize(const PolySet& polyset, csgmode_e csgmode = CSGMODE_NORMAL) const; - virtual size_t getEdgeBufferSize(const std::shared_ptr& products, bool highlight_mode, bool background_mode, bool unique_geometry = false) const; - virtual size_t getEdgeBufferSize(const CSGChainObject& csgobj, bool highlight_mode, bool background_mode, const OpenSCADOperator type = OpenSCADOperator::UNION, bool unique_geometry = false) const; - virtual size_t getEdgeBufferSize(const PolySet& polyset, csgmode_e csgmode = CSGMODE_NORMAL) const; + virtual size_t getSurfaceBufferSize(const std::shared_ptr& products, bool unique_geometry = false) const; + virtual size_t getSurfaceBufferSize(const CSGChainObject& csgobj, bool unique_geometry = false) const; + virtual size_t getSurfaceBufferSize(const PolySet& polyset) const; + virtual size_t getEdgeBufferSize(const PolySet& polyset) const; + virtual size_t getEdgeBufferSize(const Polygon2d& polygon) const; virtual void create_surface(const PolySet& ps, VertexArray& vertex_array, csgmode_e csgmode, const Transform3d& m, const Color4f& color) const; - virtual void create_edges(const PolySet& ps, VertexArray& vertex_array, - csgmode_e csgmode, const Transform3d& m, const Color4f& color) const; + virtual void create_edges(const Polygon2d& polygon, VertexArray& vertex_array, + const Transform3d& m, const Color4f& color) const; virtual void create_polygons(const PolySet& ps, VertexArray& vertex_array, - csgmode_e csgmode, const Transform3d& m, const Color4f& color) const; + const Transform3d& m, const Color4f& color) const; virtual void create_triangle(VertexArray& vertex_array, const Color4f& color, const Vector3d& p0, const Vector3d& p1, const Vector3d& p2, diff --git a/src/glview/cgal/CGALRenderUtils.cc b/src/glview/cgal/CGALRenderUtils.cc index 5e5887fc30f..3d694489adf 100644 --- a/src/glview/cgal/CGALRenderUtils.cc +++ b/src/glview/cgal/CGALRenderUtils.cc @@ -17,7 +17,7 @@ double calculateLineLineDistance(const Vector3d &l1b, const Vector3d &l1e, const } double t=n.norm(); n.normalize(); - d=n.dot(l1b-l2b); + d=n.dot(l1b-l2b); dist_lat=(v2.cross(n)).dot(l2b-l1b)/t; return d; } diff --git a/src/glview/cgal/CGALRenderer.cc b/src/glview/cgal/CGALRenderer.cc index e33cd4c45a2..4b65ae89194 100644 --- a/src/glview/cgal/CGALRenderer.cc +++ b/src/glview/cgal/CGALRenderer.cc @@ -29,57 +29,64 @@ #include #endif +#include "Feature.h" #include "PolySet.h" #include "PolySetUtils.h" #include "printutils.h" -#include "Feature.h" -#include "CGALRenderer.h" #include "CGALRenderUtils.h" +#include "CGALRenderer.h" #ifdef ENABLE_CGAL -#include "CGAL_OGL_VBOPolyhedron.h" #include "CGALHybridPolyhedron.h" +#include "CGAL_OGL_VBOPolyhedron.h" #endif #ifdef ENABLE_MANIFOLD #include "ManifoldGeometry.h" #endif -//#include "Preferences.h" +// #include "Preferences.h" -CGALRenderer::CGALRenderer(const std::shared_ptr& geom) -{ +CGALRenderer::CGALRenderer(const std::shared_ptr &geom) { this->addGeometry(geom); PRINTD("CGALRenderer::CGALRenderer() -> createPolyhedrons()"); #ifdef ENABLE_CGAL - if (!this->nefPolyhedrons.empty() && this->polyhedrons.empty()) createPolyhedrons(); + if (!this->nefPolyhedrons.empty() && this->polyhedrons.empty()) + createPolyhedrons(); #endif } -void CGALRenderer::addGeometry(const std::shared_ptr& geom) -{ - if (const auto geomlist = std::dynamic_pointer_cast(geom)) { - for (const auto& item : geomlist->getChildren()) { +void CGALRenderer::addGeometry(const std::shared_ptr &geom) { + if (const auto geomlist = + std::dynamic_pointer_cast(geom)) { + for (const auto &item : geomlist->getChildren()) { this->addGeometry(item.second); } } else if (const auto ps = std::dynamic_pointer_cast(geom)) { assert(ps->getDimension() == 3); - // We need to tessellate here, in case the generated PolySet contains concave polygons - // See tests/data/scad/3D/features/polyhedron-concave-test.scad + // We need to tessellate here, in case the generated PolySet contains + // concave polygons See + // tests/data/scad/3D/features/polyhedron-concave-test.scad this->polysets.push_back(PolySetUtils::tessellate_faces(*ps)); - } else if (const auto poly = std::dynamic_pointer_cast(geom)) { - this->polysets.push_back(std::shared_ptr(poly->tessellate())); + } else if (const auto poly = + std::dynamic_pointer_cast(geom)) { + this->polygons.emplace_back( + poly, std::shared_ptr(poly->tessellate())); #ifdef ENABLE_CGAL - } else if (const auto new_N = std::dynamic_pointer_cast(geom)) { + } else if (const auto new_N = + std::dynamic_pointer_cast(geom)) { assert(new_N->getDimension() == 3); if (!new_N->isEmpty()) { this->nefPolyhedrons.push_back(new_N); } - } else if (const auto hybrid = std::dynamic_pointer_cast(geom)) { - // TODO(ochafik): Implement rendering of CGAL_HybridMesh (CGAL::Surface_mesh) instead. + } else if (const auto hybrid = + std::dynamic_pointer_cast(geom)) { + // TODO(ochafik): Implement rendering of CGAL_HybridMesh + // (CGAL::Surface_mesh) instead. this->polysets.push_back(hybrid->toPolySet()); #endif #ifdef ENABLE_MANIFOLD - } else if (const auto mani = std::dynamic_pointer_cast(geom)) { + } else if (const auto mani = + std::dynamic_pointer_cast(geom)) { this->polysets.push_back(mani->toPolySet()); #endif } else { @@ -87,8 +94,7 @@ void CGALRenderer::addGeometry(const std::shared_ptr& geom) } } -CGALRenderer::~CGALRenderer() -{ +CGALRenderer::~CGALRenderer() { if (polyset_vertices_vbo) { glDeleteBuffers(1, &polyset_vertices_vbo); } @@ -98,13 +104,13 @@ CGALRenderer::~CGALRenderer() } #ifdef ENABLE_CGAL -void CGALRenderer::createPolyhedrons() -{ +void CGALRenderer::createPolyhedrons() { PRINTD("createPolyhedrons"); this->polyhedrons.clear(); - for (const auto& N : this->nefPolyhedrons) { + for (const auto &N : this->nefPolyhedrons) { auto p = new CGAL_OGL_VBOPolyhedron(*this->colorscheme); - CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(*N->p3, p); + CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron( + *N->p3, p); // CGAL_NEF3_MARKED_FACET_COLOR <- CGAL_FACE_BACK_COLOR // CGAL_NEF3_UNMARKED_FACET_COLOR <- CGAL_FACE_FRONT_COLOR p->init(); @@ -115,96 +121,102 @@ void CGALRenderer::createPolyhedrons() #endif // Overridden from Renderer -void CGALRenderer::setColorScheme(const ColorScheme& cs) -{ +void CGALRenderer::setColorScheme(const ColorScheme &cs) { PRINTD("setColorScheme"); Renderer::setColorScheme(cs); - colormap[ColorMode::CGAL_FACE_2D_COLOR] = ColorMap::getColor(cs, RenderColor::CGAL_FACE_2D_COLOR); - colormap[ColorMode::CGAL_EDGE_2D_COLOR] = ColorMap::getColor(cs, RenderColor::CGAL_EDGE_2D_COLOR); + colormap[ColorMode::CGAL_FACE_2D_COLOR] = + ColorMap::getColor(cs, RenderColor::CGAL_FACE_2D_COLOR); + colormap[ColorMode::CGAL_EDGE_2D_COLOR] = + ColorMap::getColor(cs, RenderColor::CGAL_EDGE_2D_COLOR); #ifdef ENABLE_CGAL this->polyhedrons.clear(); // Mark as dirty #endif PRINTD("setColorScheme done"); } -void CGALRenderer::createPolySets() -{ - PRINTD("createPolySets() polyset"); +void CGALRenderer::createPolySetStates() { + PRINTD("createPolySetStates() polyset"); - polyset_states.clear(); + vertex_states.clear(); glGenBuffers(1, &polyset_vertices_vbo); if (Feature::ExperimentalVxORenderersIndexing.is_enabled()) { glGenBuffers(1, &polyset_elements_vbo); } - VertexArray vertex_array(std::make_unique(), polyset_states, polyset_vertices_vbo, polyset_elements_vbo); + VertexArray vertex_array(std::make_unique(), + vertex_states, polyset_vertices_vbo, + polyset_elements_vbo); vertex_array.addEdgeData(); vertex_array.addSurfaceData(); - size_t num_vertices = 0; - if (this->polysets.size()) { - for (const auto& polyset : this->polysets) { - num_vertices += getSurfaceBufferSize(*polyset); - num_vertices += getEdgeBufferSize(*polyset); - } + for (const auto &polyset : this->polysets) { + num_vertices += getSurfaceBufferSize(*polyset); + num_vertices += getEdgeBufferSize(*polyset); + } + for (const auto &[polygon, polyset] : this->polygons) { + num_vertices += getSurfaceBufferSize(*polyset); + num_vertices += getEdgeBufferSize(*polygon); } vertex_array.allocateBuffers(num_vertices); - for (const auto& polyset : this->polysets) { + for (const auto &polyset : this->polysets) { Color4f color; - PRINTD("polysets"); - if (polyset->getDimension() == 2) { - PRINTD("2d polysets"); - vertex_array.writeEdge(); - - std::shared_ptr init_state = std::make_shared(); - init_state->glEnd().emplace_back([]() { - GL_TRACE0("glDisable(GL_LIGHTING)"); - GL_CHECKD(glDisable(GL_LIGHTING)); - }); - polyset_states.emplace_back(std::move(init_state)); - - // Create 2D polygons - getColor(ColorMode::CGAL_FACE_2D_COLOR, color); - this->create_polygons(*polyset, vertex_array, CSGMODE_NONE, Transform3d::Identity(), color); - - std::shared_ptr edge_state = std::make_shared(); - edge_state->glBegin().emplace_back([]() { - GL_TRACE0("glDisable(GL_DEPTH_TEST)"); - GL_CHECKD(glDisable(GL_DEPTH_TEST)); - }); - edge_state->glBegin().emplace_back([]() { - GL_TRACE0("glLineWidth(2)"); - GL_CHECKD(glLineWidth(2)); - }); - polyset_states.emplace_back(std::move(edge_state)); - - // Create 2D edges - getColor(ColorMode::CGAL_EDGE_2D_COLOR, color); - this->create_edges(*polyset, vertex_array, CSGMODE_NONE, Transform3d::Identity(), color); - - std::shared_ptr end_state = std::make_shared(); - end_state->glBegin().emplace_back([]() { - GL_TRACE0("glEnable(GL_DEPTH_TEST)"); - GL_CHECKD(glEnable(GL_DEPTH_TEST)); - }); - polyset_states.emplace_back(std::move(end_state)); - } else { - PRINTD("3d polysets"); - vertex_array.writeSurface(); - - // Create 3D polygons - getColor(ColorMode::MATERIAL, color); - this->create_surface(*polyset, vertex_array, CSGMODE_NORMAL, Transform3d::Identity(), color); - } + PRINTD("3d polysets"); + vertex_array.writeSurface(); + + // Create 3D polygons + getColor(ColorMode::MATERIAL, color); + this->create_surface(*polyset, vertex_array, CSGMODE_NORMAL, + Transform3d::Identity(), color); } - if (this->polysets.size()) { + for (const auto &[polygon, polyset] : this->polygons) { + Color4f color; + + PRINTD("2d polygons"); + vertex_array.writeEdge(); + + std::shared_ptr init_state = std::make_shared(); + init_state->glEnd().emplace_back([]() { + GL_TRACE0("glDisable(GL_LIGHTING)"); + GL_CHECKD(glDisable(GL_LIGHTING)); + }); + vertex_states.emplace_back(std::move(init_state)); + + // Create 2D polygons + getColor(ColorMode::CGAL_FACE_2D_COLOR, color); + this->create_polygons(*polyset, vertex_array, Transform3d::Identity(), + color); + + std::shared_ptr edge_state = std::make_shared(); + edge_state->glBegin().emplace_back([]() { + GL_TRACE0("glDisable(GL_DEPTH_TEST)"); + GL_CHECKD(glDisable(GL_DEPTH_TEST)); + }); + edge_state->glBegin().emplace_back([]() { + GL_TRACE0("glLineWidth(2)"); + GL_CHECKD(glLineWidth(2)); + }); + vertex_states.emplace_back(std::move(edge_state)); + + // Create 2D edges + getColor(ColorMode::CGAL_EDGE_2D_COLOR, color); + this->create_edges(*polygon, vertex_array, Transform3d::Identity(), color); + + std::shared_ptr end_state = std::make_shared(); + end_state->glBegin().emplace_back([]() { + GL_TRACE0("glEnable(GL_DEPTH_TEST)"); + GL_CHECKD(glEnable(GL_DEPTH_TEST)); + }); + vertex_states.emplace_back(std::move(end_state)); + } + + if (!this->polysets.empty() || !this->polygons.empty()) { if (Feature::ExperimentalVxORenderersIndexing.is_enabled()) { GL_TRACE0("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)"); GL_CHECKD(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); @@ -216,19 +228,21 @@ void CGALRenderer::createPolySets() } } -void CGALRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, const shaderinfo_t * /*shaderinfo*/) -{ +void CGALRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, + const shaderinfo_t * /*shaderinfo*/) { PRINTD("prepare()"); - if (!polyset_states.size()) createPolySets(); + if (!vertex_states.size()) + createPolySetStates(); #ifdef ENABLE_CGAL - if (!this->nefPolyhedrons.empty() && this->polyhedrons.empty()) createPolyhedrons(); + if (!this->nefPolyhedrons.empty() && this->polyhedrons.empty()) + createPolyhedrons(); #endif PRINTD("prepare() end"); } -void CGALRenderer::draw(bool showfaces, bool showedges, const shaderinfo_t * /*shaderinfo*/) const -{ +void CGALRenderer::draw(bool showfaces, bool showedges, + const shaderinfo_t * /*shaderinfo*/) const { PRINTD("draw()"); // grab current state to restore after GLfloat current_point_size, current_line_width; @@ -239,8 +253,9 @@ void CGALRenderer::draw(bool showfaces, bool showedges, const shaderinfo_t * /*s GL_CHECKD(glGetFloatv(GL_POINT_SIZE, ¤t_point_size)); GL_CHECKD(glGetFloatv(GL_LINE_WIDTH, ¤t_line_width)); - for (const auto& polyset : polyset_states) { - if (polyset) polyset->draw(); + for (const auto &vertex_state : vertex_states) { + if (vertex_state) + vertex_state->draw(); } // restore states @@ -249,14 +264,19 @@ void CGALRenderer::draw(bool showfaces, bool showedges, const shaderinfo_t * /*s GL_TRACE("glLineWidth(%d)", current_line_width); GL_CHECKD(glLineWidth(current_line_width)); - if (!origVertexArrayState) glDisableClientState(GL_VERTEX_ARRAY); - if (!origNormalArrayState) glDisableClientState(GL_NORMAL_ARRAY); - if (!origColorArrayState) glDisableClientState(GL_COLOR_ARRAY); + if (!origVertexArrayState) + glDisableClientState(GL_VERTEX_ARRAY); + if (!origNormalArrayState) + glDisableClientState(GL_NORMAL_ARRAY); + if (!origColorArrayState) + glDisableClientState(GL_COLOR_ARRAY); #ifdef ENABLE_CGAL - for (const auto& p : this->getPolyhedrons()) { - if (showfaces) p->set_style(SNC_BOUNDARY); - else p->set_style(SNC_SKELETON); + for (const auto &p : this->getPolyhedrons()) { + if (showfaces) + p->set_style(SNC_BOUNDARY); + else + p->set_style(SNC_SKELETON); p->draw(showfaces && showedges); } #endif @@ -264,74 +284,86 @@ void CGALRenderer::draw(bool showfaces, bool showedges, const shaderinfo_t * /*s PRINTD("draw() end"); } -BoundingBox CGALRenderer::getBoundingBox() const -{ +BoundingBox CGALRenderer::getBoundingBox() const { BoundingBox bbox; #ifdef ENABLE_CGAL - for (const auto& p : this->getPolyhedrons()) { + for (const auto &p : this->getPolyhedrons()) { CGAL::Bbox_3 cgalbbox = p->bbox(); bbox.extend(BoundingBox( - Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()), - Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()))); + Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()), + Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()))); } #endif - for (const auto& ps : this->polysets) { + for (const auto &ps : this->polysets) { bbox.extend(ps->getBoundingBox()); } + for (const auto &[polygon, polyset] : this->polygons) { + bbox.extend(polygon->getBoundingBox()); + } return bbox; } -std::vector CGALRenderer::findModelObject(Vector3d near_pt, Vector3d far_pt,int mouse_x, int mouse_y, double tolerance) { - std::vector results; +std::vector +CGALRenderer::findModelObject(Vector3d near_pt, Vector3d far_pt, int mouse_x, + int mouse_y, double tolerance) { double dist_near; - double dist_nearest=NAN; + double dist_nearest = std::numeric_limits::max(); Vector3d pt1_nearest; Vector3d pt2_nearest; - for (const std::shared_ptr& ps : this->polysets) { - for(const Vector3d &pt: ps->vertices) { - double dist_pt= calculateLinePointDistance(near_pt, far_pt, pt, dist_near); - if(dist_pt < tolerance ) { - if(isnan(dist_nearest) || dist_near < dist_nearest) - { - dist_nearest=dist_near; - pt1_nearest=pt; - } + const auto find_nearest_point = [&](const std::vector &vertices){ + for (const Vector3d &pt : vertices) { + const double dist_pt = + calculateLinePointDistance(near_pt, far_pt, pt, dist_near); + if (dist_pt < tolerance && dist_near < dist_nearest) { + dist_nearest = dist_near; + pt1_nearest = pt; } } + }; + for (const std::shared_ptr &ps : this->polysets) { + find_nearest_point(ps->vertices); } - if(!isnan(dist_nearest)) { - SelectedObject obj; - obj.type = SELECTION_POINT; - obj.p1=pt1_nearest; - results.push_back(obj); - return results; + for (const auto &[polygon, ps] : this->polygons) { + find_nearest_point(ps->vertices); } - for (const std::shared_ptr& ps : this->polysets) { - for(const auto &pol : ps->indices) { - int n = pol.size(); - for(int i=0;i < n;i++ ) - { - int ind1=pol[i]; - int ind2=pol[(i+1)%n]; - double dist_lat; - double dist_norm= fabs(calculateLineLineDistance(ps->vertices[ind1], ps->vertices[ind2], near_pt, far_pt,dist_lat)); - if(dist_lat >= 0 && dist_lat <= 1 && dist_norm < tolerance ) { - dist_nearest=dist_lat; - pt1_nearest=ps->vertices[ind1]; - pt2_nearest=ps->vertices[ind2]; - } - } + if (dist_nearest < std::numeric_limits::max()) { + SelectedObject obj = { + .type = SelectionType::SELECTION_POINT, + .p1 = pt1_nearest + }; + return std::vector{obj}; + } + + const auto find_nearest_line = [&](const std::vector &vertices, const PolygonIndices& indices) { + for (const auto &poly : indices) { + for (int i = 0; i < poly.size(); i++) { + int ind1 = poly[i]; + int ind2 = poly[(i + 1) % poly.size()]; + double dist_lat; + double dist_norm = fabs(calculateLineLineDistance( + vertices[ind1], vertices[ind2], near_pt, far_pt, dist_lat)); + if (dist_lat >= 0 && dist_lat <= 1 && dist_norm < tolerance) { + dist_nearest = dist_lat; + pt1_nearest = vertices[ind1]; + pt2_nearest = vertices[ind2]; + } } - } - - if(!isnan(dist_nearest)) { - SelectedObject obj; - obj.type = SELECTION_LINE; - obj.p1=pt1_nearest; - obj.p2=pt2_nearest; - results.push_back(obj); - return results; + } + }; + for (const std::shared_ptr &ps : this->polysets) { + find_nearest_line(ps->vertices, ps->indices); + } + for (const auto &[polygon, ps] : this->polygons) { + find_nearest_line(ps->vertices, ps->indices); + } + if (dist_nearest < std::numeric_limits::max()) { + SelectedObject obj = { + .type = SelectionType::SELECTION_LINE, + .p1 = pt1_nearest, + .p2 = pt2_nearest, + }; + return std::vector{obj}; } - return results; + return {}; } diff --git a/src/glview/cgal/CGALRenderer.h b/src/glview/cgal/CGALRenderer.h index ec9f6e46750..95e31bb978b 100644 --- a/src/glview/cgal/CGALRenderer.h +++ b/src/glview/cgal/CGALRenderer.h @@ -23,19 +23,20 @@ class CGALRenderer : public VBORenderer private: void addGeometry(const std::shared_ptr& geom); #ifdef ENABLE_CGAL - const std::list>& getPolyhedrons() const { return this->polyhedrons; } + const std::vector>& getPolyhedrons() const { return this->polyhedrons; } void createPolyhedrons(); #endif - void createPolySets(); + void createPolySetStates(); bool last_render_state; // FIXME: this is temporary to make switching between renderers seamless. - std::list> polysets; + std::vector> polysets; + std::vector, std::shared_ptr>> polygons; #ifdef ENABLE_CGAL - std::list> polyhedrons; - std::list> nefPolyhedrons; + std::vector> polyhedrons; + std::vector> nefPolyhedrons; #endif - std::vector> polyset_states; + std::vector> vertex_states; GLuint polyset_vertices_vbo{0}; GLuint polyset_elements_vbo{0}; }; diff --git a/src/glview/cgal/LegacyCGALRenderer.cc b/src/glview/cgal/LegacyCGALRenderer.cc index bde9d7f1c4b..c1efd82aa91 100644 --- a/src/glview/cgal/LegacyCGALRenderer.cc +++ b/src/glview/cgal/LegacyCGALRenderer.cc @@ -30,6 +30,7 @@ #endif #include "PolySet.h" +#include "Polygon2d.h" #include "PolySetUtils.h" #include "printutils.h" @@ -66,7 +67,7 @@ void LegacyCGALRenderer::addGeometry(const std::shared_ptr& geom // See tests/data/scad/3D/features/polyhedron-concave-test.scad this->polysets.push_back(PolySetUtils::tessellate_faces(*ps)); } else if (const auto poly = std::dynamic_pointer_cast(geom)) { - this->polysets.push_back(std::shared_ptr(poly->tessellate())); + this->polygons.emplace_back(poly, std::shared_ptr(poly->tessellate())); #ifdef ENABLE_CGAL } else if (const auto new_N = std::dynamic_pointer_cast(geom)) { assert(new_N->getDimension() == 3); @@ -127,34 +128,45 @@ void LegacyCGALRenderer::draw(bool showfaces, bool showedges, const shaderinfo_t { PRINTD("draw()"); + for (const auto& polyset : this->polysets) { PRINTD("draw() polyset"); - if (polyset->getDimension() == 2) { - // Draw 2D polygons - glDisable(GL_LIGHTING); - setColor(ColorMode::CGAL_FACE_2D_COLOR); - - for (const auto& polygon : polyset->indices) { - glBegin(GL_POLYGON); - for (const auto& ind : polygon) { - Vector3d p=polyset->vertices[ind]; - glVertex3d(p[0], p[1], 0); - } - glEnd(); - } + // Draw 3D polygons + setColor(ColorMode::MATERIAL); + render_surface(*polyset, Transform3d::Identity()); + } + + for (const auto& [polygon, polyset] : this->polygons) { + PRINTD("draw() polygon2d"); + // Draw 2D polygon + glDisable(GL_LIGHTING); + setColor(ColorMode::CGAL_FACE_2D_COLOR); - // Draw 2D edges - glDisable(GL_DEPTH_TEST); - - glLineWidth(2); - setColor(ColorMode::CGAL_EDGE_2D_COLOR); - render_edges(*polyset, CSGMODE_NONE); - glEnable(GL_DEPTH_TEST); - } else { - // Draw 3D polygons - setColor(ColorMode::MATERIAL); - render_surface(*polyset, CSGMODE_NORMAL, Transform3d::Identity(), nullptr); + for (const auto& polygon : polyset->indices) { + glBegin(GL_POLYGON); + for (const auto& ind : polygon) { + Vector3d p=polyset->vertices[ind]; + glVertex3d(p[0], p[1], 0); + } + glEnd(); } + + // Draw 2D edges + glDisable(GL_DEPTH_TEST); + + glLineWidth(2); + setColor(ColorMode::CGAL_EDGE_2D_COLOR); + glDisable(GL_LIGHTING); + for (const Outline2d& o : polygon->outlines()) { + glBegin(GL_LINE_LOOP); + for (const Vector2d& v : o.vertices) { + glVertex3d(v[0], v[1], 0); + } + glEnd(); + } + glEnable(GL_LIGHTING); + + glEnable(GL_DEPTH_TEST); } #ifdef ENABLE_CGAL @@ -183,59 +195,72 @@ BoundingBox LegacyCGALRenderer::getBoundingBox() const for (const auto& ps : this->polysets) { bbox.extend(ps->getBoundingBox()); } + for (const auto& [polygon, polyset] : this->polygons) { + bbox.extend(polygon->getBoundingBox()); + } return bbox; } -std::vector LegacyCGALRenderer::findModelObject(Vector3d near_pt, Vector3d far_pt,int mouse_x, int mouse_y, double tolerance) { - std::vector results; +std::vector +LegacyCGALRenderer::findModelObject(Vector3d near_pt, Vector3d far_pt, int mouse_x, + int mouse_y, double tolerance) { double dist_near; - double dist_nearest=NAN; + double dist_nearest = std::numeric_limits::max(); Vector3d pt1_nearest; Vector3d pt2_nearest; - for (const std::shared_ptr& ps : this->polysets) { - for(const Vector3d &pt: ps->vertices) { - double dist_pt= calculateLinePointDistance(near_pt, far_pt, pt, dist_near); - if(dist_pt < tolerance ) { - if(isnan(dist_nearest) || dist_near < dist_nearest) - { - dist_nearest=dist_near; - pt1_nearest=pt; - } + const auto find_nearest_point = [&](const std::vector &vertices){ + for (const Vector3d &pt : vertices) { + const double dist_pt = + calculateLinePointDistance(near_pt, far_pt, pt, dist_near); + if (dist_pt < tolerance && dist_near < dist_nearest) { + dist_nearest = dist_near; + pt1_nearest = pt; } } + }; + for (const std::shared_ptr &ps : this->polysets) { + find_nearest_point(ps->vertices); } - if(!isnan(dist_nearest)) { - SelectedObject obj; - obj.type = SELECTION_POINT; - obj.p1=pt1_nearest; - results.push_back(obj); - return results; + for (const auto &[polygon, ps] : this->polygons) { + find_nearest_point(ps->vertices); } - for (const std::shared_ptr& ps : this->polysets) { - for(const auto &pol : ps->indices) { - int n = pol.size(); - for(int i=0;i < n;i++ ) - { - int ind1=pol[i]; - int ind2=pol[(i+1)%n]; - double dist_lat; - double dist_norm= fabs(calculateLineLineDistance(ps->vertices[ind1], ps->vertices[ind2], near_pt, far_pt,dist_lat)); - if(dist_lat >= 0 && dist_lat <= 1 && dist_norm < tolerance ) { - dist_nearest=dist_lat; - pt1_nearest=ps->vertices[ind1]; - pt2_nearest=ps->vertices[ind2]; - } - } + if (dist_nearest < std::numeric_limits::max()) { + SelectedObject obj = { + .type = SelectionType::SELECTION_POINT, + .p1 = pt1_nearest + }; + return std::vector{obj}; + } + + const auto find_nearest_line = [&](const std::vector &vertices, const PolygonIndices& indices) { + for (const auto &poly : indices) { + for (int i = 0; i < poly.size(); i++) { + int ind1 = poly[i]; + int ind2 = poly[(i + 1) % poly.size()]; + double dist_lat; + double dist_norm = fabs(calculateLineLineDistance( + vertices[ind1], vertices[ind2], near_pt, far_pt, dist_lat)); + if (dist_lat >= 0 && dist_lat <= 1 && dist_norm < tolerance) { + dist_nearest = dist_lat; + pt1_nearest = vertices[ind1]; + pt2_nearest = vertices[ind2]; + } } - } - - if(!isnan(dist_nearest)) { - SelectedObject obj; - obj.type = SELECTION_LINE; - obj.p1=pt1_nearest; - obj.p2=pt2_nearest; - results.push_back(obj); - return results; + } + }; + for (const std::shared_ptr &ps : this->polysets) { + find_nearest_line(ps->vertices, ps->indices); + } + for (const auto &[polygon, ps] : this->polygons) { + find_nearest_line(ps->vertices, ps->indices); + } + if (dist_nearest < std::numeric_limits::max()) { + SelectedObject obj = { + .type = SelectionType::SELECTION_LINE, + .p1 = pt1_nearest, + .p2 = pt2_nearest, + }; + return std::vector{obj}; } - return results; + return {}; } diff --git a/src/glview/cgal/LegacyCGALRenderer.h b/src/glview/cgal/LegacyCGALRenderer.h index 079fdb7c18a..5bfa7694e68 100644 --- a/src/glview/cgal/LegacyCGALRenderer.h +++ b/src/glview/cgal/LegacyCGALRenderer.h @@ -1,8 +1,11 @@ #pragma once #include +#include #include "Renderer.h" +#include "PolySet.h" +#include "Polygon2d.h" #ifdef ENABLE_CGAL #include "CGAL_OGL_Polyhedron.h" #include "CGAL_Nef_polyhedron.h" @@ -12,7 +15,7 @@ class LegacyCGALRenderer : public Renderer { public: - LegacyCGALRenderer(const std::shared_ptr& geom); + LegacyCGALRenderer(const std::shared_ptr& geom); ~LegacyCGALRenderer() override = default; void prepare(bool showfaces, bool showedges, const shaderinfo_t *shaderinfo = nullptr) override; void draw(bool showfaces, bool showedges, const shaderinfo_t *shaderinfo = nullptr) const override; @@ -21,14 +24,17 @@ class LegacyCGALRenderer : public Renderer std::vector findModelObject(Vector3d near_pt, Vector3d far_pt, int mouse_x, int mouse_y, double tolerance) override; private: - void addGeometry(const std::shared_ptr& geom); + void addGeometry(const std::shared_ptr& geom); #ifdef ENABLE_CGAL - const std::list>& getPolyhedrons() const { return this->polyhedrons; } + const std::vector>& getPolyhedrons() const { return this->polyhedrons; } void createPolyhedrons(); #endif - std::list> polysets; + std::vector> polysets; + // We're using a pair: The PolySet can represent the polygon itself, + // and we use the Polygon2d to render outlines + std::vector, std::shared_ptr>> polygons; #ifdef ENABLE_CGAL - std::list> polyhedrons; - std::list> nefPolyhedrons; + std::vector> polyhedrons; + std::vector> nefPolyhedrons; #endif }; diff --git a/src/glview/preview/LegacyOpenCSGRenderer.cc b/src/glview/preview/LegacyOpenCSGRenderer.cc index 64a51baee8e..a33f39d06c4 100644 --- a/src/glview/preview/LegacyOpenCSGRenderer.cc +++ b/src/glview/preview/LegacyOpenCSGRenderer.cc @@ -24,6 +24,7 @@ * */ +#include "enums.h" #include "system-gl.h" #include "LegacyOpenCSGRenderer.h" #include "LegacyRendererUtils.h" @@ -44,11 +45,12 @@ class OpenCSGPrim : public OpenCSG::Primitive Transform3d m; Renderer::csgmode_e csgmode{Renderer::CSGMODE_NONE}; + // This is used by OpenCSG to render depth values void render() override { if (polyset) { glPushMatrix(); glMultMatrixd(m.data()); - render_surface(*polyset, csgmode, m); + render_surface(*polyset, m); glPopMatrix(); } } @@ -56,13 +58,17 @@ class OpenCSGPrim : public OpenCSG::Primitive const LegacyOpenCSGRenderer& renderer; }; -// Primitive for rendering using OpenCSG -OpenCSGPrim *createCSGPrimitive(const CSGChainObject& csgobj, OpenCSG::Operation operation, +// Primitive for depth rendering using OpenCSG +std::unique_ptr createCSGPrimitive(const CSGChainObject& csgobj, OpenCSG::Operation operation, bool highlight_mode, bool background_mode, OpenSCADOperator type, const LegacyOpenCSGRenderer &renderer) { - auto *prim = new OpenCSGPrim(operation, csgobj.leaf->polyset->getConvexity(), renderer); + auto prim = std::make_unique(operation, csgobj.leaf->polyset->getConvexity(), renderer); prim->polyset = csgobj.leaf->polyset; prim->m = csgobj.leaf->matrix; + if (prim->polyset->getDimension() == 2 && type == OpenSCADOperator::DIFFERENCE) { + // Scale 2D negative objects 10% in the Z direction to avoid z fighting + prim->m *= Eigen::Scaling(1.0, 1.0, 1.1); + } prim->csgmode = Renderer::get_csgmode(highlight_mode, background_mode, type); return prim; } @@ -99,12 +105,20 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr { #ifdef ENABLE_OPENCSG for (const auto& product : products->products) { + // owned_primitives is only for memory management + std::vector> owned_primitives; std::vector primitives; for (const auto& csgobj : product.intersections) { - if (csgobj.leaf->polyset) primitives.push_back(createCSGPrimitive(csgobj, OpenCSG::Intersection, highlight_mode, background_mode, OpenSCADOperator::INTERSECTION, *this)); + if (csgobj.leaf->polyset) { + owned_primitives.push_back(createCSGPrimitive(csgobj, OpenCSG::Intersection, highlight_mode, background_mode, OpenSCADOperator::INTERSECTION, *this)); + primitives.push_back(owned_primitives.back().get()); + } } for (const auto& csgobj : product.subtractions) { - if (csgobj.leaf->polyset) primitives.push_back(createCSGPrimitive(csgobj, OpenCSG::Subtraction, highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE, *this)); + if (csgobj.leaf->polyset) { + owned_primitives.push_back(createCSGPrimitive(csgobj, OpenCSG::Subtraction, highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE, *this)); + primitives.push_back(owned_primitives.back().get()); + } } if (primitives.size() > 1) { OpenCSG::render(primitives); @@ -113,7 +127,7 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr if (shaderinfo && shaderinfo->progid) { if (shaderinfo->type != EDGE_RENDERING || (shaderinfo->type == EDGE_RENDERING && showedges)) { - GL_CHECKD(glUseProgram(shaderinfo->progid)); + GL_CHECKD(glUseProgram(shaderinfo->progid)); } } @@ -121,10 +135,10 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr if (!csgobj.leaf->polyset) continue; if (shaderinfo && shaderinfo->type == Renderer::SELECT_RENDERING) { - int identifier = csgobj.leaf->index; - GL_CHECKD(glUniform3f(shaderinfo->data.select_rendering.identifier, - ((identifier >> 0) & 0xff) / 255.0f, ((identifier >> 8) & 0xff) / 255.0f, - ((identifier >> 16) & 0xff) / 255.0f)); + int identifier = csgobj.leaf->index; + GL_CHECKD(glUniform3f(shaderinfo->data.select_rendering.identifier, + ((identifier >> 0) & 0xff) / 255.0f, ((identifier >> 8) & 0xff) / 255.0f, + ((identifier >> 16) & 0xff) / 255.0f)); } const Color4f& c = csgobj.leaf->color; @@ -132,11 +146,11 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr ColorMode colormode = ColorMode::NONE; if (highlight_mode) { - colormode = ColorMode::HIGHLIGHT; + colormode = ColorMode::HIGHLIGHT; } else if (background_mode) { - colormode = ColorMode::BACKGROUND; + colormode = ColorMode::BACKGROUND; } else { - colormode = ColorMode::MATERIAL; + colormode = ColorMode::MATERIAL; } glPushMatrix(); @@ -144,16 +158,16 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr const Color4f color = setColor(colormode, c.data(), shaderinfo); if (color[3] == 1.0f) { - // object is opaque, draw normally - render_surface(*csgobj.leaf->polyset, csgmode, csgobj.leaf->matrix, shaderinfo); + // object is opaque, draw normally + render_surface(*csgobj.leaf->polyset, csgobj.leaf->matrix, shaderinfo); } else { - // object is transparent, so draw rear faces first. Issue #1496 - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - render_surface(*csgobj.leaf->polyset, csgmode, csgobj.leaf->matrix, shaderinfo); - glCullFace(GL_BACK); - render_surface(*csgobj.leaf->polyset, csgmode, csgobj.leaf->matrix, shaderinfo); - glDisable(GL_CULL_FACE); + // object is transparent, so draw rear faces first. Issue #1496 + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + render_surface(*csgobj.leaf->polyset, csgobj.leaf->matrix, shaderinfo); + glCullFace(GL_BACK); + render_surface(*csgobj.leaf->polyset, csgobj.leaf->matrix, shaderinfo); + glDisable(GL_CULL_FACE); } glPopMatrix(); @@ -166,27 +180,31 @@ void LegacyOpenCSGRenderer::renderCSGProducts(const std::shared_ptr ColorMode colormode = ColorMode::NONE; if (highlight_mode) { - colormode = ColorMode::HIGHLIGHT; + colormode = ColorMode::HIGHLIGHT; } else if (background_mode) { - colormode = ColorMode::BACKGROUND; + colormode = ColorMode::BACKGROUND; } else { - colormode = ColorMode::CUTOUT; + colormode = ColorMode::CUTOUT; } (void) setColor(colormode, c.data(), shaderinfo); glPushMatrix(); - glMultMatrixd(csgobj.leaf->matrix.data()); + Transform3d mat = csgobj.leaf->matrix; + if (csgobj.leaf->polyset->getDimension() == 2) { + // Scale 2D negative objects 10% in the Z direction to avoid z fighting + mat *= Eigen::Scaling(1.0, 1.0, 1.1); + } + glMultMatrixd(mat.data()); // negative objects should only render rear faces glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); - render_surface(*csgobj.leaf->polyset, csgmode, csgobj.leaf->matrix, shaderinfo); + render_surface(*csgobj.leaf->polyset, csgobj.leaf->matrix, shaderinfo); glDisable(GL_CULL_FACE); glPopMatrix(); } if (shaderinfo) glUseProgram(0); - for (auto& p : primitives) delete p; glDepthFunc(GL_LEQUAL); } #endif // ENABLE_OPENCSG diff --git a/src/glview/preview/LegacyThrownTogetherRenderer.cc b/src/glview/preview/LegacyThrownTogetherRenderer.cc index f1918ae7a13..ef53d2339ae 100644 --- a/src/glview/preview/LegacyThrownTogetherRenderer.cc +++ b/src/glview/preview/LegacyThrownTogetherRenderer.cc @@ -29,6 +29,7 @@ #include #include "Feature.h" #include "PolySet.h" +#include "enums.h" #include "printutils.h" #include "LegacyRendererUtils.h" @@ -72,8 +73,8 @@ void LegacyThrownTogetherRenderer::renderChainObject(const CSGChainObject& csgob bool highlight_mode, bool background_mode, bool fberror, OpenSCADOperator type) const { -// if (this->geomVisitMark[std::make_pair(csgobj.leaf->polyset.get(), &csgobj.leaf->matrix)]++ > 0) return; if (!csgobj.leaf->polyset) return; + if (this->geomVisitMark[std::make_pair(csgobj.leaf->polyset.get(), &csgobj.leaf->matrix)]++ > 0) return; const Color4f& c = csgobj.leaf->color; csgmode_e csgmode = get_csgmode(highlight_mode, background_mode, type); @@ -91,14 +92,14 @@ void LegacyThrownTogetherRenderer::renderChainObject(const CSGChainObject& csgob setColor(colormode, c.data(), shaderinfo); } glPushMatrix(); - glMultMatrixd(m.data()); - render_surface(*csgobj.leaf->polyset, csgmode, m, shaderinfo); - // only use old render_edges if there is no shader progid - if (showedges && (shaderinfo && shaderinfo->progid == 0)) { - // FIXME? glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); - setColor(edge_colormode); - render_edges(*csgobj.leaf->polyset, csgmode); + + Transform3d tmp = csgobj.leaf->matrix; + if (csgobj.leaf->polyset->getDimension() == 2 && type == OpenSCADOperator::DIFFERENCE) { + // Scale 2D negative objects 10% in the Z direction to avoid z fighting + tmp *= Eigen::Scaling(1.0, 1.0, 1.1); } + glMultMatrixd(tmp.data()); + render_surface(*csgobj.leaf->polyset, tmp, shaderinfo); glPopMatrix(); } @@ -109,7 +110,7 @@ void LegacyThrownTogetherRenderer::renderCSGProducts(const std::shared_ptrgeomVisitMark.clear(); + this->geomVisitMark.clear(); for (const auto& product : products->products) { for (const auto& csgobj : product.intersections) { diff --git a/src/glview/preview/LegacyThrownTogetherRenderer.h b/src/glview/preview/LegacyThrownTogetherRenderer.h index aea407fa067..5b1ffc33e98 100644 --- a/src/glview/preview/LegacyThrownTogetherRenderer.h +++ b/src/glview/preview/LegacyThrownTogetherRenderer.h @@ -2,6 +2,8 @@ #include "Renderer.h" #include "CSGNode.h" +#include +#include class CSGProducts; class CSGChainObject; @@ -31,4 +33,6 @@ class LegacyThrownTogetherRenderer : public Renderer std::shared_ptr root_products; std::shared_ptr highlight_products; std::shared_ptr background_products; + mutable std::unordered_map, int, + boost::hash>> geomVisitMark; }; diff --git a/src/glview/preview/OpenCSGRenderer.cc b/src/glview/preview/OpenCSGRenderer.cc index bf6dd6f9a2b..50daf9a28ae 100644 --- a/src/glview/preview/OpenCSGRenderer.cc +++ b/src/glview/preview/OpenCSGRenderer.cc @@ -24,21 +24,23 @@ * */ -#include "system-gl.h" #include "OpenCSGRenderer.h" +#include "linalg.h" +#include "system-gl.h" +#include "Feature.h" +#include "PolySet.h" #include #include -#include "PolySet.h" -#include "Feature.h" #ifdef ENABLE_OPENCSG -class OpenCSGVBOPrim : public OpenCSG::Primitive -{ +class OpenCSGVBOPrim : public OpenCSG::Primitive { public: - OpenCSGVBOPrim(OpenCSG::Operation operation, unsigned int convexity, std::unique_ptr vertex_state) : - OpenCSG::Primitive(operation, convexity), vertex_state(std::move(vertex_state)) { } + OpenCSGVBOPrim(OpenCSG::Operation operation, unsigned int convexity, + std::unique_ptr vertex_state) + : OpenCSG::Primitive(operation, convexity), + vertex_state(std::move(vertex_state)) {} void render() override { if (vertex_state != nullptr) { vertex_state->draw(); @@ -52,17 +54,16 @@ class OpenCSGVBOPrim : public OpenCSG::Primitive }; #endif // ENABLE_OPENCSG -OpenCSGRenderer::OpenCSGRenderer(std::shared_ptr root_products, - std::shared_ptr highlights_products, - std::shared_ptr background_products) - : root_products_(std::move(root_products)), - highlights_products_(std::move(highlights_products)), - background_products_(std::move(background_products)) -{ -} +OpenCSGRenderer::OpenCSGRenderer( + std::shared_ptr root_products, + std::shared_ptr highlights_products, + std::shared_ptr background_products) + : root_products_(std::move(root_products)), + highlights_products_(std::move(highlights_products)), + background_products_(std::move(background_products)) {} -void OpenCSGRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, const shaderinfo_t *shaderinfo) -{ +void OpenCSGRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, + const shaderinfo_t *shaderinfo) { if (vbo_vertex_products_.empty()) { if (root_products_) { createCSGVBOProducts(*root_products_, shaderinfo, false, false); @@ -76,43 +77,51 @@ void OpenCSGRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, const shad } } -void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges, const shaderinfo_t *shaderinfo) const -{ +void OpenCSGRenderer::draw(bool /*showfaces*/, bool showedges, + const shaderinfo_t *shaderinfo) const { if (!shaderinfo && showedges) shaderinfo = &getShader(); renderCSGVBOProducts(showedges, shaderinfo); } // Primitive for drawing using OpenCSG -// Makes a copy of the given VertexState enabling just unlit/uncolored vertex rendering -OpenCSGVBOPrim *OpenCSGRenderer::createVBOPrimitive(const std::shared_ptr& vertex_state, - const OpenCSG::Operation operation, const unsigned int convexity) const -{ - std::unique_ptr opencsg_vs = std::make_unique(vertex_state->drawMode(), vertex_state->drawSize(), - vertex_state->drawType(), vertex_state->drawOffset(), - vertex_state->elementOffset(), vertex_state->verticesVBO(), - vertex_state->elementsVBO()); +// Makes a copy of the given VertexState enabling just unlit/uncolored vertex +// rendering +OpenCSGVBOPrim *OpenCSGRenderer::createVBOPrimitive( + const std::shared_ptr &vertex_state, + const OpenCSG::Operation operation, const unsigned int convexity) const { + std::unique_ptr opencsg_vs = std::make_unique( + vertex_state->drawMode(), vertex_state->drawSize(), + vertex_state->drawType(), vertex_state->drawOffset(), + vertex_state->elementOffset(), vertex_state->verticesVBO(), + vertex_state->elementsVBO()); // First two glBegin entries are the vertex position calls - opencsg_vs->glBegin().insert(opencsg_vs->glBegin().begin(), vertex_state->glBegin().begin(), vertex_state->glBegin().begin() + 2); + opencsg_vs->glBegin().insert(opencsg_vs->glBegin().begin(), + vertex_state->glBegin().begin(), + vertex_state->glBegin().begin() + 2); // First glEnd entry is the disable vertex position call - opencsg_vs->glEnd().insert(opencsg_vs->glEnd().begin(), vertex_state->glEnd().begin(), vertex_state->glEnd().begin() + 1); + opencsg_vs->glEnd().insert(opencsg_vs->glEnd().begin(), + vertex_state->glEnd().begin(), + vertex_state->glEnd().begin() + 1); return new OpenCSGVBOPrim(operation, convexity, std::move(opencsg_vs)); } // Turn the CSGProducts into VBOs // Will create one (temporary) VertexArray and one VBO(+EBO) per product -// The VBO will be utilized to render multiple objects with correct state management. -// In the future, we could use a VBO per primitive and potentially reuse VBOs, but that requires -// some more careful state management. -void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Renderer::shaderinfo_t * /*shaderinfo*/, bool highlight_mode, bool background_mode) -{ - // We need to manage buffers here since we don't have another suitable container for - // managing the life cycle of VBOs. - // We're creating one VBO(+EBO) per product. +// The VBO will be utilized to render multiple objects with correct state +// management. In the future, we could use a VBO per primitive and potentially +// reuse VBOs, but that requires some more careful state management. +void OpenCSGRenderer::createCSGVBOProducts( + const CSGProducts &products, const Renderer::shaderinfo_t * /*shaderinfo*/, + bool highlight_mode, bool background_mode) { + // We need to manage buffers here since we don't have another suitable + // container for managing the life cycle of VBOs. We're creating one VBO(+EBO) + // per product. size_t vbo_count = products.products.size(); if (vbo_count) { vertices_vbos_.resize(vbo_count); - // Will default to zeroes, so we don't have to keep checking for the Indexing feature + // Will default to zeroes, so we don't have to keep checking for the + // Indexing feature elements_vbos_.resize(vbo_count); glGenBuffers(vbo_count, vertices_vbos_.data()); if (Feature::ExperimentalVxORenderersIndexing.is_enabled()) { @@ -122,37 +131,39 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re #ifdef ENABLE_OPENCSG size_t vbo_index = 0; - for (auto i=0;i primitives; - std::unique_ptr>> vertex_states = std::make_unique>>(); - VertexArray vertex_array(std::make_unique(), *(vertex_states.get()), - vertices_vbo, elements_vbo); + std::unique_ptr>> vertex_states = + std::make_unique>>(); + VertexArray vertex_array(std::make_unique(), + *(vertex_states.get()), vertices_vbo, + elements_vbo); vertex_array.addSurfaceData(); vertex_array.writeSurface(); add_shader_data(vertex_array); size_t num_vertices = 0; - for (const auto& csgobj : product.intersections) { + for (const auto &csgobj : product.intersections) { if (csgobj.leaf->polyset) { - num_vertices += getSurfaceBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::INTERSECTION); + num_vertices += getSurfaceBufferSize(csgobj); } } - for (const auto& csgobj : product.subtractions) { + for (const auto &csgobj : product.subtractions) { if (csgobj.leaf->polyset) { - num_vertices += getSurfaceBufferSize(csgobj, highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE); + num_vertices += getSurfaceBufferSize(csgobj); } } vertex_array.allocateBuffers(num_vertices); - for (const auto& csgobj : product.intersections) { + for (const auto &csgobj : product.intersections) { if (csgobj.leaf->polyset) { - const Color4f& c = csgobj.leaf->color; + const Color4f &c = csgobj.leaf->color; csgmode_e csgmode = get_csgmode(highlight_mode, background_mode); ColorMode colormode = ColorMode::NONE; @@ -173,38 +184,47 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re if (color[3] == 1.0f) { // object is opaque, draw normally - create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, csgobj.leaf->matrix, last_color); - std::shared_ptr surface = std::dynamic_pointer_cast(vertex_states->back()); + create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, + csgobj.leaf->matrix, last_color); + std::shared_ptr surface = + std::dynamic_pointer_cast( + vertex_states->back()); if (surface != nullptr) { surface->setCsgObjectIndex(csgobj.leaf->index); - primitives.emplace_back(createVBOPrimitive(surface, - OpenCSG::Intersection, - csgobj.leaf->polyset->getConvexity())); + primitives.emplace_back( + createVBOPrimitive(surface, OpenCSG::Intersection, + csgobj.leaf->polyset->getConvexity())); } } else { // object is transparent, so draw rear faces first. Issue #1496 std::shared_ptr cull = std::make_shared(); cull->glBegin().emplace_back([]() { - GL_TRACE0("glEnable(GL_CULL_FACE)"); glEnable(GL_CULL_FACE); + GL_TRACE0("glEnable(GL_CULL_FACE)"); + glEnable(GL_CULL_FACE); }); cull->glBegin().emplace_back([]() { - GL_TRACE0("glCullFace(GL_FRONT)"); glCullFace(GL_FRONT); + GL_TRACE0("glCullFace(GL_FRONT)"); + glCullFace(GL_FRONT); }); vertex_states->emplace_back(std::move(cull)); - create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, csgobj.leaf->matrix, last_color); - std::shared_ptr surface = std::dynamic_pointer_cast(vertex_states->back()); + create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, + csgobj.leaf->matrix, last_color); + std::shared_ptr surface = + std::dynamic_pointer_cast( + vertex_states->back()); if (surface != nullptr) { surface->setCsgObjectIndex(csgobj.leaf->index); - primitives.emplace_back(createVBOPrimitive(surface, - OpenCSG::Intersection, - csgobj.leaf->polyset->getConvexity())); + primitives.emplace_back( + createVBOPrimitive(surface, OpenCSG::Intersection, + csgobj.leaf->polyset->getConvexity())); cull = std::make_shared(); cull->glBegin().emplace_back([]() { - GL_TRACE0("glCullFace(GL_BACK)"); glCullFace(GL_BACK); + GL_TRACE0("glCullFace(GL_BACK)"); + glCullFace(GL_BACK); }); vertex_states->emplace_back(std::move(cull)); @@ -212,7 +232,8 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re cull = std::make_shared(); cull->glEnd().emplace_back([]() { - GL_TRACE0("glDisable(GL_CULL_FACE)"); glDisable(GL_CULL_FACE); + GL_TRACE0("glDisable(GL_CULL_FACE)"); + glDisable(GL_CULL_FACE); }); vertex_states->emplace_back(std::move(cull)); } else { @@ -222,10 +243,11 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re } } - for (const auto& csgobj : product.subtractions) { + for (const auto &csgobj : product.subtractions) { if (csgobj.leaf->polyset) { - const Color4f& c = csgobj.leaf->color; - csgmode_e csgmode = get_csgmode(highlight_mode, background_mode, OpenSCADOperator::DIFFERENCE); + const Color4f &c = csgobj.leaf->color; + csgmode_e csgmode = get_csgmode(highlight_mode, background_mode, + OpenSCADOperator::DIFFERENCE); ColorMode colormode = ColorMode::NONE; if (highlight_mode) { @@ -254,14 +276,21 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re GL_CHECKD(glCullFace(GL_FRONT)); }); vertex_states->emplace_back(std::move(cull)); - - create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, csgobj.leaf->matrix, last_color); - std::shared_ptr surface = std::dynamic_pointer_cast(vertex_states->back()); + Transform3d tmp = csgobj.leaf->matrix; + if (csgobj.leaf->polyset->getDimension() == 2) { + // Scale 2D negative objects 10% in the Z direction to avoid z fighting + tmp *= Eigen::Scaling(1.0, 1.0, 1.1); + } + create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, tmp, + last_color); + std::shared_ptr surface = + std::dynamic_pointer_cast( + vertex_states->back()); if (surface != nullptr) { surface->setCsgObjectIndex(csgobj.leaf->index); - primitives.emplace_back(createVBOPrimitive(surface, - OpenCSG::Subtraction, - csgobj.leaf->polyset->getConvexity())); + primitives.emplace_back( + createVBOPrimitive(surface, OpenCSG::Subtraction, + csgobj.leaf->polyset->getConvexity())); } else { assert(false && "Subtraction surface state was nullptr"); } @@ -283,15 +312,16 @@ void OpenCSGRenderer::createCSGVBOProducts(const CSGProducts& products, const Re GL_CHECKD(glBindBuffer(GL_ARRAY_BUFFER, 0)); vertex_array.createInterleavedVBOs(); - vbo_vertex_products_.emplace_back(std::make_unique(std::move(primitives), std::move(vertex_states))); + vbo_vertex_products_.emplace_back(std::make_unique( + std::move(primitives), std::move(vertex_states))); } #endif // ENABLE_OPENCSG } -void OpenCSGRenderer::renderCSGVBOProducts(bool showedges, const Renderer::shaderinfo_t *shaderinfo) const -{ +void OpenCSGRenderer::renderCSGVBOProducts( + bool showedges, const Renderer::shaderinfo_t *shaderinfo) const { #ifdef ENABLE_OPENCSG - for (const auto& product : vbo_vertex_products_) { + for (const auto &product : vbo_vertex_products_) { if (product->primitives().size() > 1) { GL_CHECKD(OpenCSG::render(product->primitives())); GL_TRACE0("glDepthFunc(GL_EQUAL)"); @@ -303,29 +333,33 @@ void OpenCSGRenderer::renderCSGVBOProducts(bool showedges, const Renderer::shade GL_CHECKD(glUseProgram(shaderinfo->progid)); if (shaderinfo->type == EDGE_RENDERING && showedges) { - shader_attribs_enable(); + shader_attribs_enable(); } } - for (const auto& vs : product->states()) { + for (const auto &vs : product->states()) { if (vs) { - std::shared_ptr csg_vs = std::dynamic_pointer_cast(vs); - if (csg_vs) { - if (shaderinfo && shaderinfo->type == SELECT_RENDERING) { - GL_TRACE("glUniform3f(%d, %f, %f, %f)", shaderinfo->data.select_rendering.identifier % - (((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f) % - (((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f) % - (((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); - GL_CHECKD(glUniform3f(shaderinfo->data.select_rendering.identifier, - ((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f, - ((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f, - ((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); - } - } - std::shared_ptr shader_vs = std::dynamic_pointer_cast(vs); - if (!shader_vs || (showedges && shader_vs)) { - vs->draw(); - } + std::shared_ptr csg_vs = + std::dynamic_pointer_cast(vs); + if (csg_vs) { + if (shaderinfo && shaderinfo->type == SELECT_RENDERING) { + GL_TRACE("glUniform3f(%d, %f, %f, %f)", + shaderinfo->data.select_rendering.identifier % + (((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f) % + (((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f) % + (((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); + GL_CHECKD(glUniform3f( + shaderinfo->data.select_rendering.identifier, + ((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f, + ((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f, + ((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); + } + } + std::shared_ptr shader_vs = + std::dynamic_pointer_cast(vs); + if (!shader_vs || (showedges && shader_vs)) { + vs->draw(); + } } } @@ -334,7 +368,7 @@ void OpenCSGRenderer::renderCSGVBOProducts(bool showedges, const Renderer::shade GL_CHECKD(glUseProgram(0)); if (shaderinfo->type == EDGE_RENDERING && showedges) { - shader_attribs_disable(); + shader_attribs_disable(); } } GL_TRACE0("glDepthFunc(GL_LEQUAL)"); @@ -343,12 +377,14 @@ void OpenCSGRenderer::renderCSGVBOProducts(bool showedges, const Renderer::shade #endif // ENABLE_OPENCSG } -BoundingBox OpenCSGRenderer::getBoundingBox() const -{ +BoundingBox OpenCSGRenderer::getBoundingBox() const { BoundingBox bbox; - if (root_products_) bbox = root_products_->getBoundingBox(); - if (highlights_products_) bbox.extend(highlights_products_->getBoundingBox()); - if (background_products_) bbox.extend(background_products_->getBoundingBox()); + if (root_products_) + bbox = root_products_->getBoundingBox(); + if (highlights_products_) + bbox.extend(highlights_products_->getBoundingBox()); + if (background_products_) + bbox.extend(background_products_->getBoundingBox()); return bbox; } diff --git a/src/glview/preview/ThrownTogetherRenderer.cc b/src/glview/preview/ThrownTogetherRenderer.cc index 71b838ae3a2..5e34e87387e 100644 --- a/src/glview/preview/ThrownTogetherRenderer.cc +++ b/src/glview/preview/ThrownTogetherRenderer.cc @@ -29,6 +29,7 @@ #include #include "Feature.h" #include "PolySet.h" +#include "enums.h" #include "printutils.h" #include "system-gl.h" @@ -63,9 +64,9 @@ void ThrownTogetherRenderer::prepare(bool /*showfaces*/, bool /*showedges*/, con add_shader_data(vertex_array); size_t num_vertices = 0; - if (this->root_products) num_vertices += (getSurfaceBufferSize(this->root_products, false, false, true) * 2); - if (this->background_products) num_vertices += getSurfaceBufferSize(this->background_products, false, true, true); - if (this->highlight_products) num_vertices += getSurfaceBufferSize(this->highlight_products, true, false, true); + if (this->root_products) num_vertices += (getSurfaceBufferSize(this->root_products, true) * 2); + if (this->background_products) num_vertices += getSurfaceBufferSize(this->background_products, true); + if (this->highlight_products) num_vertices += getSurfaceBufferSize(this->highlight_products, true); vertex_array.allocateBuffers(num_vertices); @@ -120,21 +121,21 @@ void ThrownTogetherRenderer::renderCSGProducts(const std::shared_ptr csg_vs = std::dynamic_pointer_cast(vs); if (csg_vs) { - if (shaderinfo && shaderinfo->type == Renderer::SELECT_RENDERING) { - GL_TRACE("glUniform3f(%d, %f, %f, %f)", - shaderinfo->data.select_rendering.identifier % - (((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f) % - (((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f) % - (((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); - GL_CHECKD(glUniform3f(shaderinfo->data.select_rendering.identifier, - ((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f, - ((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f, - ((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); - } + if (shaderinfo && shaderinfo->type == Renderer::SELECT_RENDERING) { + GL_TRACE("glUniform3f(%d, %f, %f, %f)", + shaderinfo->data.select_rendering.identifier % + (((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f) % + (((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f) % + (((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); + GL_CHECKD(glUniform3f(shaderinfo->data.select_rendering.identifier, + ((csg_vs->csgObjectIndex() >> 0) & 0xff) / 255.0f, + ((csg_vs->csgObjectIndex() >> 8) & 0xff) / 255.0f, + ((csg_vs->csgObjectIndex() >> 16) & 0xff) / 255.0f)); + } } std::shared_ptr shader_vs = std::dynamic_pointer_cast(vs); if (!shader_vs || (shader_vs && showedges)) { - vs->draw(); + vs->draw(); } } } @@ -181,7 +182,12 @@ void ThrownTogetherRenderer::createChainObject(VertexArray& vertex_array, }); vertex_states.emplace_back(std::move(cull)); - create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, csgobj.leaf->matrix, color); + Transform3d mat = csgobj.leaf->matrix; + if (csgobj.leaf->polyset->getDimension() == 2 && type == OpenSCADOperator::DIFFERENCE) { + // Scale 2D negative objects 10% in the Z direction to avoid z fighting + mat *= Eigen::Scaling(1.0, 1.0, 1.1); + } + create_surface(*csgobj.leaf->polyset, vertex_array, csgmode, mat, color); std::shared_ptr vs = std::dynamic_pointer_cast(vertex_array.states().back()); if (vs) { vs->setCsgObjectIndex(csgobj.leaf->index); diff --git a/src/gui/Measurement.cc b/src/gui/Measurement.cc index 8abc6936db3..d4d198d38d2 100644 --- a/src/gui/Measurement.cc +++ b/src/gui/Measurement.cc @@ -65,10 +65,10 @@ QString Measurement::statemachine(QPoint mouse) double lat; obj1=qglview->selected_obj[0]; obj2=qglview->selected_obj[1]; - if(obj1.type == SELECTION_POINT && obj2.type == SELECTION_POINT) dist =(obj2.p1-obj1.p1).norm(); - if(obj1.type == SELECTION_POINT && obj2.type == SELECTION_LINE) dist =calculateLinePointDistance(obj2.p1, obj2.p2,obj1.p1,lat); - if(obj1.type == SELECTION_LINE && obj2.type == SELECTION_POINT) dist =calculateLinePointDistance(obj1.p1, obj1.p2,obj2.p1,lat); - if(obj1.type == SELECTION_LINE && obj2.type == SELECTION_LINE) dist =calculateLineLineDistance(obj1.p1, obj1.p2,obj2.p1,obj2.p2,lat); + if(obj1.type == SelectionType::SELECTION_POINT && obj2.type == SelectionType::SELECTION_POINT) dist =(obj2.p1-obj1.p1).norm(); + if(obj1.type == SelectionType::SELECTION_POINT && obj2.type == SelectionType::SELECTION_LINE) dist =calculateLinePointDistance(obj2.p1, obj2.p2,obj1.p1,lat); + if(obj1.type == SelectionType::SELECTION_LINE && obj2.type == SelectionType::SELECTION_POINT) dist =calculateLinePointDistance(obj1.p1, obj1.p2,obj2.p1,lat); + if(obj1.type == SelectionType::SELECTION_LINE && obj2.type == SelectionType::SELECTION_LINE) dist =calculateLineLineDistance(obj1.p1, obj1.p2,obj2.p1,obj2.p2,lat); if(!std::isnan(dist)) { return QString("Distance is %1").arg(fabs(dist)); std::stringstream ss; @@ -88,21 +88,21 @@ QString Measurement::statemachine(QPoint mouse) obj1=qglview->selected_obj[0]; obj2=qglview->selected_obj[1]; Vector3d side1, side2; - if(obj1.type == SELECTION_LINE && obj2.type == SELECTION_POINT) + if(obj1.type == SelectionType::SELECTION_LINE && obj2.type == SelectionType::SELECTION_POINT) { side1=(obj1.p2-obj1.p1).normalized(); side2=(obj1.p2-obj2.p1).normalized(); ang=acos(side1.dot(side2))*180.0/3.14159265359; goto display_angle; } - else if(obj1.type == SELECTION_POINT && obj2.type == SELECTION_LINE) + else if(obj1.type == SelectionType::SELECTION_POINT && obj2.type == SelectionType::SELECTION_LINE) { side1=(obj2.p2-obj2.p1).normalized(); side2=(obj2.p2-obj1.p1).normalized(); ang=acos(side1.dot(side2))*180.0/3.14159265359; goto display_angle; } - else if(obj1.type == SELECTION_LINE && obj2.type == SELECTION_LINE) + else if(obj1.type == SelectionType::SELECTION_LINE && obj2.type == SelectionType::SELECTION_LINE) { if(obj1.p2 == obj2.p1) { side1=(obj2.p1-obj1.p1).normalized(); @@ -126,7 +126,7 @@ QString Measurement::statemachine(QPoint mouse) obj1=qglview->selected_obj[0]; obj2=qglview->selected_obj[1]; obj3=qglview->selected_obj[2]; - if(obj1.type == SELECTION_POINT && obj2.type == SELECTION_POINT && obj3.type == SELECTION_POINT) + if(obj1.type == SelectionType::SELECTION_POINT && obj2.type == SelectionType::SELECTION_POINT && obj3.type == SelectionType::SELECTION_POINT) { Vector3d side1=(obj2.p1-obj1.p1).normalized(); Vector3d side2=(obj2.p1-obj3.p1).normalized(); diff --git a/src/io/import_3mf.cc b/src/io/import_3mf.cc index 059522476ce..63461185650 100644 --- a/src/io/import_3mf.cc +++ b/src/io/import_3mf.cc @@ -143,7 +143,7 @@ std::unique_ptr import_3mf(const std::string& filename, const Location PRINTDB("%s: mesh %d, vertex count: %lu, triangle count: %lu", filename.c_str() % mesh_idx % vertex_count % triangle_count); - PolySetBuilder builder(0,triangle_count); + PolySetBuilder builder(0, triangle_count); for (DWORD idx = 0; idx < triangle_count; ++idx) { MODELMESHTRIANGLE triangle; if (lib3mf_meshobject_gettriangle(object, idx, &triangle) != LIB3MF_OK) { diff --git a/src/io/import_amf.cc b/src/io/import_amf.cc index 15311b988fa..309916ff03f 100644 --- a/src/io/import_amf.cc +++ b/src/io/import_amf.cc @@ -132,7 +132,7 @@ void AmfImporter::set_v3(AmfImporter *importer, const xmlChar *value) void AmfImporter::start_object(AmfImporter *importer, const xmlChar *) { - importer->builder = std::make_unique(0,0,3); + importer->builder = std::make_unique(0,0); } void AmfImporter::end_object(AmfImporter *importer, const xmlChar *) diff --git a/src/io/import_stl.cc b/src/io/import_stl.cc index 1eabe0b6ded..bb19a8c7618 100644 --- a/src/io/import_stl.cc +++ b/src/io/import_stl.cc @@ -96,7 +96,7 @@ std::unique_ptr import_stl(const std::string& filename, const Location& } } if(!binary) facenum=0; - PolySetBuilder builder(0,facenum); + PolySetBuilder builder(0, facenum); f.seekg(0); char data[5]; diff --git a/tests/regression/lazyunion-opencsg/2d-3d-expected.png b/tests/regression/lazyunion-opencsg/2d-3d-expected.png index d879d5d89bc..bdd0ce2f253 100644 Binary files a/tests/regression/lazyunion-opencsg/2d-3d-expected.png and b/tests/regression/lazyunion-opencsg/2d-3d-expected.png differ diff --git a/tests/regression/opencsgtest/2d-3d-expected.png b/tests/regression/opencsgtest/2d-3d-expected.png index ab79532903e..bdd0ce2f253 100644 Binary files a/tests/regression/opencsgtest/2d-3d-expected.png and b/tests/regression/opencsgtest/2d-3d-expected.png differ diff --git a/tests/regression/opencsgtest/control-hull-dimension-expected.png b/tests/regression/opencsgtest/control-hull-dimension-expected.png index 0c8c7f4a36e..263e3dc804a 100644 Binary files a/tests/regression/opencsgtest/control-hull-dimension-expected.png and b/tests/regression/opencsgtest/control-hull-dimension-expected.png differ diff --git a/tests/regression/opencsgtest/issue1004-expected.png b/tests/regression/opencsgtest/issue1004-expected.png index 54ba5812cfa..c0740f0e77d 100644 Binary files a/tests/regression/opencsgtest/issue1004-expected.png and b/tests/regression/opencsgtest/issue1004-expected.png differ diff --git a/tests/regression/opencsgtest/issue666_2D-expected.png b/tests/regression/opencsgtest/issue666_2D-expected.png index c61df32d3c1..983eb74e172 100644 Binary files a/tests/regression/opencsgtest/issue666_2D-expected.png and b/tests/regression/opencsgtest/issue666_2D-expected.png differ diff --git a/tests/regression/throwntogethertest/2d-3d-expected.png b/tests/regression/throwntogethertest/2d-3d-expected.png index ab79532903e..bdd0ce2f253 100644 Binary files a/tests/regression/throwntogethertest/2d-3d-expected.png and b/tests/regression/throwntogethertest/2d-3d-expected.png differ diff --git a/tests/regression/throwntogethertest/control-hull-dimension-expected.png b/tests/regression/throwntogethertest/control-hull-dimension-expected.png index 0c8c7f4a36e..263e3dc804a 100644 Binary files a/tests/regression/throwntogethertest/control-hull-dimension-expected.png and b/tests/regression/throwntogethertest/control-hull-dimension-expected.png differ diff --git a/tests/regression/throwntogethertest/issue1004-expected.png b/tests/regression/throwntogethertest/issue1004-expected.png index a595e6045f0..f34456b1ad4 100644 Binary files a/tests/regression/throwntogethertest/issue1004-expected.png and b/tests/regression/throwntogethertest/issue1004-expected.png differ diff --git a/tests/regression/throwntogethertest/issue267-normalization-crash-expected.png b/tests/regression/throwntogethertest/issue267-normalization-crash-expected.png index bee2ba2affe..63adcf5bd0c 100644 Binary files a/tests/regression/throwntogethertest/issue267-normalization-crash-expected.png and b/tests/regression/throwntogethertest/issue267-normalization-crash-expected.png differ diff --git a/tests/regression/throwntogethertest/issue666_2D-expected.png b/tests/regression/throwntogethertest/issue666_2D-expected.png index c61df32d3c1..983eb74e172 100644 Binary files a/tests/regression/throwntogethertest/issue666_2D-expected.png and b/tests/regression/throwntogethertest/issue666_2D-expected.png differ