From 5b4c246944c72459016efff6ae903ac66c090991 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 8 Oct 2021 22:32:26 +0200 Subject: [PATCH] PD: simplify code to display rejected shape and move it to its own function --- .../Gui/ViewProviderTransformed.cpp | 280 ++++++++---------- .../PartDesign/Gui/ViewProviderTransformed.h | 3 + 2 files changed, 128 insertions(+), 155 deletions(-) diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp index 0d402d0b71..0e3b7f0b06 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -198,162 +199,131 @@ void ViewProviderTransformed::recomputeFeature(bool recompute) } // Display the rejected transformations in red - if (rejected > 0) { - try { - // calculating the deflection value - Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; - { - Bnd_Box bounds; - BRepBndLib::Add(cShape, bounds); - bounds.SetGap(0.0); - bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); - } - Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); - - // create or use the mesh on the data structure - // Note: This DOES have an effect on cShape -#if OCC_VERSION_HEX >= 0x060600 - Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; - BRepMesh_IncrementalMesh(cShape,deflection,Standard_False, - AngDeflectionRads,Standard_True); -#else - BRepMesh_IncrementalMesh(cShape,deflection); -#endif - // We must reset the location here because the transformation data - // are set in the placement property - TopLoc_Location aLoc; - cShape.Location(aLoc); - - // count triangles and nodes in the mesh - int nbrTriangles=0, nbrNodes=0; - TopExp_Explorer Ex; - for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) { - Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc); - // Note: we must also count empty faces - if (!mesh.IsNull()) { - nbrTriangles += mesh->NbTriangles(); - nbrNodes += mesh->NbNodes(); - } - } - - // create memory for the nodes and indexes - SoCoordinate3* rejectedCoords = new SoCoordinate3(); - rejectedCoords ->point .setNum(nbrNodes); - SoNormal* rejectedNorms = new SoNormal(); - rejectedNorms ->vector .setNum(nbrNodes); - SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); - rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); - - // get the raw memory for fast fill up - SbVec3f* verts = rejectedCoords ->point .startEditing(); - SbVec3f* norms = rejectedNorms ->vector .startEditing(); - int32_t* index = rejectedFaceSet ->coordIndex .startEditing(); - - // preset the normal vector with null vector - for (int i=0; i < nbrNodes; i++) - norms[i]= SbVec3f(0.0,0.0,0.0); - - int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0; - for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) { - TopLoc_Location aLoc; - const TopoDS_Face &actFace = TopoDS::Face(Ex.Current()); - // get the mesh of the shape - Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc); - if (mesh.IsNull()) continue; - - // getting the transformation of the shape/face - gp_Trsf myTransf; - Standard_Boolean identity = true; - if (!aLoc.IsIdentity()) { - identity = false; - myTransf = aLoc.Transformation(); - } - - // getting size of node and triangle array of this face - int nbNodesInFace = mesh->NbNodes(); - int nbTriInFace = mesh->NbTriangles(); - // check orientation - TopAbs_Orientation orient = actFace.Orientation(); - - // cycling through the poly mesh - const Poly_Array1OfTriangle& Triangles = mesh->Triangles(); - const TColgp_Array1OfPnt& Nodes = mesh->Nodes(); - for (int g=1; g <= nbTriInFace; g++) { - // Get the triangle - Standard_Integer N1,N2,N3; - Triangles(g).Get(N1,N2,N3); - - // change orientation of the triangle if the face is reversed - if ( orient != TopAbs_FORWARD ) { - Standard_Integer tmp = N1; - N1 = N2; - N2 = tmp; - } - - // get the 3 points of this triangle - gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3)); - - // transform the vertices to the place of the face - if (!identity) { - V1.Transform(myTransf); - V2.Transform(myTransf); - V3.Transform(myTransf); - } - - // calculating per vertex normals - // 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); - - // add the triangle normal to the vertex normal for all points of this triangle - norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); - - // set the vertices - verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z())); - verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z())); - verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z())); - - // set the index vector with the 3 point indexes and the end delimiter - index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1; - index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1; - index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1; - index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX; - } - - // counting up the per Face offsets - FaceNodeOffset += nbNodesInFace; - FaceTriaOffset += nbTriInFace; - - - // normalize all normals - for (int i=0; i < nbrNodes; i++) - norms[i].normalize(); - - // end the editing of the nodes - rejectedCoords ->point .finishEditing(); - rejectedNorms ->vector .finishEditing(); - rejectedFaceSet ->coordIndex .finishEditing(); - - // fill in the transformation matrices - SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); - - - rejectedTrfms->matrix.finishEditing(); - rejectedTrfms->addChild(rejectedFaceSet); - SoSeparator* sep = new SoSeparator(); - sep->addChild(rejectedCoords); - sep->addChild(rejectedNorms); - sep->addChild(rejectedTrfms); - pcRejectedRoot->addChild(sep); - } - } - catch (...) { - Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", - pcTransformed->getNameInDocument()); - } + showRejectedShape(cShape); } } +void ViewProviderTransformed::showRejectedShape(TopoDS_Shape shape) +{ + try { + // calculating the deflection value + Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; + { + Bnd_Box bounds; + BRepBndLib::Add(shape, bounds); + bounds.SetGap(0.0); + bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); + } + Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); + + // create or use the mesh on the data structure + // Note: This DOES have an effect on shape +#if OCC_VERSION_HEX >= 0x060600 + Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; + BRepMesh_IncrementalMesh(shape, deflection, Standard_False, AngDeflectionRads, Standard_True); +#else + BRepMesh_IncrementalMesh(shape, deflection); +#endif + // We must reset the location here because the transformation data + // are set in the placement property + TopLoc_Location aLoc; + shape.Location(aLoc); + + // count triangles and nodes in the mesh + int nbrTriangles=0, nbrNodes=0; + TopExp_Explorer Ex; + for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) { + Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc); + // Note: we must also count empty faces + if (!mesh.IsNull()) { + nbrTriangles += mesh->NbTriangles(); + nbrNodes += mesh->NbNodes(); + } + } + + // create memory for the nodes and indexes + SoCoordinate3* rejectedCoords = new SoCoordinate3(); + rejectedCoords ->point .setNum(nbrNodes); + SoNormal* rejectedNorms = new SoNormal(); + rejectedNorms ->vector .setNum(nbrNodes); + SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); + rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); + + // get the raw memory for fast fill up + SbVec3f* verts = rejectedCoords ->point .startEditing(); + SbVec3f* norms = rejectedNorms ->vector .startEditing(); + int32_t* index = rejectedFaceSet ->coordIndex .startEditing(); + + // preset the normal vector with null vector + for (int i=0; i < nbrNodes; i++) + norms[i]= SbVec3f(0.0,0.0,0.0); + + int FaceNodeOffset=0,FaceTriaOffset=0; + for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) { + const TopoDS_Face &actFace = TopoDS::Face(Ex.Current()); + + // get triangulation + std::vector points; + std::vector facets; + if (!Part::Tools::getTriangulation(actFace, points, facets)) + continue; + + // get normal per vertex + std::vector vertexnormals; + Part::Tools::getPointNormals(points, facets, vertexnormals); + + // getting size of node and triangle array of this face + std::size_t nbNodesInFace = points.size(); + std::size_t nbTriInFace = facets.size(); + + for (std::size_t i = 0; i < points.size(); i++) { + verts[FaceNodeOffset+i] = SbVec3f(points[i].X(), points[i].Y(), points[i].Z()); + } + + for (std::size_t i = 0; i < vertexnormals.size(); i++) { + norms[FaceNodeOffset+i] = SbVec3f(vertexnormals[i].X(), vertexnormals[i].Y(), vertexnormals[i].Z()); + } + + // cycling through the poly mesh + for (std::size_t g=0; g < nbTriInFace; g++) { + // Get the triangle + Standard_Integer N1,N2,N3; + facets[g].Get(N1,N2,N3); + + // set the index vector with the 3 point indexes and the end delimiter + index[FaceTriaOffset*4+4*g] = FaceNodeOffset+N1; + index[FaceTriaOffset*4+4*g+1] = FaceNodeOffset+N2; + index[FaceTriaOffset*4+4*g+2] = FaceNodeOffset+N3; + index[FaceTriaOffset*4+4*g+3] = SO_END_FACE_INDEX; + } + + // counting up the per Face offsets + FaceNodeOffset += nbNodesInFace; + FaceTriaOffset += nbTriInFace; + + // normalize all normals + for (int i=0; i < nbrNodes; i++) + norms[i].normalize(); + + // end the editing of the nodes + rejectedCoords ->point .finishEditing(); + rejectedNorms ->vector .finishEditing(); + rejectedFaceSet ->coordIndex .finishEditing(); + + // fill in the transformation matrices + SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); + rejectedTrfms->matrix.finishEditing(); + rejectedTrfms->addChild(rejectedFaceSet); + SoSeparator* sep = new SoSeparator(); + sep->addChild(rejectedCoords); + sep->addChild(rejectedNorms); + sep->addChild(rejectedTrfms); + pcRejectedRoot->addChild(sep); + } + } + catch (...) { + Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", + getObject()->getNameInDocument()); + } +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h index 50a72ca1ae..ec4b8e1226 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h @@ -68,6 +68,9 @@ protected: public: void recomputeFeature(bool recompute=true); QString getMessage() const {return diagMessage;} + +private: + void showRejectedShape(TopoDS_Shape shape); };