0022600: TBB has to be disabled in BRepMesh due to data races
[occt.git] / src / BRepMesh / BRepMesh_DiscretFactory.cxx
1 // File:    BRepMesh_DiscretFactory.cxx
2 // Created: Thu Apr 10 13:32:00 2008
3 // Author:  Peter KURNEV <pkv@irinox>
4
5 #include <BRepMesh_DiscretFactory.ixx>
6
7 #include <OSD_SharedLibrary.hxx>
8 #include <OSD_Function.hxx>
9 #include <BRepMesh_IncrementalMesh.hxx>
10 #include <BRepMesh_PDiscretRoot.hxx>
11
12 namespace
13 {
14   //! Embedded triangulation tool(s)
15   static TCollection_AsciiString THE_FAST_DISCRET_MESH ("FastDiscret");
16
17   //! Generate system-dependent name for dynamic library
18   //! (add standard prefixes and postfixes)
19   static void MakeLibName (const TCollection_AsciiString& theDefaultName,
20                                  TCollection_AsciiString& theLibName)
21   {
22     theLibName = "";
23   #ifndef WNT
24     theLibName += "lib";
25   #endif
26     theLibName += theDefaultName;
27   #ifdef WNT
28     theLibName += ".dll";
29   #elif __APPLE__
30     theLibName += ".dylib";
31   #elif defined (HPUX) || defined(_hpux)
32     theLibName += ".sl";
33   #else
34     theLibName += ".so";
35   #endif
36   }
37 };
38
39 //=======================================================================
40 //function : BRepMesh_DiscretFactory
41 //purpose  :
42 //=======================================================================
43 BRepMesh_DiscretFactory::BRepMesh_DiscretFactory()
44 : myPluginEntry (NULL),
45   myErrorStatus (BRepMesh_FE_NOERROR),
46   myDefaultName (THE_FAST_DISCRET_MESH),
47   myFunctionName ("DISCRETALGO")
48 {
49   // register built-in meshing algorithms
50   myNames.Add (THE_FAST_DISCRET_MESH);
51 }
52
53 //=======================================================================
54 //function : ~
55 //purpose  :
56 //=======================================================================
57 BRepMesh_DiscretFactory::~BRepMesh_DiscretFactory()
58 {
59   Clear();
60 }
61
62 //=======================================================================
63 //function : ~
64 //purpose  :
65 //=======================================================================
66 void BRepMesh_DiscretFactory::Clear()
67 {
68   // what should we do here? Unload dynamic libraries and reset plugins list?
69 }
70
71 //=======================================================================
72 //function : Get
73 //purpose  :
74 //=======================================================================
75 BRepMesh_DiscretFactory& BRepMesh_DiscretFactory::Get()
76 {
77   //! global factory instance
78   static BRepMesh_DiscretFactory THE_GLOBAL_FACTORY;
79   return THE_GLOBAL_FACTORY;
80 }
81
82 //=======================================================================
83 //function : ErrorStatus
84 //purpose  :
85 //=======================================================================
86 BRepMesh_FactoryError BRepMesh_DiscretFactory::ErrorStatus() const
87 {
88   return myErrorStatus;
89 }
90
91 //=======================================================================
92 //function : Names
93 //purpose  :
94 //=======================================================================
95 const TColStd_MapOfAsciiString& BRepMesh_DiscretFactory::Names() const
96 {
97   return myNames;
98 }
99
100 //=======================================================================
101 //function : SetDefaultName
102 //purpose  :
103 //=======================================================================
104 Standard_Boolean BRepMesh_DiscretFactory::SetDefaultName (const TCollection_AsciiString& theName)
105 {
106   return SetDefault (theName, myFunctionName);
107 }
108
109 //=======================================================================
110 //function : DefaultName
111 //purpose  :
112 //=======================================================================
113 const TCollection_AsciiString& BRepMesh_DiscretFactory::DefaultName() const
114 {
115   return myDefaultName;
116 }
117
118 //=======================================================================
119 //function : SetFunctionName
120 //purpose  :
121 //=======================================================================
122 Standard_Boolean BRepMesh_DiscretFactory::SetFunctionName (const TCollection_AsciiString& theFuncName)
123 {
124   return SetDefault (myDefaultName, theFuncName);
125 }
126
127 //=======================================================================
128 //function : FunctionName
129 //purpose  :
130 //=======================================================================
131 const TCollection_AsciiString& BRepMesh_DiscretFactory::FunctionName() const
132 {
133   return myFunctionName;
134 }
135
136 //=======================================================================
137 //function : SetDefault
138 //purpose  :
139 //=======================================================================
140 Standard_Boolean BRepMesh_DiscretFactory::SetDefault (const TCollection_AsciiString& theName,
141                                                       const TCollection_AsciiString& theFuncName)
142 {
143   myErrorStatus = BRepMesh_FE_NOERROR;
144   if (theName == THE_FAST_DISCRET_MESH)
145   {
146     // built-in, nothing to do
147     myPluginEntry  = NULL;
148     myDefaultName  = theName;
149     myFunctionName = theFuncName;
150     return Standard_True;
151   }
152   else if (theName == myDefaultName && theFuncName == myFunctionName)
153   {
154     // already active
155     return myPluginEntry != NULL;
156   }
157
158   TCollection_AsciiString aMeshAlgoId = theName + "_" + theFuncName;
159   BRepMesh_PluginEntryType aFunc = NULL;
160   if (myFactoryMethods.IsBound (aMeshAlgoId))
161   {
162     // retrieve from cache
163     aFunc = (BRepMesh_PluginEntryType )myFactoryMethods (aMeshAlgoId);
164   }
165   else
166   {
167     TCollection_AsciiString aLibName;
168     MakeLibName (theName, aLibName);
169     OSD_SharedLibrary aSL (aLibName.ToCString());
170     if (!aSL.DlOpen (OSD_RTLD_LAZY))
171     {
172       // library is not found
173       myErrorStatus = BRepMesh_FE_LIBRARYNOTFOUND;
174       return Standard_False;
175     }
176
177     // retrieve the function from plugin
178     aFunc = (BRepMesh_PluginEntryType )aSL.DlSymb (theFuncName.ToCString());
179     myFactoryMethods.Bind (aMeshAlgoId, (OSD_Function )aFunc);
180   }
181
182   if (aFunc == NULL)
183   {
184     // function is not found - invalid plugin?
185     myErrorStatus = BRepMesh_FE_FUNCTIONNOTFOUND;
186     return Standard_False;
187   }
188
189   // try to create dummy tool
190   BRepMesh_PDiscretRoot anInstancePtr = NULL;
191   Standard_Integer anErr = aFunc (TopoDS_Shape(), 0.001, 0.1, anInstancePtr);
192   if (anErr != 0 || anInstancePtr == NULL)
193   {
194     // can not create the algo specified  
195     myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
196     delete anInstancePtr;
197     return Standard_False;
198   }
199   delete anInstancePtr;
200
201   // if all checks done - switch to this tool
202   myPluginEntry  = aFunc;
203   myDefaultName  = theName;
204   myFunctionName = theFuncName;
205   myNames.Add (theName);
206   return Standard_True;
207 }
208
209 //=======================================================================
210 //function : Discret
211 //purpose  :
212 //=======================================================================
213 Handle(BRepMesh_DiscretRoot) BRepMesh_DiscretFactory
214   ::Discret (const TopoDS_Shape& theShape,
215              const Standard_Real theDeflection,
216              const Standard_Real theAngle)
217 {
218   Handle(BRepMesh_DiscretRoot) aDiscretRoot;
219   BRepMesh_PDiscretRoot anInstancePtr = NULL;
220   if (myPluginEntry != NULL)
221   {
222     // use plugin
223     Standard_Integer anErr = myPluginEntry (theShape, theDeflection, theAngle, anInstancePtr);
224     if (anErr != 0 || anInstancePtr == NULL)
225     {
226       // can not create the algo specified - should never happens here
227       myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
228       return aDiscretRoot;
229     }
230   }
231   else //if (myDefaultName == THE_FAST_DISCRET_MESH)
232   {
233     // use built-in
234     BRepMesh_IncrementalMesh::Discret (theShape, theDeflection, theAngle, anInstancePtr);
235   }
236
237   // cover with handle
238   aDiscretRoot = anInstancePtr;
239
240   // return the handle
241   return aDiscretRoot;
242 }