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