1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-30 13:05:50 +03:00

0022600: TBB has to be disabled in BRepMesh due to data races

This commit is contained in:
KGV 2011-09-07 08:30:31 +00:00 committed by bugmaster
parent 7edf74fd3d
commit 0b97567d24
14 changed files with 701 additions and 447 deletions

View File

@ -32,7 +32,8 @@ uses Standard,
GeomAbs,
GeomAdaptor,
TopLoc,
SortTools
SortTools,
Plugin
is enumeration DegreeOfFreedom is
@ -79,6 +80,8 @@ is enumeration DegreeOfFreedom is
imported VertexCellFilter from BRepMesh;
imported VectorOfVertex from BRepMesh;
primitive PluginEntryType;
class ComparatorOfVertexOfDelaun;
class ComparatorOfIndexedVertexOfDelaun;
class SelectorOfDataStructureOfDelaun;

View File

@ -1,22 +1,26 @@
-- File: BRepMesh_DiscretFactory.cdl
-- Created: Thu Apr 10 12:34:15 2008
-- Author: Peter KURNEV
-- <pkv@irinox>
-- Author: Peter KURNEV <pkv@irinox>
--
---Copyright: Matra Datavision 2008
class DiscretFactory from BRepMesh
---Purpose:
-- This class intended to setup / retrieve default triangulation algorithm.
-- Use BRepMesh_DiscretFactory::Get() static method to retrieve global Factory instance.
-- Use BRepMesh_DiscretFactory::Discret() method to retrieve meshing tool.
uses
AsciiString from TCollection,
PDiscretRoot from BRepMesh,
MapOfAsciiString from TColStd,
DiscretRoot from BRepMesh,
FactoryError from BRepMesh,
Shape from TopoDS
--raises
PluginEntryType from BRepMesh,
AsciiString from TCollection,
MapOfAsciiString from TColStd,
Shape from TopoDS,
MapOfFunctions from Plugin
--raises
is
Create
@ -27,45 +31,75 @@ is
Get (myclass)
returns DiscretFactory from BRepMesh;
---C++: return &
---Purpose:
-- Returns the global factory instance.
Names (me)
returns MapOfAsciiString from TColStd;
---C++: return const &
---Purpose:
-- Returns the list of registered meshing algorithms.
SetDefaultName ( me : out;
theName:AsciiString from TCollection);
theName : AsciiString from TCollection)
returns Boolean from Standard;
---Purpose:
-- Setup meshing algorithm by name.
-- Returns true if requested tool is available.
-- On fail Factory will continue to use previous algo.
DefaultName (me)
returns AsciiString from TCollection;
---C++: return const &
---Purpose:
-- Returns name for current meshing algorithm.
SetFunctionName ( me : out;
theName:AsciiString from TCollection);
theFuncName : AsciiString from TCollection)
returns Boolean from Standard;
---Purpose:
-- Advanced function. Changes function name to retrieve from plugin.
-- Returns true if requested tool is available.
-- On fail Factory will continue to use previous algo.
SetDefault ( me : out;
theName : AsciiString from TCollection;
theFuncName : AsciiString from TCollection = "DISCRETALGO")
returns Boolean from Standard;
---Purpose:
-- Setup meshing algorithm that should be created by this Factory.
-- Returns true if requested tool is available.
-- On fail Factory will continue to use previous algo.
-- Call ::ErrorStatus() method to retrieve fault reason.
FunctionName (me)
returns AsciiString from TCollection;
---C++: return const &
---Purpose:
-- Returns function name that should be exported by plugin.
Discret (me : out;
theShape : Shape from TopoDS;
theDeflection : Real from Standard;
theAngle : Real from Standard)
returns PDiscretRoot from BRepMesh;
---C++: return &
returns DiscretRoot from BRepMesh;
---Purpose:
-- Returns triangulation algorithm instance.
ErrorStatus (me)
returns FactoryError from BRepMesh;
---Purpose:
-- Returns error status for last meshing algorithm switch.
Clear (me : out)
is protected;
fields
myPDiscret : PDiscretRoot from BRepMesh is protected;
myPluginEntry : PluginEntryType from BRepMesh is protected;
myErrorStatus : FactoryError from BRepMesh is protected;
myNames : MapOfAsciiString from TColStd is protected;
myFixedNames : AsciiString from TCollection[1] is protected;
myDefaultName : AsciiString from TCollection is protected;
myFunctionName : AsciiString from TCollection is protected;
myFactoryMethods : MapOfFunctions from Plugin is protected;
end DiscretFactory;

View File

