//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;
#ifndef _Prs3d_ShapeTool_HeaderFile
#define _Prs3d_ShapeTool_HeaderFile
-#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
-
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_Boolean.hxx>
#include <TopTools_HSequenceOfShape.hxx>
-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.
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;
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;
Standard_Integer myEdge;
Standard_Integer myVertex;
-
};
-
-
-
-
-
-
#endif // _Prs3d_ShapeTool_HeaderFile
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);
+ }
}
//==================================================================
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_HSurface.hxx>
+#include <OSD_Parallel.hxx>
#include <StdPrs_DeflectionCurve.hxx>
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <StdPrs_Isolines.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+//! 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<TopoDS_Face>& 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<TopoDS_Face>& 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())
{
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<TopoDS_Face> 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);
//! @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