Skip to content

Commit c47d9c0

Browse files
authored
Mesh - Replace plugin system with registry-based factory pattern (#1033)
Replace the legacy DISCRETPLUGIN/DISCRETALGO symbol-based plugin system with a clean registry-based factory pattern following the design of Graphic3d_GraphicDriverFactory. Problem: TKMesh and TKXMesh both exported the same DISCRETALGO symbol, causing symbol collisions when both libraries were loaded. The old plugin system required dlopen/dlsym which was error-prone and limited. Solution: Each meshing algorithm now registers itself as a factory with a unique name. Multiple algorithms can coexist and be selected at runtime. New classes: - BRepMesh_DiscretAlgoFactory: Abstract factory base with static registry - BRepMesh_IncrementalMeshFactory: Factory for "FastDiscret" algorithm - XBRepMesh_Factory: Factory for "XBRepMesh" algorithm Removed (breaking changes): - BRepMesh_PluginMacro.hxx: DISCRETPLUGIN macro - BRepMesh_PluginEntryType.hxx: Legacy function pointer type - BRepMesh_FactoryError.hxx: Legacy error enum - XBRepMesh class: Replaced by XBRepMesh_Factory - BRepMesh_DiscretFactory::Names(), SetFunctionName(), FunctionName(), ErrorStatus() - Draw commands: mpsetfunctionname, mpgetfunctionname, mperror Simplified BRepMesh_DiscretFactory API to delegate to the new registry. Updated MeshTest_PluginCommands to use BRepMesh_DiscretAlgoFactory.
1 parent 553466c commit c47d9c0

19 files changed

Lines changed: 634 additions & 480 deletions

src/Draw/TKTopTest/MeshTest/MeshTest_PluginCommands.cxx

Lines changed: 48 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
#include <BRep_Tool.hxx>
1717
#include <BRepGProp.hxx>
18+
#include <BRepMesh_DiscretAlgoFactory.hxx>
1819
#include <BRepMesh_DiscretFactory.hxx>
1920
#include <BRepMesh_DiscretRoot.hxx>
20-
#include <BRepMesh_FactoryError.hxx>
2121
#include <BRepMesh_IncrementalMesh.hxx>
2222
#include <DBRep.hxx>
2323
#include <Draw.hxx>
@@ -48,9 +48,6 @@
4848
static int mpnames(Draw_Interpretor&, int, const char**);
4949
static int mpsetdefaultname(Draw_Interpretor&, int, const char**);
5050
static int mpgetdefaultname(Draw_Interpretor&, int, const char**);
51-
static int mpsetfunctionname(Draw_Interpretor&, int, const char**);
52-
static int mpgetfunctionname(Draw_Interpretor&, int, const char**);
53-
static int mperror(Draw_Interpretor&, int, const char**);
5451
static int mpincmesh(Draw_Interpretor&, int, const char**);
5552
static int mpparallel(Draw_Interpretor&, int, const char**);
5653
static int triarea(Draw_Interpretor&, int, const char**);
@@ -69,13 +66,18 @@ void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
6966
//
7067
const char* g = "Mesh Commands";
7168
// Commands
72-
theCommands.Add("mpnames", "use mpnames", __FILE__, mpnames, g);
73-
theCommands.Add("mpsetdefaultname", "use mpsetdefaultname", __FILE__, mpsetdefaultname, g);
74-
theCommands.Add("mpgetdefaultname", "use mpgetdefaultname", __FILE__, mpgetdefaultname, g);
75-
theCommands.Add("mpsetfunctionname", "use mpsetfunctionname", __FILE__, mpsetfunctionname, g);
76-
theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname, g);
77-
theCommands.Add("mperror", "use mperror", __FILE__, mperror, g);
78-
theCommands.Add("mpincmesh", "use mpincmesh", __FILE__, mpincmesh, g);
69+
theCommands.Add("mpnames", "mpnames : list available meshing algorithms", __FILE__, mpnames, g);
70+
theCommands.Add("mpsetdefaultname",
71+
"mpsetdefaultname name : set default meshing algorithm",
72+
__FILE__,
73+
mpsetdefaultname,
74+
g);
75+
theCommands.Add("mpgetdefaultname",
76+
"mpgetdefaultname : get default meshing algorithm name",
77+
__FILE__,
78+
mpgetdefaultname,
79+
g);
80+
theCommands.Add("mpincmesh", "mpincmesh shape deflection [angle]", __FILE__, mpincmesh, g);
7981
theCommands.Add("mpparallel",
8082
"mpparallel [toTurnOn] : show / set multi-threading flag for incremental mesh",
8183
__FILE__,
@@ -98,176 +100,110 @@ void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
98100

99101
static int mpnames(Draw_Interpretor&, int n, const char**)
100102
{
101-
int aNb;
102-
NCollection_Map<TCollection_AsciiString>::Iterator aIt;
103-
//
104103
if (n != 1)
105104
{
106105
printf(" use mpnames\n");
107106
return 0;
108107
}
109-
//
110-
const NCollection_Map<TCollection_AsciiString>& aMN = BRepMesh_DiscretFactory::Get().Names();
111-
aNb = aMN.Extent();
112-
if (!aNb)
108+
109+
const NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& aFactories =
110+
BRepMesh_DiscretAlgoFactory::Factories();
111+
112+
if (aFactories.IsEmpty())
113113
{
114-
printf(" *no names found\n");
114+
printf(" *no algorithms registered\n");
115115
return 0;
116116
}
117-
//
118-
printf(" *available names:\n");
119-
aIt.Initialize(aMN);
120-
for (; aIt.More(); aIt.Next())
117+
118+
printf(" *available algorithms:\n");
119+
for (NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>::Iterator anIter(aFactories);
120+
anIter.More();
121+
anIter.Next())
121122
{
122-
const TCollection_AsciiString& aName = aIt.Key();
123-
printf(" %s\n", aName.ToCString());
123+
printf(" %s\n", anIter.Value()->Name().ToCString());
124124
}
125-
//
125+
126126
return 0;
127127
}
128128

129129
//=================================================================================================
130130

131131
static int mpsetdefaultname(Draw_Interpretor&, int n, const char** a)
132132
{
133-
TCollection_AsciiString aName;
134-
//
135133
if (n != 2)
136134
{
137135
printf(" use mpsetdefaultname name\n");
138136
return 0;
139137
}
140-
//
141-
aName = a[1];
142-
//
138+
139+
TCollection_AsciiString aName = a[1];
143140
if (BRepMesh_DiscretFactory::Get().SetDefaultName(aName))
141+
{
144142
printf(" *ready\n");
143+
}
145144
else
146-
printf(" *fault\n");
147-
//
148-
return 0;
149-
}
150-
151-
//=================================================================================================
152-
153-
static int mpgetdefaultname(Draw_Interpretor&, int n, const char**)
154-
{
155-
if (n != 1)
156145
{
157-
printf(" use mpgetdefaultname\n");
158-
return 0;
146+
printf(" *algorithm '%s' not found\n", aName.ToCString());
159147
}
160-
//
161-
const TCollection_AsciiString& aName = BRepMesh_DiscretFactory::Get().DefaultName();
162-
printf(" *default name: %s\n", aName.ToCString());
163-
//
164-
return 0;
165-
}
166-
167-
//=================================================================================================
168148

169-
static int mpsetfunctionname(Draw_Interpretor&, int n, const char** a)
170-
{
171-
TCollection_AsciiString aName;
172-
//
173-
if (n != 2)
174-
{
175-
printf(" use mpsetfunctionname name\n");
176-
return 0;
177-
}
178-
//
179-
aName = a[1];
180-
//
181-
if (BRepMesh_DiscretFactory::Get().SetFunctionName(aName))
182-
printf(" *ready\n");
183-
else
184-
printf(" *fault\n");
185-
//
186149
return 0;
187150
}
188151

189152
//=================================================================================================
190153

191-
static int mpgetfunctionname(Draw_Interpretor&, int n, const char**)
154+
static int mpgetdefaultname(Draw_Interpretor&, int n, const char**)
192155
{
193156
if (n != 1)
194157
{
195-
printf(" use mpgetfunctionname\n");
158+
printf(" use mpgetdefaultname\n");
196159
return 0;
197160
}
198-
//
199-
const TCollection_AsciiString& aName = BRepMesh_DiscretFactory::Get().FunctionName();
200-
printf(" *function name: %s\n", aName.ToCString());
201-
//
202-
return 0;
203-
}
204161

205-
//=================================================================================================
162+
const TCollection_AsciiString& aName = BRepMesh_DiscretFactory::Get().DefaultName();
163+
printf(" *default name: %s\n", aName.ToCString());
206164

207-
static int mperror(Draw_Interpretor&, int n, const char**)
208-
{
209-
BRepMesh_FactoryError aErr;
210-
//
211-
if (n != 1)
212-
{
213-
printf(" use mperror\n");
214-
return 0;
215-
}
216-
//
217-
aErr = BRepMesh_DiscretFactory::Get().ErrorStatus();
218-
printf(" *ErrorStatus: %d\n", (int)aErr);
219-
//
220165
return 0;
221166
}
222167

223168
//=================================================================================================
224169

225170
static int mpincmesh(Draw_Interpretor&, int n, const char** a)
226171
{
227-
double aDeflection, aAngle;
228-
TopoDS_Shape aS;
229-
//
230172
if (n < 3)
231173
{
232-
printf(" use mpincmesh s deflection [angle]\n");
174+
printf(" use mpincmesh shape deflection [angle]\n");
233175
return 0;
234176
}
235-
//
236-
aS = DBRep::Get(a[1]);
177+
178+
TopoDS_Shape aS = DBRep::Get(a[1]);
237179
if (aS.IsNull())
238180
{
239-
printf(" null shapes is not allowed here\n");
181+
printf(" null shape is not allowed here\n");
240182
return 0;
241183
}
242-
//
243-
aDeflection = Draw::Atof(a[2]);
244-
aAngle = 0.5;
184+
185+
double aDeflection = Draw::Atof(a[2]);
186+
double aAngle = 0.5;
245187
if (n > 3)
246188
{
247189
aAngle = Draw::Atof(a[3]);
248190
}
249-
//
191+
250192
occ::handle<BRepMesh_DiscretRoot> aMeshAlgo =
251193
BRepMesh_DiscretFactory::Get().Discret(aS, aDeflection, aAngle);
252-
//
253-
BRepMesh_FactoryError aErr = BRepMesh_DiscretFactory::Get().ErrorStatus();
254-
if (aErr != BRepMesh_FE_NOERROR)
255-
{
256-
printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr);
257-
}
258-
//
194+
259195
if (aMeshAlgo.IsNull())
260196
{
261-
printf(" *Can not create the algo\n");
197+
printf(" *Cannot create the meshing algorithm\n");
262198
return 0;
263199
}
264-
//
200+
265201
aMeshAlgo->Perform();
266202
if (!aMeshAlgo->IsDone())
267203
{
268-
printf(" *Not done\n");
204+
printf(" *Meshing not done\n");
269205
}
270-
//
206+
271207
return 0;
272208
}
273209

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright (c) 2025 OPEN CASCADE SAS
2+
//
3+
// This file is part of Open CASCADE Technology software library.
4+
//
5+
// This library is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU Lesser General Public License version 2.1 as published
7+
// by the Free Software Foundation, with special exception defined in the file
8+
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9+
// distribution for complete text of the license and disclaimer of any warranty.
10+
//
11+
// Alternatively, this file may be used under the terms of Open CASCADE
12+
// commercial license or contractual agreement.
13+
14+
#include <BRepMesh_DiscretAlgoFactory.hxx>
15+
16+
#include <BRepMesh_DiscretRoot.hxx>
17+
18+
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_DiscretAlgoFactory, Standard_Transient)
19+
20+
namespace
21+
{
22+
static NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& getFactories()
23+
{
24+
static NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>> TheFactories;
25+
return TheFactories;
26+
}
27+
} // namespace
28+
29+
//==================================================================================================
30+
31+
const NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& BRepMesh_DiscretAlgoFactory::
32+
Factories()
33+
{
34+
return getFactories();
35+
}
36+
37+
//==================================================================================================
38+
39+
void BRepMesh_DiscretAlgoFactory::RegisterFactory(
40+
const occ::handle<BRepMesh_DiscretAlgoFactory>& theFactory,
41+
bool theIsPreferred)
42+
{
43+
const TCollection_AsciiString aName = theFactory->Name();
44+
NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& aFactories = getFactories();
45+
if (theIsPreferred)
46+
{
47+
UnregisterFactory(aName);
48+
aFactories.Prepend(theFactory);
49+
return;
50+
}
51+
52+
for (NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>::Iterator anIter(aFactories);
53+
anIter.More();
54+
anIter.Next())
55+
{
56+
if (TCollection_AsciiString::IsSameString(anIter.Value()->Name(), aName, false))
57+
{
58+
return;
59+
}
60+
}
61+
aFactories.Append(theFactory);
62+
}
63+
64+
//==================================================================================================
65+
66+
void BRepMesh_DiscretAlgoFactory::UnregisterFactory(const TCollection_AsciiString& theName)
67+
{
68+
NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& aFactories = getFactories();
69+
for (NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>::Iterator anIter(aFactories);
70+
anIter.More();)
71+
{
72+
if (TCollection_AsciiString::IsSameString(anIter.Value()->Name(), theName, false))
73+
{
74+
aFactories.Remove(anIter);
75+
}
76+
else
77+
{
78+
anIter.Next();
79+
}
80+
}
81+
}
82+
83+
//==================================================================================================
84+
85+
occ::handle<BRepMesh_DiscretAlgoFactory> BRepMesh_DiscretAlgoFactory::DefaultFactory()
86+
{
87+
const NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& aFactories = getFactories();
88+
return !aFactories.IsEmpty() ? aFactories.First() : occ::handle<BRepMesh_DiscretAlgoFactory>();
89+
}
90+
91+
//==================================================================================================
92+
93+
occ::handle<BRepMesh_DiscretAlgoFactory> BRepMesh_DiscretAlgoFactory::FindFactory(
94+
const TCollection_AsciiString& theName)
95+
{
96+
const NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>& aFactories = getFactories();
97+
for (NCollection_List<occ::handle<BRepMesh_DiscretAlgoFactory>>::Iterator anIter(aFactories);
98+
anIter.More();
99+
anIter.Next())
100+
{
101+
if (TCollection_AsciiString::IsSameString(anIter.Value()->Name(), theName, false))
102+
{
103+
return anIter.Value();
104+
}
105+
}
106+
return occ::handle<BRepMesh_DiscretAlgoFactory>();
107+
}
108+
109+
//==================================================================================================
110+
111+
BRepMesh_DiscretAlgoFactory::BRepMesh_DiscretAlgoFactory(const TCollection_AsciiString& theName)
112+
: myName(theName)
113+
{
114+
}

0 commit comments

Comments
 (0)