@ -1,209 +1,22 @@
// File: BRepMesh_DiscretFactory.cxx
// Created: Thu Apr 10 13:32:00 2008
// Author: Peter KURNEV
// <pkv@irinox>
// Author: Peter KURNEV <pkv@irinox>
#include <BRepMesh_DiscretFactory.ixx>
#include <OSD_SharedLibrary.hxx>
#include <OSD_Function.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepMesh_PDiscretRoot.hxx>
static
void MakeLibName(const TCollection_AsciiString& ,
TCollection_AsciiString& );
static
Standard_Integer CreateDiscret(const TopoDS_Shape& theShape,
const Standard_Real ,
const Standard_Real ,
OSD_Function& ,
BRepMesh_PDiscretRoot& );
namespace
{
//! Embedded triangulation tool(s)
static TCollection_AsciiString THE_FAST_DISCRET_MESH ("FastDiscret");
//=======================================================================
//function : BRepMesh_DiscretFactory
//purpose :
//=======================================================================
BRepMesh_DiscretFactory::BRepMesh_DiscretFactory()
{
myFixedNames[0]="FastDiscret";
//
myNames.Add(myFixedNames[0]);
myDefaultName=myFixedNames[0];
myFunctionName="DISCRETALGO";
myPDiscret=NULL;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BRepMesh_DiscretFactory::~BRepMesh_DiscretFactory()
{
Clear();
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
void BRepMesh_DiscretFactory::Clear()
{
if (myPDiscret) {
delete myPDiscret;
myPDiscret=NULL;
}
}
//=======================================================================
//function : Get
//purpose :
//=======================================================================
BRepMesh_DiscretFactory& BRepMesh_DiscretFactory::Get()
{
static BRepMesh_DiscretFactory* sFactory;
static Standard_Boolean isInit=Standard_False;
if(!isInit) {
isInit = Standard_True;
sFactory = new BRepMesh_DiscretFactory;
}
return *sFactory;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
BRepMesh_FactoryError BRepMesh_DiscretFactory::ErrorStatus()const
{
return myErrorStatus;
}
//=======================================================================
//function : Names
//purpose :
//=======================================================================
const TColStd_MapOfAsciiString& BRepMesh_DiscretFactory::Names()const
{
return myNames;
}
//=======================================================================
//function : SetDefaultName
//purpose :
//=======================================================================
void BRepMesh_DiscretFactory::SetDefaultName(const TCollection_AsciiString& theName)
{
myDefaultName=theName;
}
//=======================================================================
//function : DefaultName
//purpose :
//=======================================================================
const TCollection_AsciiString& BRepMesh_DiscretFactory::DefaultName()const
{
return myDefaultName;
}
//=======================================================================
//function : SetFunctionName
//purpose :
//=======================================================================
void BRepMesh_DiscretFactory::SetFunctionName(const TCollection_AsciiString& theName)
{
myFunctionName=theName;
}
//=======================================================================
//function : FunctionName
//purpose :
//=======================================================================
const TCollection_AsciiString& BRepMesh_DiscretFactory::FunctionName()const
{
return myFunctionName;
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
BRepMesh_PDiscretRoot&
BRepMesh_DiscretFactory::Discret(const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle)
{
myErrorStatus=BRepMesh_FE_NOERROR;
Clear();
// DEB f
//myDefaultName="TKXMesh";
// DEB t
if(myDefaultName==myFixedNames[0]) {
myPDiscret=new BRepMesh_IncrementalMesh;
myPDiscret->SetDeflection(theDeflection);
myPDiscret->SetAngle(theAngle);
myPDiscret->SetShape(theShape);
}
else {
Standard_Integer iErr;
TCollection_AsciiString aLibName;
OSD_Function aF;
//
myPDiscret=NULL;
//
MakeLibName(myDefaultName, aLibName);
//
OSD_SharedLibrary aSL(aLibName.ToCString());
if (!aSL.DlOpen(OSD_RTLD_LAZY)) {
myErrorStatus=BRepMesh_FE_LIBRARYNOTFOUND; // library is not found
return myPDiscret;
}
//
aF = aSL.DlSymb(myFunctionName.ToCString());
if(aF==NULL ) {
myErrorStatus=BRepMesh_FE_FUNCTIONNOTFOUND; // function is not found
return myPDiscret;
}
//
iErr=CreateDiscret(theShape,
theDeflection,
theAngle,
aF,
myPDiscret);
if (iErr) {
myErrorStatus=BRepMesh_FE_CANNOTCREATEALGO; // can not create the algo specified
}
else {
myNames.Add(myDefaultName);
}
}
//
return myPDiscret;
}
//=======================================================================
//function : CreateDiscret
//purpose :
//=======================================================================
Standard_Integer CreateDiscret(const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle,
OSD_Function& theF,
BRepMesh_PDiscretRoot& theAlgo)
{
Standard_Integer iErr;
Standard_Integer (*fp) (const TopoDS_Shape& ,
const Standard_Real ,
const Standard_Real ,
BRepMesh_PDiscretRoot& );
//
fp=(Standard_Integer (*)(const TopoDS_Shape& ,
const Standard_Real ,
const Standard_Real ,
BRepMesh_PDiscretRoot&)) theF;
//
iErr=(*fp)(theShape,
theDeflection,
theAngle,
theAlgo);
//
return iErr;
}
//=======================================================================
//function : MakeLibName
//purpose :
//=======================================================================
void MakeLibName(const TCollection_AsciiString& theDefaultName,
//! Generate system-dependent name for dynamic library
//! (add standard prefixes and postfixes)
static void MakeLibName (const TCollection_AsciiString& theDefaultName,
TCollection_AsciiString& theLibName)
{
theLibName = "";
@ -221,3 +34,209 @@ void MakeLibName(const TCollection_AsciiString& theDefaultName,
theLibName += ".so";
#endif
}
};
//=======================================================================
//function : BRepMesh_DiscretFactory
//purpose :
//=======================================================================
BRepMesh_DiscretFactory::BRepMesh_DiscretFactory()
: myPluginEntry (NULL),
myErrorStatus (BRepMesh_FE_NOERROR),
myDefaultName (THE_FAST_DISCRET_MESH),
myFunctionName ("DISCRETALGO")
{
// register built-in meshing algorithms
myNames.Add (THE_FAST_DISCRET_MESH);
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BRepMesh_DiscretFactory::~BRepMesh_DiscretFactory()
{
Clear();
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
void BRepMesh_DiscretFactory::Clear()
{
// what should we do here? Unload dynamic libraries and reset plugins list?
}
//=======================================================================
//function : Get
//purpose :
//=======================================================================
BRepMesh_DiscretFactory& BRepMesh_DiscretFactory::Get()
{
//! global factory instance
static BRepMesh_DiscretFactory THE_GLOBAL_FACTORY;
return THE_GLOBAL_FACTORY;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
BRepMesh_FactoryError BRepMesh_DiscretFactory::ErrorStatus() const
{
return myErrorStatus;
}
//=======================================================================
//function : Names
//purpose :
//=======================================================================
const TColStd_MapOfAsciiString& BRepMesh_DiscretFactory::Names() const
{
return myNames;
}
//=======================================================================
//function : SetDefaultName
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_DiscretFactory::SetDefaultName (const TCollection_AsciiString& theName)
{
return SetDefault (theName, myFunctionName);
}
//=======================================================================
//function : DefaultName
//purpose :
//=======================================================================
const TCollection_AsciiString& BRepMesh_DiscretFactory::DefaultName() const
{
return myDefaultName;
}
//=======================================================================
//function : SetFunctionName
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_DiscretFactory::SetFunctionName (const TCollection_AsciiString& theFuncName)
{
return SetDefault (myDefaultName, theFuncName);
}
//=======================================================================
//function : FunctionName
//purpose :
//=======================================================================
const TCollection_AsciiString& BRepMesh_DiscretFactory::FunctionName() const
{
return myFunctionName;
}
//=======================================================================
//function : SetDefault
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_DiscretFactory::SetDefault (const TCollection_AsciiString& theName,
const TCollection_AsciiString& theFuncName)
{
myErrorStatus = BRepMesh_FE_NOERROR;
if (theName == THE_FAST_DISCRET_MESH)
{
// built-in, nothing to do
myPluginEntry = NULL;
myDefaultName = theName;
myFunctionName = theFuncName;
return Standard_True;
}
else if (theName == myDefaultName && theFuncName == myFunctionName)
{
// already active
return myPluginEntry != NULL;
}
TCollection_AsciiString aMeshAlgoId = theName + "_" + theFuncName;
BRepMesh_PluginEntryType aFunc = NULL;
if (myFactoryMethods.IsBound (aMeshAlgoId))
{
// retrieve from cache
aFunc = (BRepMesh_PluginEntryType )myFactoryMethods (aMeshAlgoId);
}
else
{
TCollection_AsciiString aLibName;
MakeLibName (theName, aLibName);
OSD_SharedLibrary aSL (aLibName.ToCString());
if (!aSL.DlOpen (OSD_RTLD_LAZY))
{
// library is not found
myErrorStatus = BRepMesh_FE_LIBRARYNOTFOUND;
return Standard_False;
}
// retrieve the function from plugin
aFunc = (BRepMesh_PluginEntryType )aSL.DlSymb (theFuncName.ToCString());
myFactoryMethods.Bind (aMeshAlgoId, (OSD_Function )aFunc);
}
if (aFunc == NULL)
{
// function is not found - invalid plugin?
myErrorStatus = BRepMesh_FE_FUNCTIONNOTFOUND;
return Standard_False;
}
// try to create dummy tool
BRepMesh_PDiscretRoot anInstancePtr = NULL;
Standard_Integer anErr = aFunc (TopoDS_Shape(), 0.001, 0.1, anInstancePtr);
if (anErr != 0 || anInstancePtr == NULL)
{
// can not create the algo specified
myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
delete anInstancePtr;
return Standard_False;
}
delete anInstancePtr;
// if all checks done - switch to this tool
myPluginEntry = aFunc;
myDefaultName = theName;
myFunctionName = theFuncName;
myNames.Add (theName);
return Standard_True;
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
Handle(BRepMesh_DiscretRoot) BRepMesh_DiscretFactory
::Discret (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle)
{
Handle(BRepMesh_DiscretRoot) aDiscretRoot;
BRepMesh_PDiscretRoot anInstancePtr = NULL;
if (myPluginEntry != NULL)
{
// use plugin
Standard_Integer anErr = myPluginEntry (theShape, theDeflection, theAngle, anInstancePtr);
if (anErr != 0 || anInstancePtr == NULL)
{
// can not create the algo specified - should never happens here
myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
return aDiscretRoot;
}
}
else //if (myDefaultName == THE_FAST_DISCRET_MESH)
{
// use built-in
BRepMesh_IncrementalMesh::Discret (theShape, theDeflection, theAngle, anInstancePtr);
}
// cover with handle
aDiscretRoot = anInstancePtr;
// return the handle
return aDiscretRoot;
}

View File

@ -1,13 +1,16 @@
-- File: BRepMesh_DiscretRoot.cdl
-- Created: Thu Apr 10 09:57:55 2008
-- Author: Peter KURNEV
-- <pkv@irinox>
-- Author: Peter KURNEV <pkv@irinox>
--
---Copyright: Matra Datavision 2008
deferred class DiscretRoot from BRepMesh
inherits Transient from Standard
---Purpose:
-- This is a common interface for meshing algorithms
-- instantiated by Mesh Factory and implemented by plugins.
uses
Shape from TopoDS
@ -15,47 +18,62 @@ uses
--raises
is
Initialize
returns DiscretRoot from BRepMesh;
SetDeflection(me: out;
SetDeflection ( me : mutable;
theDeflection : Real from Standard);
---Purpose:
-- Setup linear deflection.
---C++: alias "Standard_EXPORT virtual ~BRepMesh_DiscretRoot();"
Deflection (me)
returns Real from Standard;
---Purpose:
-- Returns linear deflection.
SetAngle(me: out;
SetAngle ( me : mutable;
theAngle : Real from Standard);
---Purpose:
-- Setup angular deflection.
Angle (me)
returns Real from Standard;
---Purpose:
-- Returns angular deflection.
SetShape(me: out;
SetShape ( me : mutable;
theShape : Shape from TopoDS);
---Purpose:
-- Set the shape to triangulate.
Shape (me)
returns Shape from TopoDS;
---C++: return const &
Perform(me: out)
Perform (me : mutable)
is deferred;
---Purpose:
-- Compute triangulation for set shape.
IsDone (me)
returns Boolean from Standard;
---Purpose:
-- Returns true if triangualtion was performed and has success.
--
-- Protected methods
--
SetDone(me:out)
SetDone (me : mutable)
is protected;
SetNotDone(me:out)
SetNotDone (me : mutable)
is protected;
Init(me:out)
Init (me : mutable)
is virtual protected;
fields
myDeflection : Real from Standard is protected;
myAngle : Real from Standard is protected;

View File

@ -1,8 +1,6 @@
// File: BRepMesh_DiscretRoot.cxx
// Created: Thu Apr 10 10:08:44 2008
// Author: Peter KURNEV
// <pkv@irinox>
// Author: Peter KURNEV <pkv@irinox>
#include <BRepMesh_DiscretRoot.ixx>
@ -11,11 +9,13 @@
//purpose :
//=======================================================================
BRepMesh_DiscretRoot::BRepMesh_DiscretRoot()
: myDeflection (0.001),
myAngle (0.1),
myIsDone (Standard_False)
{
myIsDone=Standard_False;
myDeflection=0.001;
myAngle=0.1;
//
}
//=======================================================================
//function : ~
//purpose :
@ -23,6 +23,7 @@ BRepMesh_DiscretRoot::BRepMesh_DiscretRoot()
BRepMesh_DiscretRoot::~BRepMesh_DiscretRoot()
{
}
//=======================================================================
//function : SetDeflection
//purpose :
@ -31,6 +32,7 @@ void BRepMesh_DiscretRoot::SetDeflection(const Standard_Real theDeflection)
{
myDeflection = theDeflection;
}
//=======================================================================
//function : Deflection
//purpose :
@ -39,6 +41,7 @@ Standard_Real BRepMesh_DiscretRoot::Deflection()const
{
return myDeflection;
}
//=======================================================================
//function : SetAngle
//purpose :
@ -47,6 +50,7 @@ void BRepMesh_DiscretRoot::SetAngle(const Standard_Real theAngle)
{
myAngle = theAngle;
}
//=======================================================================
//function : Angle
//purpose :
@ -55,6 +59,7 @@ Standard_Real BRepMesh_DiscretRoot::Angle()const
{
return myAngle;
}
//=======================================================================
//function : SetShape
//purpose :
@ -63,6 +68,7 @@ void BRepMesh_DiscretRoot::SetShape(const TopoDS_Shape& theShape)
{
myShape = theShape;
}
//=======================================================================
//function : Shape
//purpose :
@ -71,6 +77,7 @@ const TopoDS_Shape& BRepMesh_DiscretRoot::Shape()const
{
return myShape;
}
//=======================================================================
//function : IsDone
//purpose :
@ -79,6 +86,7 @@ Standard_Boolean BRepMesh_DiscretRoot::IsDone()const
{
return myIsDone;
}
//=======================================================================
//function : SetDone
//purpose :
@ -87,6 +95,7 @@ void BRepMesh_DiscretRoot::SetDone()
{
myIsDone = Standard_True;
}
//=======================================================================
//function : SetNotDone
//purpose :
@ -95,11 +104,12 @@ void BRepMesh_DiscretRoot::SetNotDone()
{
myIsDone = Standard_False;
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BRepMesh_DiscretRoot::Init()
{
//
}

View File

@ -165,6 +165,16 @@ is
defedge: Real from Standard)
is static private;
SetParallel ( me : mutable;
theInParallel : Boolean from Standard);
---Purpose:
-- Request algorithm to launch in multiple threads
-- to improve performance (should be supported by plugin).
IsParallel (me)
returns Boolean from Standard;
---Purpose:
-- Returns the multi-threading usage flag.
-- Output :
@ -293,6 +303,7 @@ fields
myDeflection : Real from Standard;
myDtotale : Real from Standard;
myWithShare : Boolean from Standard;
myInParallel : Boolean from Standard;
myVertices : DataMapOfVertexInteger from BRepMesh;
myEdges : DataMapOfShapePairOfPolygon from BRepMesh;
myInternaledges: DataMapOfShapePairOfPolygon from BRepMesh;

View File

@ -77,13 +77,8 @@
#include <vector>
// NOTE: replaced by more correct check
// #if defined(WNT) || defined(LIN)
// #define HAVE_TBB 1
// #endif
// paralleling with Intel TBB
#ifdef HAVE_TBB
// paralleling using Intel TBB
#include <tbb/parallel_for_each.h>
#endif
@ -121,8 +116,13 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
const Standard_Boolean theInshape,
const Standard_Boolean theRelative,
const Standard_Boolean theShapetrigu) :
myAngle(theAngl), myDeflection(theDefle),myWithShare(theWithShare),
myNbLocat(0), myRelative(theRelative), myShapetrigu(theShapetrigu),
myAngle (theAngl),
myDeflection (theDefle),
myWithShare (theWithShare),
myInParallel (Standard_False),
myNbLocat (0),
myRelative (theRelative),
myShapetrigu (theShapetrigu),
myInshape (theInshape)
{
myAllocator = new NCollection_IncAllocator(64000);
@ -143,8 +143,13 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(const Standard_Real theDefle,
const Standard_Boolean theInshape,
const Standard_Boolean theRelative,
const Standard_Boolean theShapetrigu):
myAngle(theAngl), myDeflection(theDefle),myWithShare(theWithShare),
myNbLocat(0), myRelative(theRelative), myShapetrigu(theShapetrigu),
myAngle (theAngl),
myDeflection (theDefle),
myWithShare (theWithShare),
myInParallel (Standard_False),
myNbLocat (0),
myRelative (theRelative),
myShapetrigu (theShapetrigu),
myInshape (theInshape)
{
myAllocator = new NCollection_IncAllocator(64000);
@ -213,14 +218,22 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
aFaces.push_back(aF);
}
// mesh faces in parallel threads using TBB
if (myInParallel)
{
#ifdef HAVE_TBB
if (Standard::IsReentrant())
// mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
else
#endif
#else
// alternative parallelization not yet available
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
Process (*it);
#endif
}
else
{
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
Process (*it);
}
}

View File

@ -1,18 +1,17 @@
-- File: BRepMesh_IncrementalMesh.cdl
-- Created: Tue Jun 20 10:19:28 1995
-- Author: Stagiaire Alain JOURDAIN
-- <ajo@phobox>
-- Author: Stagiaire Alain JOURDAIN <ajo@phobox>
--
---Copyright: Matra Datavision 1995
class IncrementalMesh from BRepMesh
inherits DiscretRoot from BRepMesh
---Purpose: Builds the mesh of a shape with respect of their
-- correctly triangulated parts
--
uses
Box from Bnd,
Shape from TopoDS,
@ -22,7 +21,8 @@ uses
IndexedDataMapOfShapeListOfShape from TopTools,
DataMapOfShapeReal from TopTools,
FastDiscret from BRepMesh,
Status from BRepMesh
Status from BRepMesh,
PDiscretRoot from BRepMesh
is
Create
@ -33,54 +33,89 @@ is
D : Real from Standard;
Relatif : Boolean from Standard = Standard_False;
Ang : Real from Standard = 0.5)
---Purpose: if the boolean <Relatif> is True, the
returns IncrementalMesh from BRepMesh;
---Purpose: If the boolean <Relatif> is True, the
-- deflection used for the polygonalisation of
-- each edge will be <D> * Size of Edge.
-- the deflection used for the faces will be the maximum
-- deflection of their edges.
returns IncrementalMesh from BRepMesh;
SetRelative(me:out;
SetRelative ( me : mutable;
theFlag : Boolean from Standard);
Relative (me)
returns Boolean from Standard;
Init(me:out)
Init (me : mutable)
is redefined protected;
Perform(me:out)
Perform (me : mutable)
is redefined;
Update(me:out;
Update (me : mutable;
S : Shape from TopoDS)
is static;
---Purpose: Builds the incremental mesh of the shape
IsModified (me)
returns Boolean from Standard
is static;
IsModified(me) returns Boolean from Standard
is static;
Update(me : in out;
Update (me : mutable;
E : Edge from TopoDS)
is static private;
---Purpose: Locate a correct discretisation if it exists
-- Set no one otherwise
is static private;
Update(me : in out;
Update (me : mutable;
F : Face from TopoDS)
---Purpose: if the face is not correctly triangulated, or
is static private;
---Purpose: If the face is not correctly triangulated, or
-- if one of its edges is to be discretisated
-- correctly, the triangulation of this face is
-- built.
is static private;
GetStatusFlags (me)
returns Integer from Standard
is static;
SetParallel ( me : mutable;
theInParallel : Boolean from Standard);
---Purpose:
-- Request algorithm to launch in multiple threads to improve performance.
IsParallel (me)
returns Boolean from Standard;
---Purpose:
-- Returns the multi-threading usage flag.
--
-- Plugin interface
--
Discret (myclass;
theShape : Shape from TopoDS;
theDeflection : Real from Standard;
theAngle : Real from Standard;
theAlgo : out PDiscretRoot from BRepMesh)
returns Integer from Standard;
---Purpose:
-- Plugin interface for the Mesh Factories.
IsParallelDefault (myclass)
returns Boolean from Standard;
---Purpose:
-- Returns multi-threading usage flag set by default in
-- Discret() static method (thus applied only to Mesh Factories).
SetParallelDefault (myclass;
theInParallel : Boolean from Standard);
---Purpose:
-- Setup multi-threading usage flag set by default in
-- Discret() static method (thus applied only to Mesh Factories).
fields
myRelative : Boolean from Standard is protected;
myInParallel : Boolean from Standard is protected;
myMap : MapOfShape from TopTools is protected;
myMesh : FastDiscret from BRepMesh is protected;
myModified : Boolean from Standard is protected;
@ -91,7 +126,3 @@ fields
myStatus : Integer from Standard is protected;
end IncrementalMesh;

View File

@ -10,6 +10,7 @@
#include <BRepMesh_Edge.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_FastDiscretFace.hxx>
#include <BRepMesh_PluginMacro.hxx>
#include <Bnd_Box.hxx>
#include <BRep_Builder.hxx>
@ -36,22 +37,25 @@
#include <vector>
// NOTE: to be replaced by more correct check
// #if defined(WNT) || defined(LIN)
// #define HAVE_TBB 1
// #endif
// paralleling with Intel TBB
#ifdef HAVE_TBB
// paralleling using Intel TBB
#include <tbb/parallel_for_each.h>
#endif
namespace
{
//! Default flag to control parallelization for BRepMesh_IncrementalMesh
//! tool returned for Mesh Factory
static Standard_Boolean IS_IN_PARALLEL = Standard_False;
};
//=======================================================================
//function : BRepMesh_IncrementalMesh
//purpose :
//=======================================================================
BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
: myRelative (Standard_False),
myInParallel (Standard_False),
myModified (Standard_False),
myStatus (0)
{
@ -63,21 +67,20 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
//function : BRepMesh_IncrementalMesh
//purpose :
//=======================================================================
BRepMesh_IncrementalMesh::
BRepMesh_IncrementalMesh(const TopoDS_Shape& S,
const Standard_Real D,
const Standard_Boolean Rel,
const Standard_Real Ang) :
myRelative(Rel),
BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Boolean theRelative,
const Standard_Real theAngle)
: myRelative (theRelative),
myInParallel (Standard_False),
myModified (Standard_False),
myStatus (0)
{
mymapedge.Clear();
myancestors.Clear();
myDeflection = D;
myAngle = Ang;
myShape = S;
myDeflection = theDeflection;
myAngle = theAngle;
myShape = theShape;
//
Perform();
@ -91,6 +94,24 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
{
}
//=======================================================================
//function : SetParallel
//purpose :
//=======================================================================
void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
{
myInParallel = theInParallel;
}
//=======================================================================
//function : IsParallel
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
{
return myInParallel;
}
//=======================================================================
//function : Init
//purpose :
@ -173,7 +194,6 @@ Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
//purpose : Builds the incremental mesh of the shape
//=======================================================================
void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
{
myModified = Standard_False;
TopExp_Explorer ex;
@ -209,14 +229,22 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
aFaces.push_back (F);
}
// mesh faces in parallel threads using TBB
if (myInParallel)
{
#ifdef HAVE_TBB
if (Standard::IsReentrant())
// mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
else
#endif
#else
// alternative parallelization not yet available
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
myMesh->Process (*it);
#endif
}
else
{
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
myMesh->Process (*it);
}
// maillage des edges non contenues dans les faces :
Standard_Real f, l, defedge;
@ -271,6 +299,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
ex.Next();
}
}
//=======================================================================
//function : Update(edge)
//purpose : Locate a correct discretisation if it exists
@ -441,3 +470,47 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
}
}
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle,
BRepMesh_PDiscretRoot& theAlgo)
{
BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
anAlgo->SetDeflection (theDeflection);
anAlgo->SetAngle (theAngle);
anAlgo->SetShape (theShape);
anAlgo->SetParallel (IS_IN_PARALLEL);
theAlgo = anAlgo;
return 0; // no error
}
//=======================================================================
//function : IsParallelDefault
//purpose :
//=======================================================================
Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
{
#ifdef HAVE_TBB
return IS_IN_PARALLEL;
#else
// no alternative parallelization yet - flag has no meaning
return Standard_False;
#endif
}
//=======================================================================
//function : Discret
//purpose :
//=======================================================================
void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
{
IS_IN_PARALLEL = theInParallel;
}
//! Export Mesh Plugin entry function
DISCRETPLUGIN(BRepMesh_IncrementalMesh)

View File

@ -0,0 +1,17 @@
#ifndef _BRepMesh_PluginEntryType_HeaderFile
#define _BRepMesh_PluginEntryType_HeaderFile
#ifndef _Standard_Real_HeaderFile
#include <Standard_Real.hxx>
#endif
class TopoDS_Shape;
class BRepMesh_DiscretRoot;
//! Type definition for plugin exported function
typedef Standard_Integer (*BRepMesh_PluginEntryType) (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Standard_Real theAngle,
BRepMesh_DiscretRoot*& theMeshAlgoInstance);
#endif //_BRepMesh_PluginEntryType_HeaderFile

View File

@ -1,3 +1,4 @@
BRepMesh_PluginEntryType.hxx
BRepMesh_PluginMacro.hxx
BRepMesh_ClassifierPtr.hxx
BRepMesh_CellFilter.hxx

View File

@ -11,6 +11,7 @@
#include <TColStd_MapIteratorOfMapOfAsciiString.hxx>
#include <BRepMesh_FactoryError.hxx>
#include <BRepMesh_DiscretRoot.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <Bnd_Box.hxx>
#include <BRepMesh_PDiscretRoot.hxx>
#include <DBRep.hxx>
@ -35,6 +36,7 @@ static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer
static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** );
static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** );
static Standard_Integer mpparallel (Draw_Interpretor& , Standard_Integer , const char** );
static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** );
static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** );
@ -59,6 +61,8 @@ void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname , g);
theCommands.Add("mperror" , "use mperror" , __FILE__, mperror , g);
theCommands.Add("mpincmesh" , "use mpincmesh" , __FILE__, mpincmesh , g);
theCommands.Add("mpparallel" , "mpparallel [toTurnOn] : show / set multi-threading flag for incremental mesh",
__FILE__, mpparallel, g);
theCommands.Add("triarea","shape [eps] (computes triangles and surface area)",__FILE__, triarea, g);
theCommands.Add("tricheck", "shape (checks triangulation of shape)", __FILE__, tricheck, g);
@ -109,8 +113,10 @@ static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer n
//
aName=a[1];
//
BRepMesh_DiscretFactory::Get().SetDefaultName(aName);
if (BRepMesh_DiscretFactory::Get().SetDefaultName (aName))
printf(" *ready\n");
else
printf(" *fault\n");
//
return 0;
}
@ -145,8 +151,10 @@ static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer
//
aName=a[1];
//
BRepMesh_DiscretFactory::Get().SetFunctionName(aName);
if (BRepMesh_DiscretFactory::Get().SetFunctionName (aName))
printf(" *ready\n");
else
printf(" *fault\n");
//
return 0;
}
@ -191,11 +199,8 @@ static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer n, const c
//=======================================================================
static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const char** a)
{
Standard_Boolean bIsDone;
Standard_Real aDeflection, aAngle;
TopoDS_Shape aS;
BRepMesh_FactoryError aErr;
BRepMesh_PDiscretRoot pAlgo;
//
if (n<3) {
printf(" use mpincmesh s deflection [angle]\n");
@ -214,23 +219,25 @@ static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const
aAngle=atof(a[3]);
}
//
pAlgo=BRepMesh_DiscretFactory::Get().Discret(aS,
Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (aS,
aDeflection,
aAngle);
//
aErr=BRepMesh_DiscretFactory::Get().ErrorStatus();
if (aErr!=BRepMesh_FE_NOERROR) {
BRepMesh_FactoryError aErr = BRepMesh_DiscretFactory::Get().ErrorStatus();
if (aErr != BRepMesh_FE_NOERROR)
{
printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr);
}
//
if (!pAlgo) {
if (aMeshAlgo.IsNull())
{
printf(" *Can not create the algo\n");
return 0;
}
//
pAlgo->Perform();
bIsDone=pAlgo->IsDone();
if (!bIsDone) {
aMeshAlgo->Perform();
if (!aMeshAlgo->IsDone())
{
printf(" *Not done\n");
}
//
@ -404,3 +411,19 @@ static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
<< " Free_nodes " << nbFreeNodes << "\n";
return 0;
}
//=======================================================================
//function : mpparallel
//purpose :
//=======================================================================
static int mpparallel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
if (argc == 2)
{
Standard_Boolean isParallelOn = atoi (argv[1]) == 1;
BRepMesh_IncrementalMesh::SetParallelDefault (isParallelOn);
}
std::cout << "Incremental Mesh, multi-threading "
<< (BRepMesh_IncrementalMesh::IsParallelDefault() ? "ON\n" : "OFF\n");
return 0;
}

View File

@ -12,7 +12,7 @@ is
exception Failure inherits Failure from Standard;
private class MapOfFunctions instantiates DataMap from TCollection(AsciiString from TCollection ,Function from OSD, AsciiString from TCollection);
class MapOfFunctions instantiates DataMap from TCollection(AsciiString from TCollection ,Function from OSD, AsciiString from TCollection);
Load(aGUID: GUID from Standard) returns Transient from Standard

View File

@ -316,19 +316,20 @@ void Prs3d_ShadedShape::Add(const Handle (Prs3d_Presentation)& aPresentation,
}
}
Standard_Real aDeflection = GetDeflection(aShape, aDrawer);
//using of plugin
// Check if it is possible to avoid unnecessary recomputation
// of shape triangulation
if (!BRepTools::Triangulation (aShape, aDeflection))
{
BRepTools::Clean (aShape);
BRepMesh_PDiscretRoot pAlgo;
pAlgo=BRepMesh_DiscretFactory::Get().Discret(aShape,
// retrieve meshing tool from Factory
Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (aShape,
aDeflection,
aDrawer->HLRAngle());
if (pAlgo)
pAlgo->Perform();
if (!aMeshAlgo.IsNull())
aMeshAlgo->Perform();
}
ShadeFromShape(aShape, aDeflection, Standard_True, aPresentation, aDrawer);
}