From b605c40449917fd08337dbfaeb37bc6252c025f5 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 13 Sep 2022 23:14:17 +0200 Subject: [PATCH] Part: implement TopoShape::getLines --- src/Mod/Part/App/TopoShape.cpp | 217 +++++++++++++-------------------- src/Mod/Part/App/TopoShape.h | 35 ++++-- 2 files changed, 104 insertions(+), 148 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index c09c9903df..4cd441e7bd 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -3409,22 +3409,10 @@ private: //const double Vertex::MESH_MIN_PT_DIST = 1.0e-6; const double MeshVertex::MESH_MIN_PT_DIST = gp::Resolution(); -void TopoShape::getFaces(std::vector &aPoints, - std::vector &aTopo, - float accuracy, uint16_t /*flags*/) const +void TopoShape::getFacesFromDomains(const std::vector& domains, + std::vector& points, + std::vector& faces) const { - if (this->_Shape.IsNull()) - return; - - // get the meshes of all faces and then merge them - BRepMesh_IncrementalMesh aMesh(this->_Shape, accuracy, - /*isRelative*/ Standard_False, - /*theAngDeflection*/ - defaultAngularDeflection(accuracy), - /*isInParallel*/ true); - std::vector domains; - getDomains(domains); - std::set vertices; Standard_Real x1, y1, z1; Standard_Real x2, y2, z2; @@ -3488,15 +3476,33 @@ void TopoShape::getFaces(std::vector &aPoints, if (face.I1 != face.I2 && face.I2 != face.I3 && face.I3 != face.I1) - aTopo.push_back(face); + faces.push_back(face); } } - std::vector points; - points.resize(vertices.size()); + std::vector meshPoints; + meshPoints.resize(vertices.size()); for (std::set::iterator it = vertices.begin(); it != vertices.end(); ++it) - points[it->i] = it->toPoint(); - aPoints.swap(points); + meshPoints[it->i] = it->toPoint(); + points.swap(meshPoints); +} + +void TopoShape::getFaces(std::vector &aPoints, + std::vector &aTopo, + float accuracy, uint16_t /*flags*/) const +{ + if (this->_Shape.IsNull()) + return; + + // get the meshes of all faces and then merge them + BRepMesh_IncrementalMesh aMesh(this->_Shape, accuracy, + /*isRelative*/ Standard_False, + /*theAngDeflection*/ + defaultAngularDeflection(accuracy), + /*isInParallel*/ true); + std::vector domains; + getDomains(domains); + getFacesFromDomains(domains, aPoints, aTopo); } void TopoShape::setFaces(const std::vector &Points, @@ -3624,6 +3630,60 @@ void TopoShape::setFaces(const std::vector &Points, _Shape = aComp; } +void TopoShape::getLinesFromSubShape(const TopoDS_Shape& shape, + std::vector &vertices, + std::vector &lines) const +{ + if (shape.IsNull()) + return; + + // build up map edge->face + TopTools_IndexedDataMapOfShapeListOfShape edge2Face; + TopExp::MapShapesAndAncestors(this->_Shape, TopAbs_EDGE, TopAbs_FACE, edge2Face); + + for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) { + TopoDS_Edge aEdge = TopoDS::Edge(exp.Current()); + std::vector points; + + if (!Tools::getPolygon3D(aEdge, points)) { + // the edge has not its own triangulation, but then a face the edge is attached to + // must provide this triangulation + + // Look for one face in our map (it doesn't care which one we take) + int index = edge2Face.FindIndex(aEdge); + if (index < 1) + continue; + + const auto &faces = edge2Face.FindFromIndex(index); + if (faces.IsEmpty()) + continue; + + const TopoDS_Face& aFace = TopoDS::Face(faces.First()); + if (!Part::Tools::getPolygonOnTriangulation(aEdge, aFace, points)) + continue; + } + + auto line_start = vertices.size(); + vertices.reserve(vertices.size() + points.size()); + std::for_each(points.begin(), points.end(), [&vertices](const gp_Pnt& p) { + vertices.push_back(Base::convertTo(p)); + }); + + if (line_start+1 < vertices.size()) { + lines.emplace_back(); + lines.back().I1 = line_start; + lines.back().I2 = vertices.size()-1; + } + } +} + +void TopoShape::getLines(std::vector &vertices, + std::vector &lines, + float /*Accuracy*/, uint16_t /*flags*/) const +{ + getLinesFromSubShape(_Shape, vertices, lines); +} + void TopoShape::getPoints(std::vector &Points, std::vector &Normals, float Accuracy, uint16_t /*flags*/) const @@ -3746,50 +3806,8 @@ void TopoShape::getLinesFromSubElement(const Data::Segment* element, const TopoDS_Shape& shape = static_cast(element)->Shape; if (shape.IsNull()) return; - if(shape.ShapeType() == TopAbs_VERTEX) { - auto pnt = BRep_Tool::Pnt(TopoDS::Vertex(shape)); - vertices.emplace_back(pnt.X(),pnt.Y(),pnt.Z()); - return; - } - // build up map edge->face - TopTools_IndexedDataMapOfShapeListOfShape edge2Face; - TopExp::MapShapesAndAncestors(this->_Shape, TopAbs_EDGE, TopAbs_FACE, edge2Face); - - for(TopExp_Explorer exp(shape,TopAbs_EDGE);exp.More();exp.Next()) { - - TopoDS_Edge aEdge = TopoDS::Edge(exp.Current()); - std::vector points; - - if (!Tools::getPolygon3D(aEdge, points)) { - // the edge has not its own triangulation, but then a face the edge is attached to - // must provide this triangulation - - // Look for one face in our map (it doesn't care which one we take) - int index = edge2Face.FindIndex(aEdge); - if (index < 1) - continue; - const auto &faces = edge2Face.FindFromIndex(index); - if (faces.Extent() == 0) - continue; - const TopoDS_Face& aFace = TopoDS::Face(faces.First()); - - if (!Part::Tools::getPolygonOnTriangulation(aEdge, aFace, points)) - continue; - } - - auto line_start = vertices.size(); - vertices.reserve(vertices.size() + points.size()); - std::for_each(points.begin(), points.end(), [&vertices](const gp_Pnt& p) { - vertices.push_back(Base::convertTo(p)); - }); - - if (line_start+1 < vertices.size()) { - lines.emplace_back(); - lines.back().I1 = line_start; - lines.back().I2 = vertices.size()-1; - } - } + getLinesFromSubShape(shape, vertices, lines); } } @@ -3806,80 +3824,9 @@ void TopoShape::getFacesFromSubElement(const Data::Segment* element, // get the meshes of all faces and then merge them std::vector domains; TopoShape(shape).getDomains(domains); - - std::set vertices; - Standard_Real x1, y1, z1; - Standard_Real x2, y2, z2; - Standard_Real x3, y3, z3; - - for (std::vector::const_iterator it = domains.begin(); it != domains.end(); ++it) { - const Domain& domain = *it; - for (std::vector::const_iterator jt = domain.facets.begin(); jt != domain.facets.end(); ++jt) { - x1 = domain.points[jt->I1].x; - y1 = domain.points[jt->I1].y; - z1 = domain.points[jt->I1].z; - - x2 = domain.points[jt->I2].x; - y2 = domain.points[jt->I2].y; - z2 = domain.points[jt->I2].z; - - x3 = domain.points[jt->I3].x; - y3 = domain.points[jt->I3].y; - z3 = domain.points[jt->I3].z; - - TopoShape::Facet face; - std::set::iterator vIt; - - // 1st vertex - MeshVertex v1(x1,y1,z1); - vIt = vertices.find(v1); - if (vIt == vertices.end()) { - v1.i = vertices.size(); - face.I1 = v1.i; - vertices.insert(v1); - } - else { - face.I1 = vIt->i; - } - - // 2nd vertex - MeshVertex v2(x2,y2,z2); - vIt = vertices.find(v2); - if (vIt == vertices.end()) { - v2.i = vertices.size(); - face.I2 = v2.i; - vertices.insert(v2); - } - else { - face.I2 = vIt->i; - } - - // 3rd vertex - MeshVertex v3(x3,y3,z3); - vIt = vertices.find(v3); - if (vIt == vertices.end()) { - v3.i = vertices.size(); - face.I3 = v3.i; - vertices.insert(v3); - } - else { - face.I3 = vIt->i; - } - - // make sure that we don't insert invalid facets - if (face.I1 != face.I2 && - face.I2 != face.I3 && - face.I3 != face.I1) - faces.push_back(face); - } - } + getFacesFromDomains(domains, points, faces); (void)pointNormals; // leave this empty - std::vector meshPoints; - meshPoints.resize(vertices.size()); - for (std::set::iterator it = vertices.begin(); it != vertices.end(); ++it) - meshPoints[it->i] = it->toPoint(); - points.swap(meshPoints); } } diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 21a377350a..a24558b421 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -128,6 +128,28 @@ public: static gp_Trsf convert(const Base::Matrix4D& mtrx); //@} + /** @name Getting basic geometric entities */ + //@{ +private: + /** Get lines from sub-shape */ + void getLinesFromSubShape(const TopoDS_Shape& shape, std::vector& vertices, std::vector& lines) const; + void getFacesFromDomains(const std::vector& domains, std::vector& vertices, std::vector& faces) const; + +public: + /** Get points from object with given accuracy */ + void getPoints(std::vector &Points, + std::vector &Normals, + float Accuracy, uint16_t flags=0) const override; + /** Get lines from object with given accuracy */ + void getLines(std::vector &Points,std::vector &lines, + float Accuracy, uint16_t flags=0) const override; + void getFaces(std::vector &Points,std::vector &faces, + float Accuracy, uint16_t flags=0) const override; + void setFaces(const std::vector &Points, + const std::vector &faces, double tolerance=1.0e-06); + void getDomains(std::vector&) const; + //@} + /** @name Subelement management */ //@{ /** Sub type list @@ -297,19 +319,6 @@ public: TopoDS_Shape makeShell(const TopoDS_Shape&) const; //@} - /** @name Getting basic geometric entities */ - //@{ - /** Get points from object with given accuracy */ - void getPoints(std::vector &Points, - std::vector &Normals, - float Accuracy, uint16_t flags=0) const override; - void getFaces(std::vector &Points,std::vector &faces, - float Accuracy, uint16_t flags=0) const override; - void setFaces(const std::vector &Points, - const std::vector &faces, double tolerance=1.0e-06); - void getDomains(std::vector&) const; - //@} - /** @name Element name mapping aware shape maker * * To be complete in next batch of patches