0026106: BRepMesh - revision of data model
[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.hxx>
17
18 #include <OSD_SharedLibrary.hxx>
19 #include <OSD_Function.hxx>
20 #include <BRepMesh_IncrementalMesh.hxx>
21 #include <BRepMesh_DiscretRoot.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 _WIN32
35     theLibName += "lib";
36   #endif
37     theLibName += theDefaultName;
38   #ifdef _WIN32
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 : clear
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 : SetDefault
95 //purpose  :
96 //=======================================================================
97 Standard_Boolean BRepMesh_DiscretFactory::SetDefault(
98   const TCollection_AsciiString& theName,
99   const TCollection_AsciiString& theFuncName)
100 {
101   myErrorStatus = BRepMesh_FE_NOERROR;
102   if (theName == THE_FAST_DISCRET_MESH)
103   {
104     // built-in, nothing to do
105     myPluginEntry  = NULL;
106     myDefaultName  = theName;
107     myFunctionName = theFuncName;
108     return Standard_True;
109   }
110   else if (theName == myDefaultName && theFuncName == myFunctionName)
111   {
112     // already active
113     return myPluginEntry != NULL;
114   }
115
116   TCollection_AsciiString aMeshAlgoId = theName + "_" + theFuncName;
117   BRepMesh_PluginEntryType aFunc = NULL;
118   if (myFactoryMethods.IsBound (aMeshAlgoId))
119   {
120     // retrieve from cache
121     aFunc = (BRepMesh_PluginEntryType )myFactoryMethods (aMeshAlgoId);
122   }
123   else
124   {
125     TCollection_AsciiString aLibName;
126     MakeLibName (theName, aLibName);
127     OSD_SharedLibrary aSL (aLibName.ToCString());
128     if (!aSL.DlOpen (OSD_RTLD_LAZY))
129     {
130       // library is not found
131       myErrorStatus = BRepMesh_FE_LIBRARYNOTFOUND;
132       return Standard_False;
133     }
134
135     // retrieve the function from plugin
136     aFunc = (BRepMesh_PluginEntryType )aSL.DlSymb (theFuncName.ToCString());
137     myFactoryMethods.Bind (aMeshAlgoId, (OSD_Function )aFunc);
138   }
139
140   if (aFunc == NULL)
141   {
142     // function is not found - invalid plugin?
143     myErrorStatus = BRepMesh_FE_FUNCTIONNOTFOUND;
144     return Standard_False;
145   }
146
147   // try to create dummy tool
148   BRepMesh_DiscretRoot* anInstancePtr = NULL;
149   Standard_Integer anErr = aFunc (TopoDS_Shape(), 0.001, 0.1, anInstancePtr);
150   if (anErr != 0 || anInstancePtr == NULL)
151   {
152     // can not create the algo specified  
153     myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
154     delete anInstancePtr;
155     return Standard_False;
156   }
157   delete anInstancePtr;
158
159   // if all checks done - switch to this tool
160   myPluginEntry  = aFunc;
161   myDefaultName  = theName;
162   myFunctionName = theFuncName;
163   myNames.Add (theName);
164   return Standard_True;
165 }
166
167 //=======================================================================
168 //function : Discret
169 //purpose  :
170 //=======================================================================
171 Handle(BRepMesh_DiscretRoot) BRepMesh_DiscretFactory::Discret(
172   const TopoDS_Shape& theShape,
173   const Standard_Real theDeflection,
174   const Standard_Real theAngle)
175 {
176   Handle(BRepMesh_DiscretRoot) aDiscretRoot;
177   BRepMesh_DiscretRoot* anInstancePtr = NULL;
178   if (myPluginEntry != NULL)
179   {
180     // use plugin
181     Standard_Integer anErr = myPluginEntry (theShape, 
182       theDeflection, theAngle, anInstancePtr);
183       
184     if (anErr != 0 || anInstancePtr == NULL)
185     {
186       // can not create the algo specified - should never happens here
187       myErrorStatus = BRepMesh_FE_CANNOTCREATEALGO;
188       return aDiscretRoot;
189     }
190   }
191   else //if (myDefaultName == THE_FAST_DISCRET_MESH)
192   {
193     // use built-in
194     BRepMesh_IncrementalMesh::Discret (theShape, 
195       theDeflection, theAngle, anInstancePtr);
196   }
197
198   // cover with handle
199   aDiscretRoot = anInstancePtr;
200
201   // return the handle
202   return aDiscretRoot;
203 }