Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: MeshTest_PluginCommands.cxx |
2 | // Created: Fri Apr 11 15:41:24 2008 | |
3 | // Author: Peter KURNEV | |
4 | // <pkv@irinox> | |
5 | ||
6 | #include <MeshTest.ixx> | |
7 | #include <Draw_Interpretor.hxx> | |
8 | #include <TColStd_MapOfAsciiString.hxx> | |
9 | #include <BRepMesh_DiscretFactory.hxx> | |
10 | #include <TCollection_AsciiString.hxx> | |
11 | #include <TColStd_MapIteratorOfMapOfAsciiString.hxx> | |
12 | #include <BRepMesh_FactoryError.hxx> | |
13 | #include <BRepMesh_DiscretRoot.hxx> | |
14 | #include <Bnd_Box.hxx> | |
15 | #include <BRepMesh_PDiscretRoot.hxx> | |
16 | #include <DBRep.hxx> | |
17 | #include <TopTools_IndexedMapOfShape.hxx> | |
18 | #include <TopExp.hxx> | |
19 | #include <Poly_Triangulation.hxx> | |
20 | #include <gp_Vec.hxx> | |
21 | #include <GProp_GProps.hxx> | |
22 | #include <BRepGProp.hxx> | |
23 | #include <DrawTrSurf.hxx> | |
24 | #include <BRep_Tool.hxx> | |
25 | #include <TopoDS.hxx> | |
26 | #include <MeshTest_CheckTopology.hxx> | |
27 | #include <TColgp_Array1OfPnt2d.hxx> | |
28 | #include <Poly_Polygon3D.hxx> | |
29 | #include <Poly_Polygon2D.hxx> | |
30 | ||
31 | static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** ); | |
32 | static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** ); | |
33 | static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** ); | |
34 | static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** ); | |
35 | static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** ); | |
36 | static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** ); | |
37 | static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** ); | |
38 | static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** ); | |
e1bcbb52 | 39 | static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** ); |
7fd59977 | 40 | |
41 | //======================================================================= | |
42 | //function : PluginCommands | |
43 | //purpose : | |
44 | //======================================================================= | |
45 | void MeshTest::PluginCommands(Draw_Interpretor& theCommands) | |
46 | { | |
47 | static Standard_Boolean done = Standard_False; | |
48 | if (done) { | |
49 | return; | |
50 | } | |
51 | done = Standard_True; | |
52 | // | |
53 | const char* g = "Mesh Commands"; | |
54 | // Commands | |
55 | theCommands.Add("mpnames" , "use mpnames" , __FILE__, mpnames , g); | |
56 | theCommands.Add("mpsetdefaultname" , "use mpsetdefaultname" , __FILE__, mpsetdefaultname , g); | |
57 | theCommands.Add("mpgetdefaultname" , "use mpgetdefaultname" , __FILE__, mpgetdefaultname , g); | |
58 | theCommands.Add("mpsetfunctionname", "use mpsetfunctionname", __FILE__, mpsetfunctionname , g); | |
59 | theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname , g); | |
60 | theCommands.Add("mperror" , "use mperror" , __FILE__, mperror , g); | |
61 | theCommands.Add("mpincmesh" , "use mpincmesh" , __FILE__, mpincmesh , g); | |
62 | theCommands.Add("triarea","shape [eps] (computes triangles and surface area)",__FILE__, triarea, g); | |
e1bcbb52 | 63 | theCommands.Add("tricheck", "shape (checks triangulation of shape)", __FILE__, tricheck, g); |
7fd59977 | 64 | |
65 | } | |
66 | ||
67 | //======================================================================= | |
68 | //function : mpnames | |
69 | //purpose : | |
70 | //======================================================================= | |
71 | static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer n, const char** ) | |
72 | { | |
73 | Standard_Integer aNb; | |
74 | TColStd_MapIteratorOfMapOfAsciiString aIt; | |
75 | // | |
76 | if (n!=1) { | |
77 | printf(" use mpnames\n"); | |
78 | return 0; | |
79 | } | |
80 | // | |
81 | const TColStd_MapOfAsciiString& aMN=BRepMesh_DiscretFactory::Get().Names(); | |
82 | aNb=aMN.Extent(); | |
83 | if (!aNb) { | |
84 | printf(" *no names found\n"); | |
85 | return 0; | |
86 | } | |
87 | // | |
88 | printf(" *available names:\n"); | |
89 | aIt.Initialize(aMN); | |
90 | for (; aIt.More(); aIt.Next()) { | |
91 | const TCollection_AsciiString& aName=aIt.Key(); | |
92 | printf(" %s\n", aName.ToCString()); | |
93 | } | |
94 | // | |
95 | return 0; | |
96 | } | |
97 | //======================================================================= | |
98 | //function : mpsetdefaultname | |
99 | //purpose : | |
100 | //======================================================================= | |
101 | static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer n, const char**a ) | |
102 | { | |
103 | TCollection_AsciiString aName; | |
104 | // | |
105 | if (n!=2) { | |
106 | printf(" use mpsetdefaultname name\n"); | |
107 | return 0; | |
108 | } | |
109 | // | |
110 | aName=a[1]; | |
111 | // | |
112 | BRepMesh_DiscretFactory::Get().SetDefaultName(aName); | |
113 | printf(" *ready\n"); | |
114 | // | |
115 | return 0; | |
116 | } | |
117 | //======================================================================= | |
118 | //function : mpgetdefaultname | |
119 | //purpose : | |
120 | //======================================================================= | |
121 | static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer n, const char** ) | |
122 | { | |
123 | if (n!=1) { | |
124 | printf(" use mpgetdefaultname\n"); | |
125 | return 0; | |
126 | } | |
127 | // | |
128 | const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().DefaultName(); | |
129 | printf(" *default name: %s\n", aName.ToCString()); | |
130 | // | |
131 | return 0; | |
132 | } | |
133 | //======================================================================= | |
134 | //function : mpsetfunctionname | |
135 | //purpose : | |
136 | //======================================================================= | |
137 | static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer n, const char**a ) | |
138 | { | |
139 | TCollection_AsciiString aName; | |
140 | // | |
141 | if (n!=2) { | |
142 | printf(" use mpsetfunctionname name\n"); | |
143 | return 0; | |
144 | } | |
145 | // | |
146 | aName=a[1]; | |
147 | // | |
148 | BRepMesh_DiscretFactory::Get().SetFunctionName(aName); | |
149 | printf(" *ready\n"); | |
150 | // | |
151 | return 0; | |
152 | } | |
153 | //======================================================================= | |
154 | //function : mpgetdefaultname | |
155 | //purpose : | |
156 | //======================================================================= | |
157 | static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer n, const char** ) | |
158 | { | |
159 | if (n!=1) { | |
160 | printf(" use mpgetfunctionname\n"); | |
161 | return 0; | |
162 | } | |
163 | // | |
164 | const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().FunctionName(); | |
165 | printf(" *function name: %s\n", aName.ToCString()); | |
166 | // | |
167 | return 0; | |
168 | } | |
169 | //======================================================================= | |
170 | //function : mperror | |
171 | //purpose : | |
172 | //======================================================================= | |
173 | static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer n, const char** ) | |
174 | { | |
175 | BRepMesh_FactoryError aErr; | |
176 | // | |
177 | if (n!=1) { | |
178 | printf(" use mperror\n"); | |
179 | return 0; | |
180 | } | |
181 | // | |
182 | aErr=BRepMesh_DiscretFactory::Get().ErrorStatus(); | |
183 | printf(" *ErrorStatus: %d\n", (int)aErr); | |
184 | // | |
185 | return 0; | |
186 | } | |
187 | ||
188 | //======================================================================= | |
189 | //function :mpincmesh | |
190 | //purpose : | |
191 | //======================================================================= | |
192 | static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const char** a) | |
193 | { | |
194 | Standard_Boolean bIsDone; | |
195 | Standard_Real aDeflection, aAngle; | |
196 | TopoDS_Shape aS; | |
197 | BRepMesh_FactoryError aErr; | |
198 | BRepMesh_PDiscretRoot pAlgo; | |
199 | // | |
200 | if (n<3) { | |
201 | printf(" use mpincmesh s deflection [angle]\n"); | |
202 | return 0; | |
203 | } | |
204 | // | |
205 | aS=DBRep::Get(a[1]); | |
206 | if (aS.IsNull()) { | |
207 | printf(" null shapes is not allowed here\n"); | |
208 | return 0; | |
209 | } | |
210 | // | |
211 | aDeflection=atof(a[2]); | |
212 | aAngle=0.5; | |
213 | if (n>3) { | |
214 | aAngle=atof(a[3]); | |
215 | } | |
216 | // | |
217 | pAlgo=BRepMesh_DiscretFactory::Get().Discret(aS, | |
218 | aDeflection, | |
219 | aAngle); | |
220 | // | |
221 | aErr=BRepMesh_DiscretFactory::Get().ErrorStatus(); | |
222 | if (aErr!=BRepMesh_FE_NOERROR) { | |
223 | printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr); | |
224 | } | |
225 | // | |
226 | if (!pAlgo) { | |
227 | printf(" *Can not create the algo\n"); | |
228 | return 0; | |
229 | } | |
230 | // | |
231 | pAlgo->Perform(); | |
232 | bIsDone=pAlgo->IsDone(); | |
233 | if (!bIsDone) { | |
234 | printf(" *Not done\n"); | |
235 | } | |
236 | // | |
237 | return 0; | |
238 | } | |
239 | ||
240 | //####################################################################### | |
241 | static Standard_Integer triarea (Draw_Interpretor& di, int n, const char ** a) | |
242 | { | |
243 | ||
244 | if (n < 2) return 1; | |
245 | ||
246 | TopoDS_Shape shape = DBRep::Get(a[1]); | |
247 | if (shape.IsNull()) return 1; | |
248 | Standard_Real anEps = -1.; | |
249 | if (n > 2) | |
250 | anEps = atof(a[2]); | |
251 | ||
252 | TopTools_IndexedMapOfShape aMapF; | |
253 | TopExp::MapShapes (shape, TopAbs_FACE, aMapF); | |
254 | ||
255 | // detect if a shape has triangulation | |
256 | Standard_Boolean hasPoly = Standard_False; | |
257 | int i; | |
258 | for (i=1; i <= aMapF.Extent(); i++) { | |
259 | const TopoDS_Face& aFace = TopoDS::Face(aMapF(i)); | |
260 | TopLoc_Location aLoc; | |
261 | Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); | |
262 | if (!aPoly.IsNull()) { | |
263 | hasPoly = Standard_True; | |
264 | break; | |
265 | } | |
266 | } | |
267 | ||
268 | // compute area by triangles | |
269 | double aTriArea=0; | |
270 | if (hasPoly) { | |
271 | for (i=1; i <= aMapF.Extent(); i++) { | |
272 | const TopoDS_Face& aFace = TopoDS::Face(aMapF(i)); | |
273 | TopLoc_Location aLoc; | |
274 | Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); | |
275 | if (aPoly.IsNull()) { | |
e1bcbb52 O |
276 | cout << "face "<<i<<" has no triangulation"<<endl; |
277 | continue; | |
7fd59977 | 278 | } |
279 | const Poly_Array1OfTriangle& triangles = aPoly->Triangles(); | |
280 | const TColgp_Array1OfPnt& nodes = aPoly->Nodes(); | |
281 | for (int j=triangles.Lower(); j <= triangles.Upper(); j++) { | |
e1bcbb52 O |
282 | const Poly_Triangle& tri = triangles(j); |
283 | int n1, n2, n3; | |
284 | tri.Get (n1, n2, n3); | |
285 | const gp_Pnt& p1 = nodes(n1); | |
286 | const gp_Pnt& p2 = nodes(n2); | |
287 | const gp_Pnt& p3 = nodes(n3); | |
288 | gp_Vec v1(p1, p2); | |
289 | gp_Vec v2(p1, p3); | |
290 | double ar = v1.CrossMagnitude(v2); | |
291 | aTriArea += ar; | |
7fd59977 | 292 | } |
293 | } | |
294 | aTriArea /= 2; | |
295 | } | |
296 | ||
297 | // compute area by geometry | |
298 | GProp_GProps props; | |
299 | if (anEps <= 0.) | |
300 | BRepGProp::SurfaceProperties(shape, props); | |
301 | else | |
302 | BRepGProp::SurfaceProperties(shape, props, anEps); | |
303 | double aGeomArea = props.Mass(); | |
304 | ||
305 | di << aTriArea << " " << aGeomArea << " "; | |
306 | return 0; | |
307 | } | |
308 | ||
309 | //####################################################################### | |
e1bcbb52 | 310 | static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a) |
7fd59977 | 311 | { |
312 | if (n < 2) return 1; | |
313 | ||
314 | TopoDS_Shape shape = DBRep::Get(a[1]); | |
315 | if (shape.IsNull()) return 1; | |
316 | ||
317 | TopTools_IndexedMapOfShape aMapF; | |
318 | TopExp::MapShapes (shape, TopAbs_FACE, aMapF); | |
319 | Standard_CString name = "."; | |
320 | ||
446e11f3 | 321 | // execute check |
7fd59977 | 322 | MeshTest_CheckTopology aCheck(shape); |
323 | aCheck.Perform(); | |
446e11f3 A |
324 | |
325 | // dump info on free links inside the triangulation | |
7fd59977 | 326 | Standard_Integer nbFree = 0; |
327 | Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k; | |
328 | if (nbFac > 0) { | |
329 | for (k=1; k <= nbFac; k++) { | |
330 | Standard_Integer nbEdge = aCheck.NbFreeLinks(k); | |
331 | Standard_Integer iF = aCheck.GetFaceNumWithFL(k); | |
332 | nbFree += nbEdge; | |
333 | cout<<"free links of face "<<iF<<endl; | |
334 | const TopoDS_Face& aFace = TopoDS::Face(aMapF.FindKey(iF)); | |
335 | TopLoc_Location aLoc; | |
336 | Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc); | |
337 | const TColgp_Array1OfPnt& aPoints = aT->Nodes(); | |
338 | const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes(); | |
339 | const gp_Trsf& trsf = aLoc.Transformation(); | |
340 | TColgp_Array1OfPnt pnts(1,2); | |
341 | TColgp_Array1OfPnt2d pnts2d(1,2); | |
342 | for (i=1; i <= nbEdge; i++) { | |
e1bcbb52 O |
343 | Standard_Integer n1, n2; |
344 | aCheck.GetFreeLink(k, i, n1, n2); | |
345 | cout<<"{"<<n1<<" "<<n2<<"} "; | |
346 | pnts(1) = aPoints(n1).Transformed(trsf); | |
347 | pnts(2) = aPoints(n2).Transformed(trsf); | |
348 | Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts); | |
349 | DrawTrSurf::Set (name, poly); | |
350 | DrawTrSurf::Set (name, pnts(1)); | |
351 | DrawTrSurf::Set (name, pnts(2)); | |
352 | pnts2d(1) = aPoints2d(n1); | |
353 | pnts2d(2) = aPoints2d(n2); | |
354 | Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d); | |
355 | DrawTrSurf::Set (name, poly2d); | |
356 | DrawTrSurf::Set (name, pnts2d(1)); | |
357 | DrawTrSurf::Set (name, pnts2d(2)); | |
7fd59977 | 358 | } |
359 | cout<<endl; | |
360 | } | |
361 | } | |
362 | ||
446e11f3 | 363 | // dump info on cross face errors |
7fd59977 | 364 | Standard_Integer nbErr = aCheck.NbCrossFaceErrors(); |
365 | if (nbErr > 0) { | |
366 | cout<<"cross face errors: {face1, node1, face2, node2, distance}"<<endl; | |
367 | for (i=1; i <= nbErr; i++) { | |
368 | Standard_Integer iF1, n1, iF2, n2; | |
369 | Standard_Real aVal; | |
370 | aCheck.GetCrossFaceError(i, iF1, n1, iF2, n2, aVal); | |
371 | cout<<"{"<<iF1<<" "<<n1<<" "<<iF2<<" "<<n2<<" "<<aVal<<"} "; | |
372 | } | |
373 | cout<<endl; | |
374 | } | |
375 | ||
446e11f3 | 376 | // dump info on edges |
7fd59977 | 377 | Standard_Integer nbAsync = aCheck.NbAsyncEdges(); |
378 | if (nbAsync > 0) { | |
379 | cout<<"async edges:"<<endl; | |
380 | for (i=1; i <= nbAsync; i++) { | |
381 | Standard_Integer ie = aCheck.GetAsyncEdgeNum(i); | |
382 | cout<<ie<<" "; | |
383 | } | |
384 | cout<<endl; | |
385 | } | |
386 | ||
446e11f3 A |
387 | // dump info on free nodes |
388 | Standard_Integer nbFreeNodes = aCheck.NbFreeNodes(); | |
389 | if (nbFreeNodes > 0) { | |
390 | cout << "free nodes (in pairs: face / node): " << endl; | |
391 | for (i=1; i <= nbFreeNodes; i++) { | |
392 | Standard_Integer iface, inode; | |
393 | aCheck.GetFreeNodeNum(i, iface, inode); | |
394 | cout << "{" << iface << " " << inode << "} "; | |
395 | } | |
396 | cout << endl; | |
397 | } | |
398 | ||
399 | // output errors summary to DRAW | |
400 | if ( nbFree > 0 || nbErr > 0 || nbAsync > 0 || nbFreeNodes > 0 ) | |
401 | di << "Free_links " << nbFree | |
402 | << " Cross_face_errors " << nbErr | |
403 | << " Async_edges " << nbAsync | |
404 | << " Free_nodes " << nbFreeNodes << " "; | |
7fd59977 | 405 | return 0; |
406 | } |