From 461c0b1f7bc28c5f2d98c006b1647c4f3d0198b2 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 4 Aug 2016 15:22:30 +0200 Subject: [PATCH] fix TopoShape::getFacesFromSubelement --- src/Mod/Part/App/TopoShape.cpp | 205 ++++++++++++++------------------- 1 file changed, 88 insertions(+), 117 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 314c89659..69e5020fa 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -257,123 +257,6 @@ Data::Segment* TopoShape::getSubElement(const char* Type, unsigned long n) const return new ShapeSegment(getSubShape(temp.c_str())); } -void TopoShape::getLinesFromSubelement(const Data::Segment* element, - std::vector &Points, - std::vector &lines) const -{ -} - -void TopoShape::getFacesFromSubelement(const Data::Segment* element, - std::vector &Points, - std::vector &PointNormals, - std::vector &faces) const -{ - if (element->getTypeId() == ShapeSegment::getClassTypeId()) { - const TopoDS_Shape& shape = static_cast(element)->Shape; - if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE) - return; - - TopLoc_Location aLoc; - // doing the meshing and checking the result - Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(TopoDS::Face(shape),aLoc); - if (aPoly.IsNull()) - return; - - // geting the transformation of the shape/face - gp_Trsf myTransf; - Standard_Boolean identity = true; - if (!aLoc.IsIdentity()) { - identity = false; - myTransf = aLoc.Transformation(); - } - - Standard_Integer i; - // geting size and create the array - int nbNodesInFace = aPoly->NbNodes(); - int nbTriInFace = aPoly->NbTriangles(); - Points.resize(nbNodesInFace); - PointNormals.resize(nbNodesInFace); // fills up already the array - faces.resize(nbTriInFace); - - // check orientation - TopAbs_Orientation orient = shape.Orientation(); - - // cycling through the poly mesh - const Poly_Array1OfTriangle& Triangles = aPoly->Triangles(); - const TColgp_Array1OfPnt& Nodes = aPoly->Nodes(); - for (i=1; i<=nbTriInFace; i++) { - // Get the triangle - Standard_Integer N1,N2,N3; - Triangles(i).Get(N1,N2,N3); - - // change orientation of the triangles - if (orient != TopAbs_FORWARD) { - Standard_Integer tmp = N1; - N1 = N2; - N2 = tmp; - } - - gp_Pnt V1 = Nodes(N1); - gp_Pnt V2 = Nodes(N2); - gp_Pnt V3 = Nodes(N3); - - // transform the vertices to the place of the face - if (!identity) { - V1.Transform(myTransf); - V2.Transform(myTransf); - V3.Transform(myTransf); - } - - // Calculate triangle normal - gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); - gp_Vec Normal = (v2-v1)^(v3-v1); - - //Standard_Real Area = 0.5 * Normal.Magnitude(); - - // add the triangle normal to the vertex normal for all points of this triangle - PointNormals[N1-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z()); - PointNormals[N2-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z()); - PointNormals[N3-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z()); - - Points[N1-1].Set(V1.X(),V1.Y(),V1.Z()); - Points[N2-1].Set(V2.X(),V2.Y(),V2.Z()); - Points[N3-1].Set(V3.X(),V3.Y(),V3.Z()); - - int j = i - 1; - N1--; - N2--; - N3--; - faces[j].I1 = N1; - faces[j].I2 = N2; - faces[j].I3 = N3; - } - - // normalize all vertex normals - for (i=0; i < nbNodesInFace; i++) { - gp_Dir clNormal; - try { - Handle_Geom_Surface Surface = BRep_Tool::Surface(TopoDS::Face(shape)); - - gp_Pnt vertex(Base::convertTo(Points[i])); - GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface); - Standard_Real fU, fV; - ProPntSrf.Parameters(1, fU, fV); - - GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution()); - - clNormal = clPropOfFace.Normal(); - Base::Vector3d temp = Base::convertTo(clNormal); - if (temp * Points[i] < 0) - temp = -temp; - Points[i] = temp; - } - catch (...) { - } - Points[i].Normalize(); - } - } -} - TopoDS_Shape TopoShape::getSubShape(const char* Type) const { if (!Type) @@ -2706,3 +2589,91 @@ void TopoShape::getPoints(std::vector &Points, if (!hasFaces) Normals.clear(); } + +void TopoShape::getLinesFromSubelement(const Data::Segment* element, + std::vector &Points, + std::vector &lines) const +{ +} + +void TopoShape::getFacesFromSubelement(const Data::Segment* element, + std::vector &Points, + std::vector &PointNormals, + std::vector &faces) const +{ + if (element->getTypeId() == ShapeSegment::getClassTypeId()) { + const TopoDS_Shape& shape = static_cast(element)->Shape; + if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE) + return; + std::set vertices; + Standard_Real x1, y1, z1; + Standard_Real x2, y2, z2; + Standard_Real x3, y3, z3; + + Handle_StlMesh_Mesh aMesh = new StlMesh_Mesh(); +#if OCC_VERSION_HEX >= 0x060801 + StlTransfer::RetrieveMesh(shape, aMesh); +#else + throw Base::AttributeError("getFacesFromSubelement is available only in OCC 6.8.1 and up."); +#endif + + StlMesh_MeshExplorer xp(aMesh); + for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) { + for (xp.InitTriangle (nbd); xp.MoreTriangle (); xp.NextTriangle ()) { + xp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3); + Data::ComplexGeoData::Facet face; + std::set::iterator it; + + // 1st vertex + MeshVertex v1(x1,y1,z1); + it = vertices.find(v1); + if (it == vertices.end()) { + v1.i = vertices.size(); + face.I1 = v1.i; + vertices.insert(v1); + } + else { + face.I1 = it->i; + } + + // 2nd vertex + MeshVertex v2(x2,y2,z2); + it = vertices.find(v2); + if (it == vertices.end()) { + v2.i = vertices.size(); + face.I2 = v2.i; + vertices.insert(v2); + } + else { + face.I2 = it->i; + } + + // 3rd vertex + MeshVertex v3(x3,y3,z3); + it = vertices.find(v3); + if (it == vertices.end()) { + v3.i = vertices.size(); + face.I3 = v3.i; + vertices.insert(v3); + } + else { + face.I3 = it->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); + } + } + + (void)PointNormals; // leave this empty + std::vector points; + points.resize(vertices.size()); + for (std::set::iterator it = vertices.begin(); it != vertices.end(); ++it) + points[it->i] = it->toPoint(); + for (std::vector::iterator it = points.begin(); it != points.end(); ++it) + Points.push_back(Base::Vector3d(it->X(),it->Y(),it->Z())); + } +}