MapOfInteger from BRepMesh,
BaseAllocator from BRepMesh,
DataMapOfFaceAttribute from BRepMesh,
- IndexedDataMapOfShapeListOfShape from TopTools
-
+ IndexedDataMapOfShapeListOfShape from TopTools,
+ MutexForShapeProvider from TopTools,
+ ShapeEnum from TopAbs
is
returns Boolean from Standard;
---Purpose:
-- Returns the multi-threading usage flag.
+
+ CreateMutexesForSubShapes(me : mutable;
+ theShape : Shape from TopoDS;
+ theType : ShapeEnum from TopAbs);
+ ---Purpose:
+ -- Creates mutexes for each sub-shape of type theType in theShape.
+ -- Used to avoid data races.
+
+ RemoveAllMutexes(me: mutable);
+ ---Purpose:
+ -- Removes all created mutexes
-- Output :
myMapdefle : DataMapOfShapeReal from TopTools;
myNottriangulated : ListOfShape from TopTools;
myAllocator : BaseAllocator from BRepMesh;
+ myMutexProvider: MutexForShapeProvider from TopTools;
end FastDiscret;
if (myInParallel)
{
#ifdef HAVE_TBB
+ CreateMutexesForSubShapes(theShape, TopAbs_EDGE);
// mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
#else
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
Process (*it);
#endif
+ RemoveAllMutexes();
}
else
{
if ( GetFaceAttribute (theFace, fattribute) )
{
BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
- aTool.Add (theFace, fattribute, GetMapOfDefEdge());
+ aTool.Add (theFace, fattribute, GetMapOfDefEdge(), myMutexProvider);
}
//cout << "END face " << theFace.TShape().operator->() << endl << flush;
}
if(myMapattrib.IsBound(theFace))
myMapattrib.UnBind(theFace);
}
+
+//=======================================================================
+//function : CreateMutexesForSubShapes
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscret::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
+ const TopAbs_ShapeEnum theType)
+{
+ myMutexProvider.CreateMutexesForSubShapes(theShape, theType);
+}
+
+//=======================================================================
+//function : RemoveAllMutexes
+//purpose :
+//=======================================================================
+void BRepMesh_FastDiscret::RemoveAllMutexes()
+{
+ myMutexProvider.RemoveAllMutexes();
+}
\ No newline at end of file
DataMapOfVertexInteger from BRepMesh,
DataMapOfIntegerListOfXY from BRepMesh,
DataMapOfShapeReal from TopTools,
+ MutexForShapeProvider from TopTools,
ListOfVertex from BRepMesh,
ClassifierPtr from BRepMesh,
Triangle from BRepMesh,
Triangulation from Poly,
Location from TopLoc
-
is
Create (theAngle : Real from Standard;
Add (me : mutable;
theFace : Face from TopoDS;
theAttrib : FaceAttribute from BRepMesh;
- theMapDefle : DataMapOfShapeReal from TopTools)
+ theMapDefle : DataMapOfShapeReal from TopTools;
+ theMutexProvider : MutexForShapeProvider from TopTools)
is static;
AddInShape (me: mutable;
theFace : Face from TopoDS;
- theDefFace: Real from Standard)
+ theDefFace: Real from Standard;
+ theMutexProvider: MutexForShapeProvider from TopTools)
is static private;
void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace,
const Handle(BRepMesh_FaceAttribute)& theAttrib,
- const TopTools_DataMapOfShapeReal& theMapDefle)
+ const TopTools_DataMapOfShapeReal& theMapDefle,
+ const TopTools_MutexForShapeProvider& theMutexProvider)
{
#ifndef DEB_MESH
try
}
myStructure->ReplaceNodes(aMoveNodes);
- AddInShape(face, (aDef < 0.0)? theAttrib->GetDefFace() : aDef);
+ AddInShape(face, (aDef < 0.0)? theAttrib->GetDefFace() : aDef, theMutexProvider);
#ifndef DEB_MESH
}
catch(Standard_Failure)
return Sqrt(maxdef);
}
+static Standard_Mutex DummyMutex;
+
//=======================================================================
//function : AddInShape
//purpose :
//=======================================================================
void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
- const Standard_Real theDefFace)
+ const Standard_Real theDefFace,
+ const TopTools_MutexForShapeProvider& theMutexProvider)
{
// gp_Pnt Pt;
BRep_Builder B;
const BRepMesh_PairOfPolygon& pair = It.Value();
const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
+
+ // lock mutex to prevent parallel change of the same data
+ Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
+ Standard_Mutex::SentryNested (aMutex == NULL ? DummyMutex : *aMutex,
+ aMutex != NULL);
+
if ( NOD1 == NOD2 ) {
B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc);
B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, T, loc);
#include <TopExp_Explorer.hxx>
#include <TopAbs.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MutexForShapeProvider.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TopoDS_Shape.hxx>
if (myInParallel)
{
#ifdef HAVE_TBB
+ myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
// mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
#else
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
myMesh->Process (*it);
#endif
+ myMesh->RemoveAllMutexes();
}
else
{
//! Callback method to unlock the mutex if OCC exception or signal is raised
virtual void DestroyCallback ();
+ //! This method should not be called (prohibited).
+ Standard_Mutex (const Standard_Mutex &);
+ //! This method should not be called (prohibited).
+ Standard_Mutex& operator = (const Standard_Mutex &);
+
private:
#ifdef WNT
CRITICAL_SECTION myMutex;
--- /dev/null
+TopTools_MutexForShapeProvider.hxx
+TopTools_MutexForShapeProvider.cxx
\ No newline at end of file
--
-- Package methods
- --
+ --
+
+ imported MutexForShapeProvider;
Dump(Sh : Shape from TopoDS; S : in out OStream);
---Purpose: Dumps the topological structure of <Sh> on the
--- /dev/null
+// Created on: 2012-06-27
+// Created by: Dmitry BOBYLEV
+// Copyright (c) 2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <TopTools_MutexForShapeProvider.hxx>
+
+#include <TopoDS_Iterator.hxx>
+
+// macro to compare two types of shapes
+#define SAMETYPE(x,y) ((x) == (y))
+#define LESSCOMPLEX(x,y) ((x) > (y))
+
+//=======================================================================
+//function : TopTools_MutexForShapeProvider
+//purpose :
+//=======================================================================
+TopTools_MutexForShapeProvider::TopTools_MutexForShapeProvider()
+{
+}
+
+
+//=======================================================================
+//function : ~TopTools_MutexForShapeProvider
+//purpose :
+//=======================================================================
+TopTools_MutexForShapeProvider::~TopTools_MutexForShapeProvider()
+{
+ RemoveAllMutexes();
+}
+
+//=======================================================================
+//function : CreateMutexesForSubShapes
+//purpose :
+//=======================================================================
+void TopTools_MutexForShapeProvider::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
+ const TopAbs_ShapeEnum theType)
+{
+ if (LESSCOMPLEX(theShape.ShapeType(), theType))
+ return;
+
+ for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next())
+ {
+ const TopoDS_Shape& aShape = anIt.Value();
+ if (LESSCOMPLEX(theType, aShape.ShapeType()))
+ {
+ CreateMutexesForSubShapes(aShape, theType);
+ }
+ else if (SAMETYPE(theType, aShape.ShapeType()))
+ {
+ CreateMutexForShape(aShape);
+ }
+ }
+}
+
+//=======================================================================
+//function : CreateMutexForShape
+//purpose :
+//=======================================================================
+void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& theShape)
+{
+ if (!myMap.IsBound(theShape))
+ {
+ Standard_Mutex* aMutex = new Standard_Mutex();
+ myMap.Bind(theShape, aMutex);
+ }
+}
+
+//=======================================================================
+//function : CreateMutexForShape
+//purpose :
+//=======================================================================
+Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& theShape) const
+{
+ if (myMap.IsBound(theShape))
+ {
+ Standard_Mutex* aMutex = myMap.Find(theShape);
+ return aMutex;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+//=======================================================================
+//function : RemoveAllMutexes
+//purpose :
+//=======================================================================
+void TopTools_MutexForShapeProvider::RemoveAllMutexes()
+{
+ for (NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher>::Iterator anIter;
+ anIter.More(); anIter.Next())
+ {
+ delete anIter.Value();
+ }
+ myMap.Clear();
+}
--- /dev/null
+// Created on: 2012-06-27
+// Created by: Dmitry BOBYLEV
+// Copyright (c) 2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+
+#ifndef _TopTools_MutexForShapeProvider_HeaderFile
+#define _TopTools_MutexForShapeProvider_HeaderFile
+
+#include <NCollection_DataMap.hxx>
+#include <Standard_Mutex.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+
+
+//! Class TopTools_MutexForShapeProvider
+//! This class is used to create and store mutexes associated with shapes.
+class TopTools_MutexForShapeProvider
+{
+public:
+ //! Constructor
+ Standard_EXPORT TopTools_MutexForShapeProvider();
+
+ //! Destructor
+ Standard_EXPORT ~TopTools_MutexForShapeProvider();
+
+ //! Creates and associates mutexes with each sub-shape of type theType in theShape.
+ Standard_EXPORT void CreateMutexesForSubShapes(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType);
+
+ //! Creates and associates mutex with theShape
+ Standard_EXPORT void CreateMutexForShape(const TopoDS_Shape& theShape);
+
+ //! Returns pointer to mutex associated with theShape.
+ //! In case when mutex not found returns NULL.
+ Standard_EXPORT Standard_Mutex* GetMutex(const TopoDS_Shape& theShape) const;
+
+ //! Removes all mutexes
+ Standard_EXPORT void RemoveAllMutexes();
+
+private:
+ //! This method should not be called (prohibited).
+ TopTools_MutexForShapeProvider (const TopTools_MutexForShapeProvider &);
+ //! This method should not be called (prohibited).
+ TopTools_MutexForShapeProvider & operator = (const TopTools_MutexForShapeProvider &);
+
+
+ NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher> myMap;
+
+};
+
+#endif
\ No newline at end of file