From: kgv Date: Thu, 25 May 2017 14:36:10 +0000 (+0300) Subject: 0028788: Visualization, StdPrs_WFShape - Add option to compute Isolines using multipl... X-Git-Tag: V7_2_0_beta~119 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=884cafd8935201add6c3d10808148ee3fcb59995;p=occt-copy.git 0028788: Visualization, StdPrs_WFShape - Add option to compute Isolines using multiple threads StdPrs_WFShape::Add() now accepts new argument theIsParallel (FALSE by default) for computing Isolines using multiple threads (if there is more then 1 Face). StdPrs_Isolines::addOnTriangulation() - changed the iteration order (cosmetics). --- diff --git a/src/Prs3d/Prs3d_ShapeTool.cxx b/src/Prs3d/Prs3d_ShapeTool.cxx index edb891254f..732f3205a7 100644 --- a/src/Prs3d/Prs3d_ShapeTool.cxx +++ b/src/Prs3d/Prs3d_ShapeTool.cxx @@ -142,11 +142,10 @@ Bnd_Box Prs3d_ShapeTool::FaceBound() const //purpose : //======================================================================= -Standard_Boolean Prs3d_ShapeTool::IsPlanarFace() const +Standard_Boolean Prs3d_ShapeTool::IsPlanarFace (const TopoDS_Face& theFace) { TopLoc_Location l; - const TopoDS_Face& F = TopoDS::Face(myFaceExplorer.Current()); - const Handle(Geom_Surface)& S = BRep_Tool::Surface(F, l); + const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace, l); if (S.IsNull()) { return Standard_False; diff --git a/src/Prs3d/Prs3d_ShapeTool.hxx b/src/Prs3d/Prs3d_ShapeTool.hxx index a8bae58698..cd64f03660 100644 --- a/src/Prs3d/Prs3d_ShapeTool.hxx +++ b/src/Prs3d/Prs3d_ShapeTool.hxx @@ -17,37 +17,29 @@ #ifndef _Prs3d_ShapeTool_HeaderFile #define _Prs3d_ShapeTool_HeaderFile -#include #include -#include - +#include +#include #include #include #include #include -#include -#include #include -class TopoDS_Shape; -class TopoDS_Face; + class Bnd_Box; class TopoDS_Edge; class TopoDS_Vertex; class Poly_Triangulation; -class TopLoc_Location; class Poly_PolygonOnTriangulation; class Poly_Polygon3D; - //! describes the behaviour requested for a wireframe //! shape presentation. class Prs3d_ShapeTool { public: - DEFINE_STANDARD_ALLOC - //! Constructs the tool and initializes it using theShape and theAllVertices //! (optional) arguments. By default, only isolated and internal vertices are considered, //! however if theAllVertices argument is equal to True, all shape's vertices are taken into account. @@ -62,9 +54,13 @@ public: Standard_EXPORT const TopoDS_Face& GetFace() const; Standard_EXPORT Bnd_Box FaceBound() const; - - Standard_EXPORT Standard_Boolean IsPlanarFace() const; - + + Standard_Boolean IsPlanarFace() const + { + const TopoDS_Face& aFace = TopoDS::Face (myFaceExplorer.Current()); + return IsPlanarFace (aFace); + } + Standard_EXPORT void InitCurve(); Standard_EXPORT Standard_Boolean MoreCurve() const; @@ -97,19 +93,12 @@ public: Standard_EXPORT Handle(Poly_Polygon3D) Polygon3D (TopLoc_Location& l) const; +public: - - -protected: - - - - + Standard_EXPORT static Standard_Boolean IsPlanarFace (const TopoDS_Face& theFace); private: - - TopoDS_Shape myShape; TopExp_Explorer myFaceExplorer; TopTools_IndexedDataMapOfShapeListOfShape myEdgeMap; @@ -117,13 +106,6 @@ private: Standard_Integer myEdge; Standard_Integer myVertex; - }; - - - - - - #endif // _Prs3d_ShapeTool_HeaderFile diff --git a/src/StdPrs/StdPrs_Isolines.cxx b/src/StdPrs/StdPrs_Isolines.cxx index 15e7a4b6e5..6df065af5d 100644 --- a/src/StdPrs/StdPrs_Isolines.cxx +++ b/src/StdPrs/StdPrs_Isolines.cxx @@ -231,87 +231,67 @@ void StdPrs_Isolines::addOnTriangulation (const Handle(Poly_Triangulation)& theT Prs3d_NListOfSequenceOfPnt& theUPolylines, Prs3d_NListOfSequenceOfPnt& theVPolylines) { - const Standard_Integer aNbIsoU = theUIsoParams.Length(); - const Standard_Integer aNbIsoV = theVIsoParams.Length(); - - SeqOfVecOfSegments aUPolylines, aVPolylines; - const Poly_Array1OfTriangle& aTriangles = theTriangulation->Triangles(); const TColgp_Array1OfPnt& aNodes = theTriangulation->Nodes(); const TColgp_Array1OfPnt2d& aUVNodes = theTriangulation->UVNodes(); - - TColStd_Array1OfInteger aUIsoIndexes (1, aNbIsoU); - TColStd_Array1OfInteger aVIsoIndexes (1, aNbIsoV); - aUIsoIndexes.Init (-1); - aVIsoIndexes.Init (-1); - - for (Standard_Integer anI = aTriangles.Lower(); anI <= aTriangles.Upper(); ++anI) + for (Standard_Integer anUVIter = 0; anUVIter < 2; ++anUVIter) { - Standard_Integer aNodeIdxs[3]; - aTriangles.Value (anI).Get (aNodeIdxs[0], aNodeIdxs[1],aNodeIdxs[2]); - const gp_Pnt aNodesXYZ[3] = { aNodes.Value (aNodeIdxs[0]), - aNodes.Value (aNodeIdxs[1]), - aNodes.Value (aNodeIdxs[2]) }; - const gp_Pnt2d aNodesUV[3] = { aUVNodes.Value (aNodeIdxs[0]), - aUVNodes.Value (aNodeIdxs[1]), - aUVNodes.Value (aNodeIdxs[2]) }; - - // Evaluate polyline points for u isolines. - for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoU; ++anIsoIdx) + const Standard_Boolean isUIso = anUVIter == 0; + const TColStd_SequenceOfReal& anIsoParams = isUIso ? theUIsoParams : theVIsoParams; + const Standard_Integer aNbIsolines = anIsoParams.Length(); + if (aNbIsolines == 0) { - SegOnIso aSegment; - const gp_Lin2d anIsolineUV = isoU (theUIsoParams.Value (anIsoIdx)); - - // Find intersections with triangle in uv space and its projection on triangulation. - if (!findSegmentOnTriangulation (theSurface, true, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) - { - continue; - } - - if (aUIsoIndexes.Value (anIsoIdx) == -1) - { - aUPolylines.Append (new VecOfSegments()); - aUIsoIndexes.SetValue (anIsoIdx, aUPolylines.Size()); - } - - Handle(VecOfSegments) anIsoPnts = aUPolylines.ChangeValue (aUIsoIndexes.Value (anIsoIdx)); - if (!theLocation.IsIdentity()) - { - aSegment[0].Pnt.Transform (theLocation); - aSegment[1].Pnt.Transform (theLocation); - } - anIsoPnts->Append (aSegment); + continue; } - // Evaluate polyline points for v isolines. - for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoV; ++anIsoIdx) + SeqOfVecOfSegments aPolylines; + TColStd_Array1OfInteger anIsoIndexes (1, aNbIsolines); + anIsoIndexes.Init (-1); + for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsolines; ++anIsoIdx) { - SegOnIso aSegment; - const gp_Lin2d anIsolineUV = isoV (theVIsoParams.Value (anIsoIdx)); - - if (!findSegmentOnTriangulation (theSurface, false, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) + const gp_Lin2d anIsolineUV = isUIso ? isoU (anIsoParams.Value (anIsoIdx)) : isoV (anIsoParams.Value (anIsoIdx)); + Handle(VecOfSegments) anIsoPnts; + if (anIsoIndexes.Value (anIsoIdx) != -1) { - continue; + anIsoPnts = aPolylines.ChangeValue (anIsoIndexes.Value (anIsoIdx)); } - if (aVIsoIndexes.Value (anIsoIdx) == -1) + for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter) { - aVPolylines.Append (new VecOfSegments()); - aVIsoIndexes.SetValue (anIsoIdx, aVPolylines.Size()); - } + Standard_Integer aNodeIdxs[3]; + aTriangles.Value (aTriIter).Get (aNodeIdxs[0], aNodeIdxs[1],aNodeIdxs[2]); + const gp_Pnt aNodesXYZ[3] = { aNodes.Value (aNodeIdxs[0]), + aNodes.Value (aNodeIdxs[1]), + aNodes.Value (aNodeIdxs[2]) }; + const gp_Pnt2d aNodesUV[3] = { aUVNodes.Value (aNodeIdxs[0]), + aUVNodes.Value (aNodeIdxs[1]), + aUVNodes.Value (aNodeIdxs[2]) }; + + // Find intersections with triangle in uv space and its projection on triangulation. + SegOnIso aSegment; + if (!findSegmentOnTriangulation (theSurface, isUIso, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) + { + continue; + } - Handle(VecOfSegments) anIsoPnts = aVPolylines.ChangeValue (aVIsoIndexes.Value (anIsoIdx)); - if (!theLocation.IsIdentity()) - { - aSegment[0].Pnt.Transform (theLocation); - aSegment[1].Pnt.Transform (theLocation); + if (anIsoPnts.IsNull()) + { + aPolylines.Append (new VecOfSegments()); + anIsoIndexes.SetValue (anIsoIdx, aPolylines.Size()); + anIsoPnts = aPolylines.ChangeValue (anIsoIndexes.Value (anIsoIdx)); + } + + if (!theLocation.IsIdentity()) + { + aSegment[0].Pnt.Transform (theLocation); + aSegment[1].Pnt.Transform (theLocation); + } + anIsoPnts->Append (aSegment); } - anIsoPnts->Append (aSegment); } - } - sortSegments (aUPolylines, theUPolylines); - sortSegments (aVPolylines, theVPolylines); + sortSegments (aPolylines, isUIso ? theUPolylines : theVPolylines); + } } //================================================================== diff --git a/src/StdPrs/StdPrs_WFShape.cxx b/src/StdPrs/StdPrs_WFShape.cxx index f566250dae..418e0a3b23 100644 --- a/src/StdPrs/StdPrs_WFShape.cxx +++ b/src/StdPrs/StdPrs_WFShape.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -41,13 +42,56 @@ #include #include +//! Functor for executing StdPrs_Isolines in parallel threads. +class StdPrs_WFShape_IsoFunctor +{ +public: + StdPrs_WFShape_IsoFunctor (Prs3d_NListOfSequenceOfPnt& thePolylinesU, + Prs3d_NListOfSequenceOfPnt& thePolylinesV, + const std::vector& theFaces, + const Handle(Prs3d_Drawer)& theDrawer, + Standard_Real theShapeDeflection) + : myPolylinesU (thePolylinesU), + myPolylinesV (thePolylinesV), + myFaces (theFaces), + myDrawer (theDrawer), + myShapeDeflection (theShapeDeflection) + { + // + } + + void operator()(const Standard_Integer& theIndex) const + { + Prs3d_NListOfSequenceOfPnt aPolylinesU, aPolylinesV; + const TopoDS_Face& aFace = myFaces[theIndex]; + StdPrs_Isolines::Add (aFace, myDrawer, myShapeDeflection, aPolylinesU, aPolylinesV); + { + Standard_Mutex::Sentry aLock (myMutex); + myPolylinesU.Append (aPolylinesU); + myPolylinesV.Append (aPolylinesV); + } + } + +private: + StdPrs_WFShape_IsoFunctor operator= (StdPrs_WFShape_IsoFunctor& ); +private: + Prs3d_NListOfSequenceOfPnt& myPolylinesU; + Prs3d_NListOfSequenceOfPnt& myPolylinesV; + const std::vector& myFaces; + const Handle(Prs3d_Drawer)& myDrawer; + mutable Standard_Mutex myMutex; + const Standard_Real myShapeDeflection; +}; + + // ========================================================================= // function : Add // purpose : // ========================================================================= -void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) +void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer, + Standard_Boolean theIsParallel) { if (theShape.IsNull()) { @@ -106,14 +150,43 @@ void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, aVPolylinesPtr = &aCommonPolylines; } - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) + bool isParallelIso = false; + if (theIsParallel) { - if (aTool.IsPlanarFace() && !theDrawer->IsoOnPlane()) + Standard_Integer aNbFaces = 0; + for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) { - continue; + ++aNbFaces; } + if (aNbFaces > 1) + { + isParallelIso = true; + std::vector aFaces (aNbFaces); + aNbFaces = 0; + for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current()); + if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace)) + { + aFaces[aNbFaces++] = aFace; + } + } + + StdPrs_WFShape_IsoFunctor anIsoFunctor (*aUPolylinesPtr, *aVPolylinesPtr, aFaces, theDrawer, aShapeDeflection); + OSD_Parallel::For (0, aNbFaces - 1, anIsoFunctor, aNbFaces < 2); + } + } - StdPrs_Isolines::Add (aTool.GetFace(), theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr); + if (!isParallelIso) + { + for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current()); + if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace)) + { + StdPrs_Isolines::Add (aFace, theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr); + } + } } Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectU, aUPolylines); diff --git a/src/StdPrs/StdPrs_WFShape.hxx b/src/StdPrs/StdPrs_WFShape.hxx index db759de52c..de35127f46 100755 --- a/src/StdPrs/StdPrs_WFShape.hxx +++ b/src/StdPrs/StdPrs_WFShape.hxx @@ -33,9 +33,11 @@ public: //! @param thePresentation [in] the presentation. //! @param theShape [in] the shape. //! @param theDrawer [in] the draw settings. - Standard_EXPORT static void Add (const Handle (Prs3d_Presentation)& thePresentation, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer); + //! @param theIsParallel [in] perform algorithm using multiple threads + Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer, + Standard_Boolean theIsParallel = Standard_False); //! Compute free and boundary edges on a triangulation of each face in the given shape. //! @param theShape [in] the list of triangulated faces