Integration of OCCT 6.5.0 from SVN
[occt.git] / src / MeshTest / MeshTest_PluginCommands.cxx
CommitLineData
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
31static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** );
32static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
33static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
34static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
35static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
36static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** );
37static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** );
38static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** );
39static Standard_Integer checktopo (Draw_Interpretor& , Standard_Integer , const char** );
40
41//=======================================================================
42//function : PluginCommands
43//purpose :
44//=======================================================================
45void 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//=======================================================================
71static 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//=======================================================================
101static 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//=======================================================================
121static 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//=======================================================================
137static 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//=======================================================================
157static 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//=======================================================================
173static 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//=======================================================================
192static 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//#######################################################################
241static 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//#######################################################################
310static 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}