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** ); |
39 | static Standard_Integer checktopo (Draw_Interpretor& , Standard_Integer , const char** ); |
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); |
63 | theCommands.Add("checktopo", "shape (checks mesh topology)", __FILE__, checktopo, g); |
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()) { |
276 | cout << "face "<<i<<" has no triangulation"<<endl; |
277 | break; |
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++) { |
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; |
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 | //####################################################################### |
310 | static Standard_Integer checktopo (Draw_Interpretor& di, int n, const char ** a) |
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 | |
321 | MeshTest_CheckTopology aCheck(shape); |
322 | aCheck.Perform(); |
323 | Standard_Integer nbFree = 0; |
324 | Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k; |
325 | if (nbFac > 0) { |
326 | for (k=1; k <= nbFac; k++) { |
327 | Standard_Integer nbEdge = aCheck.NbFreeLinks(k); |
328 | Standard_Integer iF = aCheck.GetFaceNumWithFL(k); |
329 | nbFree += nbEdge; |
330 | cout<<"free links of face "<<iF<<endl; |
331 | const TopoDS_Face& aFace = TopoDS::Face(aMapF.FindKey(iF)); |
332 | TopLoc_Location aLoc; |
333 | Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc); |
334 | const TColgp_Array1OfPnt& aPoints = aT->Nodes(); |
335 | const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes(); |
336 | const gp_Trsf& trsf = aLoc.Transformation(); |
337 | TColgp_Array1OfPnt pnts(1,2); |
338 | TColgp_Array1OfPnt2d pnts2d(1,2); |
339 | for (i=1; i <= nbEdge; i++) { |
340 | Standard_Integer n1, n2; |
341 | aCheck.GetFreeLink(k, i, n1, n2); |
342 | cout<<"{"<<n1<<" "<<n2<<"} "; |
343 | pnts(1) = aPoints(n1).Transformed(trsf); |
344 | pnts(2) = aPoints(n2).Transformed(trsf); |
345 | Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts); |
346 | DrawTrSurf::Set (name, poly); |
347 | DrawTrSurf::Set (name, pnts(1)); |
348 | DrawTrSurf::Set (name, pnts(2)); |
349 | pnts2d(1) = aPoints2d(n1); |
350 | pnts2d(2) = aPoints2d(n2); |
351 | Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d); |
352 | DrawTrSurf::Set (name, poly2d); |
353 | DrawTrSurf::Set (name, pnts2d(1)); |
354 | DrawTrSurf::Set (name, pnts2d(2)); |
355 | } |
356 | cout<<endl; |
357 | } |
358 | } |
359 | |
360 | Standard_Integer nbErr = aCheck.NbCrossFaceErrors(); |
361 | if (nbErr > 0) { |
362 | cout<<"cross face errors: {face1, node1, face2, node2, distance}"<<endl; |
363 | for (i=1; i <= nbErr; i++) { |
364 | Standard_Integer iF1, n1, iF2, n2; |
365 | Standard_Real aVal; |
366 | aCheck.GetCrossFaceError(i, iF1, n1, iF2, n2, aVal); |
367 | cout<<"{"<<iF1<<" "<<n1<<" "<<iF2<<" "<<n2<<" "<<aVal<<"} "; |
368 | } |
369 | cout<<endl; |
370 | } |
371 | |
372 | Standard_Integer nbAsync = aCheck.NbAsyncEdges(); |
373 | if (nbAsync > 0) { |
374 | cout<<"async edges:"<<endl; |
375 | for (i=1; i <= nbAsync; i++) { |
376 | Standard_Integer ie = aCheck.GetAsyncEdgeNum(i); |
377 | cout<<ie<<" "; |
378 | } |
379 | cout<<endl; |
380 | } |
381 | |
382 | if (nbFree > 0 || nbErr > 0 || nbAsync > 0) |
383 | di<<"Free_links "<<nbFree |
384 | <<" Cross_face_errors "<<nbErr |
385 | <<" Async_edges "<<nbAsync << " "; |
386 | return 0; |
387 | } |