From f933136b63cabe8d21b93363a3306accd09a0e7b Mon Sep 17 00:00:00 2001 From: kgv Date: Sun, 25 Mar 2018 13:55:30 +0300 Subject: [PATCH] 0026072: Visualization - more realistic display of face edges StdPrs_ShadedShape::FillFaceBoundaries() - compute Edges with normals --- src/Graphic3d/Graphic3d_ArrayOfSegments.hxx | 6 +- src/StdPrs/StdPrs_ShadedShape.cxx | 95 +++++++++++++-------- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx b/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx index 07750ff7fb..4dfc460695 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx @@ -49,10 +49,12 @@ public: //! @param theMaxVertexs defines the maximum allowed vertex number in the array //! @param theMaxEdges defines the maximum allowed edge number in the array //! @param theHasVColors when TRUE, AddVertex(Point,Color) should be used for specifying vertex color + //! @param theHasVNormals when TRUE, AddVertex(Point,Normal) should be used for specifying vertex with normal Graphic3d_ArrayOfSegments (const Standard_Integer theMaxVertexs, const Standard_Integer theMaxEdges = 0, - const Standard_Boolean theHasVColors = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, Standard_False, theHasVColors, Standard_False, Standard_False) {} + const Standard_Boolean theHasVColors = Standard_False, + const Standard_Boolean theHasVNormals = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, Standard_False) {} }; diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index e29b6950c0..48fcfe0a6a 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -306,7 +306,7 @@ namespace Standard_Integer aNodeNumber = 0; Standard_Integer aNbPolylines = 0; - TopLoc_Location aTrsf; + TopLoc_Location aLoc; TColgp_SequenceOfPnt aSeqPntsExtra; for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) { @@ -332,14 +332,14 @@ namespace // take one of the shared edges and get edge triangulation const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First()); - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLoc); if (aTriangulation.IsNull()) { continue; } const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); - Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aLoc); if (!anEdgePoly.IsNull() && anEdgePoly->Nodes().Length() >= 2) { @@ -366,7 +366,7 @@ namespace // create indexed segments array to pack polylines from different edges into single array const Standard_Integer aSegmentEdgeNb = (aNodeNumber - aNbPolylines) * 2; - Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aSeqPntsExtra.Size(), aSegmentEdgeNb + aSeqPntsExtra.Size()); + Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aSeqPntsExtra.Size(), aSegmentEdgeNb + aSeqPntsExtra.Size(), false, true); for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgesMap); anEdgeIter.More(); anEdgeIter.Next()) { if (anEdgeIter.Value().Extent() == 0) @@ -374,43 +374,68 @@ namespace continue; } - const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First()); - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf); - if (aTriangulation.IsNull()) + Standard_Integer aFaceIndex = 0; + const Standard_Integer aFirstNodeInFace = aSegments->VertexNumber() + 1; + const Standard_Integer aNbFaces = anEdgeIter.Value().Extent(); + for (TopTools_ListOfShape::Iterator aFaceIter (anEdgeIter.Value()); aFaceIter.More(); aFaceIter.Next()) { - continue; - } - - const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); - Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); - if (anEdgePoly.IsNull() - || anEdgePoly->Nodes().Length () < 2) - { - continue; - } - - // get edge nodes indexes from face triangulation - const TColgp_Array1OfPnt& aTriNodes = aTriangulation->Nodes(); - const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes(); + const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value()); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLoc); + if (aTriangulation.IsNull()) + { + continue; + } - // collect the edge nodes - Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1; - for (Standard_Integer aNodeIdx = anEdgeNodes.Lower(); aNodeIdx <= anEdgeNodes.Upper(); ++aNodeIdx) - { - // node index in face triangulation - // get node and apply location transformation to the node - const Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx); - gp_Pnt aTriNode = aTriNodes.Value (aTriIndex); - if (!aTrsf.IsIdentity()) + const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aLoc); + if (anEdgePoly.IsNull() + || anEdgePoly->Nodes().Length () < 2) { - aTriNode.Transform (aTrsf); + continue; } - aSegments->AddVertex (aTriNode); - if (aNodeIdx != anEdgeNodes.Lower()) + // get edge nodes indexes from face triangulation + ++aFaceIndex; + const TColgp_Array1OfPnt& aTriNodes = aTriangulation->Nodes(); + const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes(); + const gp_Trsf& aTrsf = aLoc.Transformation(); + + // collect the edge nodes + Standard_Integer aSegmentEdge = aFirstNodeInFace; + for (Standard_Integer aNodeIdx = anEdgeNodes.Lower(); aNodeIdx <= anEdgeNodes.Upper(); ++aNodeIdx) { - aSegments->AddEdge ( aSegmentEdge); - aSegments->AddEdge (++aSegmentEdge); + // node index in face triangulation + // get node and apply location transformation to the node + const Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx); + gp_Pnt aTriNode = aTriNodes.Value (aTriIndex); + gp_Dir aNorm = aTriangulation->Normal (aTriIndex); + if (aFace.Orientation() == TopAbs_REVERSED) + { + aNorm.Reverse(); + } + if (!aLoc.IsIdentity()) + { + aTriNode.Transform (aTrsf); + aNorm.Transform (aTrsf); + } + + if (aFaceIndex == 1) + { + aSegments->AddVertex (aTriNode, aNorm); + if (aNodeIdx != anEdgeNodes.Lower()) + { + aSegments->AddEdge ( aSegmentEdge); + aSegments->AddEdge (++aSegmentEdge); + } + } + else + { + gp_XYZ aNormSum; + aSegments->VertexNormal (aSegmentEdge, aNormSum.ChangeCoord (1), aNormSum.ChangeCoord (2), aNormSum.ChangeCoord (3)); + aNormSum += aNorm.XYZ(); + aSegments->SetVertexNormal (aSegmentEdge, aNormSum.ChangeCoord (1), aNormSum.ChangeCoord (2), aNormSum.ChangeCoord (3)); + ++aSegmentEdge; + } } } } -- 2.39.5