0025418: Debug output to be limited to OCC development environment
[occt.git] / src / MeshTest / MeshTest.cxx
1 // Created on: 1993-09-22
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Standard_Stream.hxx>
18
19 #include <stdio.h>
20
21 #include <MeshTest.ixx>
22
23 #include <MeshTest_DrawableMesh.hxx>
24 #include <TopAbs_ShapeEnum.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <TopoDS_Compound.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopTools_ListIteratorOfListOfShape.hxx>
32 #include <DBRep.hxx>
33 #include <BRepTest.hxx>
34 #include <GeometryTest.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRep_Builder.hxx>
37 #include <Draw_MarkerShape.hxx>
38 #include <Draw_Appli.hxx>
39 #include <Draw.hxx>
40 #include <DrawTrSurf.hxx>
41 #include <BRepMesh_Triangle.hxx>
42 #include <BRepMesh_DataStructureOfDelaun.hxx>
43 #include <BRepMesh_Delaun.hxx>
44 #include <BRepMesh_FastDiscret.hxx>
45 #include <BRepMesh_Vertex.hxx>
46 #include <BRepMesh_Edge.hxx>
47 #include <BRepMesh_IncrementalMesh.hxx>
48 #include <TColStd_ListIteratorOfListOfInteger.hxx>
49 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
50 #include <Bnd_Box.hxx>
51 #include <Precision.hxx>
52 #include <Draw_Interpretor.hxx>
53 #include <Geom_Plane.hxx>
54 #include <Geom_Surface.hxx>
55 #include <Draw_Marker3D.hxx>
56 #include <Draw_Segment2D.hxx>
57
58 #include <GCPnts_UniformAbscissa.hxx>
59 #include <GeomAdaptor_Curve.hxx>
60 #include <Geom_Curve.hxx>
61 #include <Extrema_LocateExtPC.hxx>
62
63 #include <TopLoc_Location.hxx>
64 #include <gp_Trsf.hxx>
65 #include <Poly_Triangulation.hxx>
66 #include <Poly_Connect.hxx>
67 #include <TColgp_Array1OfPnt2d.hxx>
68 #include <TColStd_HArray1OfInteger.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <gp_Pln.hxx>
71
72 #include <PLib.hxx>
73 #include <AppCont_ContMatrices.hxx>
74 #include <math_Vector.hxx>
75 #include <math_Matrix.hxx>
76 #include <math.hxx>
77
78 #include <CSLib_DerivativeStatus.hxx>
79 #include <CSLib.hxx>
80 #include <BRepAdaptor_Surface.hxx>
81 #include <Bnd_Box.hxx>
82 #include <BRepBndLib.hxx>
83
84
85 //epa Memory leaks test
86 #include <BRepBuilderAPI_MakePolygon.hxx>
87 #include <TopoDS_Wire.hxx>
88 #include <BRepBuilderAPI_MakeFace.hxx>
89 #include <BRepTools.hxx>
90
91 //OAN: for triepoints
92 #include <BRepBuilderAPI_MakeVertex.hxx>
93 #include <Poly_PolygonOnTriangulation.hxx>
94 #include <TopTools_MapIteratorOfMapOfShape.hxx>
95
96 #ifdef WNT
97 Standard_IMPORT Draw_Viewer dout;
98 #endif
99
100 #define MAX2(X, Y)      (  Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
101 #define MAX3(X, Y, Z)   ( MAX2 ( MAX2(X,Y) , Z) )
102
103
104
105 #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
106 #define TWOTHIRD 0.666666666666666666666666666666666666666666666666666666666666
107
108 #ifdef OCCT_DEBUG_MESH_CHRONO
109 #include <OSD_Chronometer.hxx>
110 Standard_Integer D0Control, D0Internal, D0Unif, D0Edges, NbControls;
111 OSD_Chronometer chTotal, chInternal, chControl, chUnif, chAddPoint;
112 OSD_Chronometer chEdges, chMaillEdges, chEtuInter, chLastControl, chStock;
113 OSD_Chronometer chAdd11, chAdd12, chAdd2, chUpdate, chPointValid;
114 OSD_Chronometer chIsos, chPointsOnIsos;
115 #endif
116
117 //=======================================================================
118 //function : incrementalmesh
119 //purpose  : 
120 //=======================================================================
121
122 static Standard_Integer incrementalmesh(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
123 {
124   if (nbarg < 3) {
125     di << " use incmesh shape deflection [inParallel (0/1) : 0 by default]\n";
126     return 0;
127   }
128
129   TopoDS_Shape aShape = DBRep::Get(argv[1]);
130   if (aShape.IsNull()) {
131     di << " null shapes is not allowed here\n";
132     return 0;
133   }
134   Standard_Real aDeflection = Draw::Atof(argv[2]);
135
136   Standard_Boolean isInParallel = Standard_False;
137   if (nbarg == 4) {
138         isInParallel = Draw::Atoi(argv[3]) == 1;
139   }
140   di << "Incremental Mesh, multi-threading "
141     << (isInParallel ? "ON\n" : "OFF\n");
142   
143   BRepMesh_IncrementalMesh MESH(aShape, aDeflection, Standard_False, 0.5, isInParallel);
144   Standard_Integer statusFlags = MESH.GetStatusFlags();  
145
146   di << "Meshing statuses: ";
147
148   if( !statusFlags )
149   {
150     di << "NoError";
151   }
152   else
153   {
154     Standard_Integer i;
155     for( i = 0; i < 4; i++ )
156     {
157       if( (statusFlags >> i) & (Standard_Integer)1 )
158       {
159         switch(i+1)
160         {
161           case 1:
162             di << "OpenWire ";
163             break;
164           case 2:
165             di << "SelfIntersectingWire ";
166             break;
167           case 3:
168             di << "Failure ";
169             break;
170           case 4:
171             di << "ReMesh ";
172             break;
173         }
174       }
175     }
176   }
177
178   return 0;
179 }
180
181 //=======================================================================
182 //function : MemLeakTest
183 //purpose  : 
184 //=======================================================================
185
186 static Standard_Integer MemLeakTest(Draw_Interpretor&, Standard_Integer /*nbarg*/, const char** /*argv*/)
187 {
188   for(int i=0;i<10000;i++)
189   {
190     BRepBuilderAPI_MakePolygon w(gp_Pnt(0,0,0),gp_Pnt(0,100,0),gp_Pnt(20,100,0),gp_Pnt(20,0,0));
191     w.Close();     
192     TopoDS_Wire wireShape( w.Wire());
193     BRepBuilderAPI_MakeFace faceBuilder(wireShape);          
194     TopoDS_Face f( faceBuilder.Face());
195     BRepMesh_IncrementalMesh im(f,1);
196     BRepTools::Clean(f);      
197   }
198   return 0;
199 }
200
201 //=======================================================================
202 //function : fastdiscret
203 //purpose  : 
204 //=======================================================================
205
206 static Standard_Integer fastdiscret(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
207 {
208   if (nbarg < 3) return 1;
209
210   TopoDS_Shape S = DBRep::Get(argv[1]);
211   if (S.IsNull()) return 1;
212
213   const Standard_Real d = Draw::Atof(argv[2]);
214
215   Standard_Boolean WithShare = Standard_True;
216   if (nbarg > 3) WithShare = Draw::Atoi(argv[3]);
217
218   Bnd_Box B;
219   BRepBndLib::Add(S,B);
220   BRepMesh_FastDiscret MESH(d,0.5,B,WithShare,Standard_True,Standard_False,Standard_True);
221
222   //Standard_Integer NbIterations = MESH.NbIterations();
223   //if (nbarg > 4) NbIterations = Draw::Atoi(argv[4]);
224   //MESH.NbIterations() = NbIterations;
225
226   di<<"Starting FastDiscret with :"<<"\n";
227   di<<"  Deflection="<<d<<"\n";
228   di<<"  Angle="<<0.5<<"\n";
229   di<<"  SharedMode="<< (Standard_Integer) WithShare<<"\n";
230   //di<<"  NbIterations="<<NbIterations<<"\n";
231
232   Handle(Poly_Triangulation) T;
233   BRep_Builder aBuilder;
234   TopExp_Explorer ex;
235
236   // Clear existing triangulations
237   for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next())
238     aBuilder.UpdateFace(TopoDS::Face(ex.Current()),T);
239
240   MESH.Perform(S);
241
242   TopoDS_Compound aCompGood, aCompFailed, aCompViolating;
243
244   TopLoc_Location L;
245   Standard_Integer nbtriangles = 0, nbnodes = 0, nbfailed = 0, nbviolating = 0;
246   Standard_Real maxdef = 0.0;
247   for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next())
248   {
249     T = BRep_Tool::Triangulation(TopoDS::Face(ex.Current()),L);
250     if (T.IsNull())
251     {
252       nbfailed++;
253       if (aCompFailed.IsNull())
254         aBuilder.MakeCompound(aCompFailed);
255       aBuilder.Add(aCompFailed,ex.Current());
256     }
257     else
258     {
259       nbtriangles += T->NbTriangles();
260       nbnodes += T->NbNodes();
261       if (T->Deflection() > maxdef) maxdef = T->Deflection();
262       if (T->Deflection() > d)
263       {
264         nbviolating++;
265         if (aCompViolating.IsNull())
266           aBuilder.MakeCompound(aCompViolating);
267         aBuilder.Add(aCompViolating,ex.Current());
268       }
269       else
270       {
271         if (aCompGood.IsNull())
272           aBuilder.MakeCompound(aCompGood);
273         aBuilder.Add(aCompGood,ex.Current());
274       }
275     }
276   }
277
278   if (!aCompGood.IsNull())
279   {
280     char name[256];
281     strcpy(name,argv[1]);
282     strcat(name,"_good");
283     DBRep::Set(name,aCompGood);
284   }
285   if (!aCompFailed.IsNull())
286   {
287     char name[256];
288     strcpy(name,argv[1]);
289     strcat(name,"_failed");
290     DBRep::Set(name,aCompFailed);
291   }
292   if (!aCompViolating.IsNull())
293   {
294     char name[256];
295     strcpy(name,argv[1]);
296     strcat(name,"_violating");
297     DBRep::Set(name,aCompViolating);
298   }
299
300   di<<"FastDiscret completed with :"<<"\n";
301   di<<"  MaxDeflection="<<maxdef<<"\n";
302   di<<"  NbNodes="<<nbnodes<<"\n";
303   di<<"  NbTriangles="<<nbtriangles<<"\n";
304   di<<"  NbFailed="<<nbfailed<<"\n";
305   di<<"  NbViolating="<<nbviolating<<"\n";
306
307   return 0;
308 }
309
310
311 //=======================================================================
312 //function : triangule
313 //purpose  : 
314 //=======================================================================
315
316
317 class BRepMesh_Couple
318 {
319 public:
320   BRepMesh_Couple() { myI1 = myI2 = 0; }
321   BRepMesh_Couple(const Standard_Integer I1,
322     const Standard_Integer I2)
323   { myI1 = I1; myI2 = I2; }
324
325   Standard_Integer myI1;
326   Standard_Integer myI2;
327 };
328
329 inline Standard_Boolean IsEqual(const BRepMesh_Couple& one,
330                                 const BRepMesh_Couple& other)
331 {
332   if (one.myI1 == other.myI1 &&
333     one.myI2 == other.myI2) return Standard_True;
334   else return Standard_False;
335 }
336
337 inline Standard_Integer HashCode(const BRepMesh_Couple& one,
338                                  const Standard_Integer Upper)
339 {
340   return ::HashCode((one.myI1+one.myI2), Upper);
341 }
342
343 typedef NCollection_Map<BRepMesh_Couple> BRepMesh_MapOfCouple;
344
345
346 static void AddLink(BRepMesh_MapOfCouple& aMap, 
347                     Standard_Integer v1,
348                     Standard_Integer v2)
349 {
350   Standard_Integer i1 = v1;
351   Standard_Integer i2 = v2;
352   if(i1 > i2) {
353     i1 = v2;
354     i2 = v1;
355   }
356   aMap.Add(BRepMesh_Couple(i1,i2));
357 }
358
359 static void MeshStats(const TopoDS_Shape& theSape,
360                       Standard_Integer& theNbTri,
361                       Standard_Integer& theNbEdges,
362                       Standard_Integer& theNbNodes)
363 {
364   theNbTri = 0;
365   theNbEdges = 0;
366   theNbNodes = 0;
367
368   Handle(Poly_Triangulation) T;
369   TopLoc_Location L;
370
371   for ( TopExp_Explorer ex(theSape, TopAbs_FACE); ex.More(); ex.Next()) {
372     TopoDS_Face F = TopoDS::Face(ex.Current());
373     T = BRep_Tool::Triangulation(F, L);
374     if (!T.IsNull()) {
375       theNbTri += T->NbTriangles();
376       theNbNodes += T->NbNodes();
377
378       BRepMesh_MapOfCouple aMap;
379       //count number of links
380       Poly_Array1OfTriangle& Trian = T->ChangeTriangles();
381       for(Standard_Integer i = 1; i<=Trian.Length();i++) {
382         Standard_Integer v1, v2, v3;
383         Trian(i).Get(v1,v2,v3);
384
385         AddLink(aMap, v1, v2);
386         AddLink(aMap, v2, v3);
387         AddLink(aMap, v3, v1);
388       }
389
390       theNbEdges+=aMap.Extent();
391     }
392   }
393 }
394
395 static Standard_Integer triangule(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
396 {
397   if (nbarg < 4)
398     return 1;
399
400   const char *id1 = argv[2];
401   TopoDS_Shape aShape = DBRep::Get(id1);
402   if (aShape.IsNull())
403     return 1;
404
405   di << argv[1] << " ";
406
407   Standard_Real aDeflection = Draw::Atof(argv[3]);
408   if (aDeflection <= 0.)
409   {
410     di << " Incorrect value of deflection!" << "\n";
411     return 1;
412   }
413
414   Handle(MeshTest_DrawableMesh) aDMesh = 
415     new MeshTest_DrawableMesh(aShape, aDeflection);
416
417   Draw::Set(argv[1], aDMesh);
418
419   Standard_Integer nbn, nbl, nbe;
420   MeshStats(aShape, nbe, nbl, nbn);
421
422   di<<"(Resultat ("<<nbe<<" mailles) ("<<nbl<<" aretes) ("<<nbn<<" sommets))"<<"\n";
423
424   // passe de verification du maillage.
425   /*Standard_Integer nbc;
426   for (Standard_Integer iLi=1; iLi<= DM->Mesh()->NbEdges(); iLi++) {
427   const BRepMesh_Edge& ed=DM->Mesh()->Edge(iLi);
428   if (ed.Movability()!=BRepMesh_Deleted) {
429   nbc=struc->ElemConnectedTo(iLi).Extent();
430   if (nbc != 1 && nbc != 2) di <<"ERROR MAILLAGE Edge no "<< iLi<<"\n";
431   }
432   }*/
433
434
435   Bnd_Box aBox;
436
437   TopExp_Explorer aFaceIt(aShape, TopAbs_FACE);
438   for (; aFaceIt.More(); aFaceIt.Next())
439   {
440     const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
441
442     TopLoc_Location aLoc = aFace.Location();
443     Handle(Poly_Triangulation) aTriangulation =
444       BRep_Tool::Triangulation(aFace, aLoc);
445
446     if (!aTriangulation.IsNull())
447     {
448       const Standard_Integer    aLength = aTriangulation->NbNodes();
449       const TColgp_Array1OfPnt& aNodes  = aTriangulation->Nodes();
450       for (Standard_Integer i = 1; i <= aLength; ++i)
451         aBox.Add(aNodes(i));
452     }
453   }
454
455   Standard_Real aDelta = 0.;
456   if (!aBox.IsVoid())
457   {
458     Standard_Real x, y, z, X, Y, Z;
459     aBox.Get(x, y, z, X, Y, Z);
460
461     aDelta = Max(X - x, Max(Y - y, Z - z));
462     if (aDelta > 0.0)
463       aDelta = aDeflection / aDelta;
464   }
465
466   di << " Ratio between deflection and total shape size is " << aDelta << "\n";
467
468   return 0;
469 }
470
471 //=======================================================================
472 //function : addshape
473 //purpose  : 
474 //=======================================================================
475
476 Standard_Integer addshape(Draw_Interpretor&, Standard_Integer n, const char** a)
477 {
478   if (n < 3) return 1;
479   Handle(MeshTest_DrawableMesh) D =
480     Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
481   if (D.IsNull()) return 1;
482   TopoDS_Shape S = DBRep::Get(a[2]);
483   if (S.IsNull()) return 1;
484
485   D->Add(S);
486   Draw::Repaint();
487
488   return 0;
489 }
490
491
492 //=======================================================================
493 //function : smooth
494 //purpose  : 
495 //=======================================================================
496
497 /*Standard_Integer smooth(Draw_Interpretor&, Standard_Integer n, const char** a)
498 {
499 if (n < 2) return 1;
500 Handle(MeshTest_DrawableMesh) D =
501 Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
502 if (D.IsNull()) return 1;
503 Handle(BRepMesh_DataStructureOfDelaun) struc=
504 D->Mesh()->Result();
505 BRepMesh_Array1OfVertexOfDelaun toto(1,1);
506 BRepMesh_Delaun trial(struc, 
507 toto,
508 Standard_True);
509 trial.SmoothMesh(0.1);
510 Draw::Repaint();
511 return 0;
512 }
513 */
514
515 //=======================================================================
516 //function : edges
517 //purpose  : 
518 //=======================================================================
519
520 /*static Standard_Integer edges (Draw_Interpretor&, Standard_Integer n, const char** a)
521 {
522 if (n < 3) return 1;
523
524 Handle(MeshTest_DrawableMesh) D =
525 Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
526 if (D.IsNull()) return 1;
527 TopoDS_Shape S = DBRep::Get(a[2]);
528 if (S.IsNull()) return 1;
529
530 TopExp_Explorer ex;
531 TColStd_SequenceOfInteger& eseq = D->Edges();
532 Handle(BRepMesh_FastDiscret) M = D->Mesh();
533 Handle(BRepMesh_DataStructureOfDelaun) DS = M->Result();
534 Standard_Integer e1, e2, e3, iTri;
535 Standard_Boolean o1, o2, o3;
536
537 // the faces
538 for (ex.Init(S,TopAbs_FACE);ex.More();ex.Next()) {
539 const BRepMesh_MapOfInteger& elems = DS->ElemOfDomain();
540 BRepMesh_MapOfInteger::Iterator it;
541 for (it.Initialize(elems); it.More(); it.Next()) {
542 iTri = it.Key();
543 const BRepMesh_Triangle& triang = M->Triangle(iTri);
544 if (triang.Movability()!=BRepMesh_Deleted) {
545 triang.Edges(e1, e2, e3, o1, o2, o3);
546 eseq.Append(e1);
547 eseq.Append(e2);
548 eseq.Append(e3);
549 }
550 }
551 }
552
553 // the edges
554 //for (ex.Init(S,TopAbs_EDGE,TopAbs_FACE);ex.More();ex.Next()) {
555 //}
556
557 Draw::Repaint();
558 return 0;
559 }
560 */
561
562 //=======================================================================
563 //function : vertices
564 //purpose  : 
565 //=======================================================================
566 static Standard_Integer vertices(
567   Draw_Interpretor& /*di*/, 
568   Standard_Integer  /*argc*/, 
569   const char**      /*argv*/)
570 {
571   return 0;
572
573   // TODO: OAN re-implement this command according changes in BRepMesh
574   //if (argc < 3)
575   //  return 1;
576
577   //Handle(MeshTest_DrawableMesh) aDrawableMesh =
578   //  Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(argv[1]));
579   //if (aDrawableMesh.IsNull())
580   //  return 1;
581
582   //TopoDS_Shape aShape = DBRep::Get(argv[2]);
583   //if (aShape.IsNull())
584   //  return 1;
585
586   //TColStd_SequenceOfInteger&   aVertexSeq = aDrawableMesh->Vertices();
587   //Handle(BRepMesh_FastDiscret) aMesh      = aDrawableMesh->Mesh();
588
589   //TopExp_Explorer aFaceIt(aShape, TopAbs_FACE);
590   //for (; aFaceIt.More(); aFaceIt.Next())
591   //{
592   //  const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
593
594   //  Handle(BRepMesh_FaceAttribute) aAttribute;
595   //  if (aMesh->GetFaceAttribute(aFace, aAttribute))
596   //  {
597   //    Handle(BRepMesh_DataStructureOfDelaun) aStructure = aAttribute->EditStructure();
598
599   //    // Recuperate from the map of edges.
600   //    const BRepMeshCol::MapOfInteger& aEdgeMap = aStructure->LinksOfDomain();
601
602   //    // Iterator on edges.
603   //    BRepMeshCol::MapOfInteger aVertices;
604   //    BRepMeshCol::MapOfInteger::Iterator aEdgeIt(aEdgeMap);
605   //    for (; aEdgeIt.More(); aEdgeIt.Next())
606   //    {
607   //      const BRepMesh_Edge& aEdge = aStructure->GetLink(aEdgeIt.Key());
608   //      aVertices.Add(aEdge.FirstNode());
609   //      aVertices.Add(aEdge.LastNode());
610   //    }
611
612   //    BRepMeshCol::MapOfInteger::Iterator anIt(vtx);
613   //    for ( ; anIt.More(); anIt.Next() )
614   //      aVertexSeq.Append(anIt.Key());
615   //  }
616   //}
617
618   //Draw::Repaint();
619   //return 0;
620 }
621
622 //=======================================================================
623 //function : medge
624 //purpose  : 
625 //=======================================================================
626
627 static Standard_Integer medge (Draw_Interpretor&, Standard_Integer n, const char** a)
628 {
629   if (n < 3) return 1;
630
631   Handle(MeshTest_DrawableMesh) D =
632     Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
633   if (D.IsNull()) return 1;
634
635   Standard_Integer i,j,e;
636   TColStd_SequenceOfInteger& eseq = D->Edges();
637   for (i = 2; i < n; i++) {
638     e = Draw::Atoi(a[i]);
639     if (e > 0)
640       eseq.Append(e);
641     else if (e < 0) {
642       e = -e;
643       j = 1; 
644       while (j <= eseq.Length()) {
645         if (eseq(j) == e) 
646           eseq.Remove(j);
647         else
648           j++;
649       }
650     }
651     else
652       eseq.Clear();
653   }
654
655   Draw::Repaint();
656   return 0;
657 }
658
659
660 //=======================================================================
661 //function : mvertex
662 //purpose  : 
663 //=======================================================================
664
665 static Standard_Integer mvertex (Draw_Interpretor&, Standard_Integer n, const char** a)
666 {
667   if (n < 3) return 1;
668
669   Handle(MeshTest_DrawableMesh) D =
670     Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
671   if (D.IsNull()) return 1;
672
673   Standard_Integer i,j,v;
674   TColStd_SequenceOfInteger& vseq = D->Vertices();
675   for (i = 2; i < n; i++) {
676     v = Draw::Atoi(a[i]);
677     if (v > 0)
678       vseq.Append(v);
679     else if (v < 0) {
680       v = -v;
681       j = 1;
682       while (j <= vseq.Length()) {
683         if (vseq(j) == v)
684           vseq.Remove(v);
685         else
686           j++;
687       }
688     }
689     else
690       vseq.Clear();
691   }
692   Draw::Repaint();
693   return 0;
694 }
695
696
697 //=======================================================================
698 //function : triangle
699 //purpose  : 
700 //=======================================================================
701
702 static Standard_Integer triangle (Draw_Interpretor&, Standard_Integer n, const char** a)
703 {
704   if (n < 3) return 1;
705
706   Handle(MeshTest_DrawableMesh) D =
707     Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(a[1]));
708   if (D.IsNull()) return 1;
709
710   Standard_Integer i,j,v;
711   TColStd_SequenceOfInteger& tseq = D->Triangles();
712   for (i = 2; i < n; i++) {
713     v = Draw::Atoi(a[i]);
714     if (v > 0)
715       tseq.Append(v);
716     else if (v < 0) {
717       v = -v;
718       j = 1;
719       while (j <= tseq.Length()) {
720         if (tseq(j) == v)
721           tseq.Remove(v);
722         else
723           j++;
724       }
725     }
726     else
727       tseq.Clear();
728   }
729   Draw::Repaint();
730   return 0;
731 }
732
733 //=======================================================================
734 //function : dumpvertex
735 //purpose  : 
736 //=======================================================================
737
738 /*
739 Standard_Integer dumpvertex(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
740 {
741 if (argc < 2) return 1;
742
743 Handle(MeshTest_DrawableMesh) D =
744 Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(argv[1]));
745 if (D.IsNull()) return 1;
746
747 Handle(BRepMesh_DataStructureOfDelaun) struc = D->Mesh()->Result();
748
749 Standard_Integer in=1;
750 if (argc>=3) {
751 in=Draw::Atoi(argv[2]);
752 in=Max(1,in);
753 }
754 Standard_Integer nbn=in;
755 if (argc>=4) {
756 nbn=Draw::Atoi(argv[3]);
757 nbn=Min(nbn,struc->NbNodes());
758 }
759
760 for (; in<=nbn; in++) {
761 BRepMesh_Vertex nod=struc->GetNode(in);
762 di<<"(node "<<in<<" (uv "<<nod.Coord().X()
763 <<" "<<nod.Coord().Y()<<") (3d "
764 <<nod.Location3d()<<") ";
765 printdegree(nod.Movability(), di);
766 di<<" (edgeconex";
767 BRepMesh_ListOfInteger::Iterator tati(struc->LinkNeighboursOf(in));
768 for (; tati.More(); tati.Next()) di<<" "<<tati.Value();
769 di << "))\n";
770 }
771 di <<"\n";
772 return 0;
773 }
774
775 //=======================================================================
776 //function : dumpedge
777 //purpose  : 
778 //=======================================================================
779
780 Standard_Integer dumpedge(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
781 {
782 if (argc < 2) return 1;
783
784 Handle(MeshTest_DrawableMesh) D =
785 Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(argv[1]));
786 if (D.IsNull()) return 1;
787
788 Handle(BRepMesh_DataStructureOfDelaun) struc=D->Mesh()->Result();
789 Standard_Integer il=1;
790 if (argc>=3) {
791 il=Draw::Atoi(argv[2]);
792 il=Max(1, il);
793 }
794 Standard_Integer nbl=il;
795 if (argc>=4) {
796 nbl=Draw::Atoi(argv[3]);
797 nbl=Min(nbl, struc->NbLinks());
798 }
799
800 for (; il<=nbl; il++) {
801 BRepMesh_Edge edg=struc->GetLink(il);
802 di << "(edge "<<il<<" ("<<edg.FirstNode()<<" "<<edg.LastNode()
803 <<" ";
804 printdegree(edg.Movability(), di);
805 di<<") (triconex";
806 const BRepMesh_PairOfIndex& pair = struc->ElemConnectedTo(il);
807 for (Standard_Integer j = 1, jn = pair.Extent(); j <= jn; j++)
808 di<<" "<<pair.Index(j);
809 di << "))\n";
810 }
811 di <<"\n";
812 return 0;
813 }
814
815 //=======================================================================
816 //function : dumptriangle
817 //purpose  : 
818 //=======================================================================
819
820 Standard_Integer dumptriangle(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
821 {
822 if (argc < 2) return 1;
823
824 Handle(MeshTest_DrawableMesh) D =
825 Handle(MeshTest_DrawableMesh)::DownCast(Draw::Get(argv[1]));
826 if (D.IsNull()) return 1;
827
828 Handle(BRepMesh_DataStructureOfDelaun) struc=D->Mesh()->Result();
829 Standard_Integer ie=1;
830 if (argc>=3) {
831 ie=Draw::Atoi(argv[2]);
832 ie=Max(1, ie);
833 }
834 Standard_Integer nbe=ie;
835 if (argc>=4) {
836 nbe=Draw::Atoi(argv[3]);
837 nbe=Min(nbe, struc->NbElements());
838 }
839
840 Standard_Integer e1, e2, e3;
841 Standard_Boolean o1, o2, o3;
842
843 for (; ie<=nbe; ie++) {
844 BRepMesh_Triangle tri=struc->GetElement(ie);
845 tri.Edges(e1, e2, e3, o1, o2, o3); 
846 if (o1) e1=-e1;
847 if (o2) e2=-e2;
848 if (o3) e3=-e3;
849 di<<" (maille "<<ie<<" (links "<<e1<<" "
850 <<e2<<" "<<e3<<")";
851 printdegree(tri.Movability(), di);
852 di<<")\n";
853 }
854 di << "\n";
855 return 0;
856 }
857 */
858
859 //=======================================================================
860 //function : trianglesinfo
861 //purpose  : 
862 //=======================================================================
863 static Standard_Integer trianglesinfo(Draw_Interpretor& di, Standard_Integer n, const char** a)
864 {
865   if (n != 2) return 1;
866   TopoDS_Shape S = DBRep::Get(a[1]);
867   if (S.IsNull()) return 1;
868   TopExp_Explorer ex;
869   Handle(Poly_Triangulation) T;
870   TopLoc_Location L;
871
872   Standard_Real MaxDeflection = 0.0;
873   Standard_Integer nbtriangles = 0, nbnodes = 0;
874   for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next()) {
875     TopoDS_Face F = TopoDS::Face(ex.Current());
876     T = BRep_Tool::Triangulation(F, L);
877     if (!T.IsNull()) {
878       nbtriangles += T->NbTriangles();
879       nbnodes += T->NbNodes();
880       if (T->Deflection() > MaxDeflection)
881         MaxDeflection = T->Deflection();
882     }
883   }
884
885   di<<"\n";
886   di<<"This shape contains " <<nbtriangles<<" triangles."<<"\n";
887   di<<"                    " <<nbnodes    <<" nodes."<<"\n";
888   di<<"Maximal deflection " <<MaxDeflection<<"\n";
889   di<<"\n";
890 #ifdef OCCT_DEBUG_MESH_CHRONO
891   Standard_Real tot, addp, unif, contr, inter;
892   Standard_Real edges, mailledges, etuinter, lastcontrol, stock;
893   Standard_Real add11, add12, add2, upda, pointvalid;
894   Standard_Real isos, pointsisos;
895   chTotal.Show(tot); chAddPoint.Show(addp); chUnif.Show(unif); 
896   chControl.Show(contr); chInternal.Show(inter);
897   chEdges.Show(edges); chMaillEdges.Show(mailledges);
898   chEtuInter.Show(etuinter); chLastControl.Show(lastcontrol); 
899   chStock.Show(stock);
900   chAdd11.Show(add11); chAdd12.Show(add12); chAdd2.Show(add2); chUpdate.Show(upda);
901   chPointValid.Show(pointvalid); chIsos.Show(isos); chPointsOnIsos.Show(pointsisos);
902
903   if (tot > 0.00001) {
904     di <<"temps total de maillage:     "<<tot        <<" seconds"<< "\n";
905     di <<"dont: "<< "\n";
906     di <<"discretisation des edges:    "<<edges      <<" seconds---> "<< 100*edges/tot      <<" %"<<"\n";
907     di <<"maillage des edges:          "<<mailledges <<" seconds---> "<< 100*mailledges/tot <<" %"<<"\n";
908     di <<"controle et points internes: "<<etuinter   <<" seconds---> "<< 100*etuinter/tot   <<" %"<<"\n";
909     di <<"derniers controles:          "<<lastcontrol<<" seconds---> "<< 100*lastcontrol/tot<<" %"<<"\n";
910     di <<"stockage dans la S.D.        "<<stock      <<" seconds---> "<< 100*stock/tot      <<" %"<<"\n";
911     di << "\n";
912     di <<"et plus precisement: "<<"\n";
913     di <<"Add 11ere partie :           "<<add11     <<" seconds---> "<<100*add11/tot      <<" %"<<"\n";
914     di <<"Add 12ere partie :           "<<add12     <<" seconds---> "<<100*add12/tot      <<" %"<<"\n";
915     di <<"Add 2eme partie :            "<<add2      <<" seconds---> "<<100*add2/tot       <<" %"<<"\n";
916     di <<"Update :                     "<<upda      <<" seconds---> "<<100*upda/tot       <<" %"<<"\n";
917     di <<"AddPoint :                   "<<addp      <<" seconds---> "<<100*addp/tot       <<" %"<<"\n";
918     di <<"UniformDeflection            "<<unif      <<" seconds---> "<<100*unif/tot       <<" %"<<"\n";
919     di <<"Controle :                   "<<contr     <<" seconds---> "<<100*contr/tot      <<" %"<<"\n";
920     di <<"Points Internes:             "<<inter     <<" seconds---> "<<100*inter/tot      <<" %"<<"\n";
921     di <<"calcul des isos et du, dv:   "<<isos      <<" seconds---> "<<100*isos/tot       <<" %"<<"\n";
922     di <<"calcul des points sur isos:  "<<pointsisos<<" seconds---> "<<100*pointsisos/tot <<" %"<<"\n";
923     di <<"IsPointValid:                "<<pointvalid<<" seconds---> "<<100*pointvalid/tot <<" %"<<"\n";
924     di << "\n";
925
926
927     di <<"nombre d'appels de controle apres points internes          : "<< NbControls << "\n";
928     di <<"nombre de points sur restrictions                          : "<< D0Edges    << "\n";
929     di <<"nombre de points calcules par UniformDeflection            : "<< D0Unif     << "\n";
930     di <<"nombre de points calcules dans InternalVertices            : "<< D0Internal << "\n";
931     di <<"nombre de points calcules dans Control                     : "<< D0Control  << "\n";
932     if (nbnodes-D0Edges != 0) { 
933       Standard_Real ratio = (Standard_Real)(D0Internal+D0Control)/ (Standard_Real)(nbnodes-D0Edges);
934       di <<"---> Ratio: (D0Internal+D0Control) / (nbNodes-nbOnEdges)   : "<< ratio      << "\n";
935     }
936
937     di << "\n";
938
939     chTotal.Reset(); chAddPoint.Reset(); chUnif.Reset(); 
940     chControl.Reset(); chInternal.Reset();
941     chEdges.Reset(); chMaillEdges.Reset();
942     chEtuInter.Reset(); chLastControl.Reset(); 
943     chStock.Reset();
944     chAdd11.Reset(); chAdd12.Reset(); chAdd2.Reset(); chUpdate.Reset();
945     chPointValid.Reset(); chIsos.Reset(); chPointsOnIsos.Reset();
946
947   }
948 #endif
949   return 0;
950 }
951
952 //=======================================================================
953 //function : veriftriangles
954 //purpose  : 
955 //=======================================================================
956
957 static Standard_Integer veriftriangles(Draw_Interpretor& di, Standard_Integer n, const char** a)
958 {
959   if (n < 2) return 1;
960   Standard_Boolean quiet = 1;
961   if (n == 3) quiet = 0;
962   TopoDS_Shape Sh = DBRep::Get(a[1]);
963   if (Sh.IsNull()) return 1;
964   TopExp_Explorer ex;
965   Handle(Poly_Triangulation) T;
966   TopLoc_Location L;
967   Standard_Integer i, n1, n2, n3;
968   gp_Pnt2d mitri, v1, v2, v3, mi2d1, mi2d2, mi2d3;
969   gp_XYZ vecEd1, vecEd2, vecEd3;
970   //  Standard_Real dipo, dm, dv, d1, d2, d3, defle;
971   Standard_Real dipo, dv, d1, d2, d3, defle;
972   Handle(Geom_Surface) S;
973   Standard_Integer nbface = 0;
974   gp_Pnt PP;
975
976   for (ex.Init(Sh, TopAbs_FACE); ex.More(); ex.Next()) {
977     TopoDS_Face F = TopoDS::Face(ex.Current());
978     nbface++;
979     T = BRep_Tool::Triangulation(F, L);
980     Standard_Real deflemax = 0, deflemin = 1.e100;
981     if (!T.IsNull()) {
982       Standard_Real defstock = T->Deflection();
983       const Poly_Array1OfTriangle& triangles  = T->Triangles();
984       const TColgp_Array1OfPnt2d&  Nodes2d    = T->UVNodes();
985       const TColgp_Array1OfPnt&    Nodes      = T->Nodes();
986
987       S = BRep_Tool::Surface(F, L);
988
989       for(i = 1; i <= triangles.Length(); i++) {
990         if (F.Orientation() == TopAbs_REVERSED) 
991           triangles(i).Get(n1,n3,n2);
992         else 
993           triangles(i).Get(n1,n2,n3);
994
995         const gp_XY& xy1 = Nodes2d(n1).XY();
996         const gp_XY& xy2 = Nodes2d(n2).XY();
997         const gp_XY& xy3 = Nodes2d(n3).XY();
998
999         mi2d1.SetCoord((xy2.X()+xy3.X())*0.5, 
1000           (xy2.Y()+xy3.Y())*0.5);
1001         mi2d2.SetCoord((xy1.X()+xy3.X())*0.5, 
1002           (xy1.Y()+xy3.Y())*0.5);
1003         mi2d3.SetCoord((xy1.X()+xy2.X())*0.5, 
1004           (xy1.Y()+xy2.Y())*0.5);
1005
1006         gp_XYZ p1 = Nodes(n1).Transformed(L.Transformation()).XYZ();
1007         gp_XYZ p2 = Nodes(n2).Transformed(L.Transformation()).XYZ();
1008         gp_XYZ p3 = Nodes(n3).Transformed(L.Transformation()).XYZ();
1009
1010         vecEd1=p2-p1;
1011         vecEd2=p3-p2;
1012         vecEd3=p1-p3;
1013         d1=vecEd1.SquareModulus();
1014         d2=vecEd2.SquareModulus();
1015         d3=vecEd3.SquareModulus();
1016
1017         if (d1!=0. && d2!=0. && d3!=0.) {
1018           gp_XYZ equa(vecEd1^vecEd2);
1019           dv=equa.Modulus();
1020           if (dv>0.) {
1021             equa.SetCoord(equa.X()/dv, equa.Y()/dv, equa.Z()/dv);
1022             dipo=equa*p1;
1023
1024
1025             mitri.SetCoord(ONETHIRD*(xy1.X()+xy2.X()+xy3.X()),
1026               ONETHIRD*(xy1.Y()+xy2.Y()+xy3.Y()));
1027             v1.SetCoord(ONETHIRD*mi2d1.X()+TWOTHIRD*xy1.X(), 
1028               ONETHIRD*mi2d1.Y()+TWOTHIRD*xy1.Y());
1029             v2.SetCoord(ONETHIRD*mi2d2.X()+TWOTHIRD*xy2.X(), 
1030               ONETHIRD*mi2d2.Y()+TWOTHIRD*xy2.Y());
1031             v3.SetCoord(ONETHIRD*mi2d3.X()+TWOTHIRD*xy3.X(), 
1032               ONETHIRD*mi2d3.Y()+TWOTHIRD*xy3.Y());
1033
1034             S->D0(mi2d1.X(), mi2d1.Y(), PP);
1035             PP = PP.Transformed(L.Transformation());
1036             defle = Abs((equa*PP.XYZ())-dipo);
1037             deflemax = Max(deflemax, defle);
1038             deflemin = Min(deflemin, defle);
1039
1040             S->D0(mi2d2.X(), mi2d2.Y(), PP);
1041             PP = PP.Transformed(L.Transformation());
1042             defle = Abs((equa*PP.XYZ())-dipo);
1043             deflemax = Max(deflemax, defle);
1044             deflemin = Min(deflemin, defle);
1045
1046             S->D0(mi2d3.X(), mi2d3.Y(), PP);
1047             PP = PP.Transformed(L.Transformation());
1048             defle = Abs((equa*PP.XYZ())-dipo);
1049             deflemax = Max(deflemax, defle);
1050             deflemin = Min(deflemin, defle);
1051
1052             S->D0(v1.X(), v1.Y(), PP);
1053             PP = PP.Transformed(L.Transformation());
1054             defle = Abs((equa*PP.XYZ())-dipo);
1055             deflemax = Max(deflemax, defle);
1056             deflemin = Min(deflemin, defle);
1057
1058             S->D0(v2.X(), v2.Y(), PP);
1059             PP = PP.Transformed(L.Transformation());
1060             defle = Abs((equa*PP.XYZ())-dipo);
1061             deflemax = Max(deflemax, defle);
1062             deflemin = Min(deflemin, defle);
1063
1064             S->D0(v3.X(), v3.Y(), PP);
1065             PP = PP.Transformed(L.Transformation());
1066             defle = Abs((equa*PP.XYZ())-dipo);
1067             deflemax = Max(deflemax, defle);
1068             deflemin = Min(deflemin, defle);
1069
1070             S->D0(mitri.X(), mitri.Y(), PP);
1071             PP = PP.Transformed(L.Transformation());
1072             defle = Abs((equa*PP.XYZ())-dipo);
1073             deflemax = Max(deflemax, defle);
1074             deflemin = Min(deflemin, defle);
1075
1076             if (defle > defstock) {
1077               di <<"face "<< nbface <<" deflection = " << defle <<" pour "<<defstock <<" stockee."<<"\n";
1078             }
1079           }
1080         }
1081       }
1082       if (!quiet) {
1083         di <<"face "<< nbface<<", deflemin = "<< deflemin<<", deflemax = "<<deflemax<<"\n";
1084       }
1085
1086     }
1087   }
1088
1089
1090   return 0;
1091 }
1092
1093
1094
1095
1096 //=======================================================================
1097 //function : tri2d
1098 //purpose  : 
1099 //=======================================================================
1100
1101 Standard_Integer tri2d(Draw_Interpretor&, Standard_Integer n, const char** a)
1102 {
1103
1104   if (n != 2) return 1;
1105   TopoDS_Shape aLocalShape = DBRep::Get(a[1]);
1106   TopoDS_Face F = TopoDS::Face(aLocalShape);
1107   //  TopoDS_Face F = TopoDS::Face(DBRep::Get(a[1]));
1108   if (F.IsNull()) return 1;
1109   Handle(Poly_Triangulation) T;
1110   TopLoc_Location L;
1111
1112   T = BRep_Tool::Triangulation(F, L);
1113   if (!T.IsNull()) {
1114     // Build the connect tool
1115     Poly_Connect pc(T);
1116
1117     Standard_Integer i,j, nFree, nInternal, nbTriangles = T->NbTriangles();
1118     Standard_Integer t[3];
1119
1120     // count the free edges
1121     nFree = 0;
1122     for (i = 1; i <= nbTriangles; i++) {
1123       pc.Triangles(i,t[0],t[1],t[2]);
1124       for (j = 0; j < 3; j++)
1125         if (t[j] == 0) nFree++;
1126     }
1127
1128     // allocate the arrays
1129     TColStd_Array1OfInteger Free(1,2*nFree);
1130     nInternal = (3*nbTriangles - nFree) / 2;
1131     TColStd_Array1OfInteger Internal(0,2*nInternal);
1132
1133     Standard_Integer fr = 1, in = 1;
1134     const Poly_Array1OfTriangle& triangles = T->Triangles();
1135     Standard_Integer nodes[3];
1136     for (i = 1; i <= nbTriangles; i++) {
1137       pc.Triangles(i,t[0],t[1],t[2]);
1138       triangles(i).Get(nodes[0],nodes[1],nodes[2]);
1139       for (j = 0; j < 3; j++) {
1140         Standard_Integer k = (j+1) % 3;
1141         if (t[j] == 0) {
1142           Free(fr)   = nodes[j];
1143           Free(fr+1) = nodes[k];
1144           fr += 2;
1145         }
1146         // internal edge if this triangle has a lower index than the adjacent
1147         else if (i < t[j]) {
1148           Internal(in)   = nodes[j];
1149           Internal(in+1) = nodes[k];
1150           in += 2;
1151         }
1152       }
1153     }
1154
1155     // Display the edges
1156     if (T->HasUVNodes()) {
1157       const TColgp_Array1OfPnt2d& Nodes2d = T->UVNodes();
1158
1159       Handle(Draw_Segment2D) Seg;
1160
1161       // free edges
1162       Standard_Integer nn;
1163       nn = Free.Length() / 2;
1164       for (i = 1; i <= nn; i++) {
1165         Seg = new Draw_Segment2D(Nodes2d(Free(2*i-1)),
1166           Nodes2d(Free(2*i)),
1167           Draw_rouge);
1168         dout << Seg;
1169       }
1170
1171       // internal edges
1172
1173       nn = nInternal;
1174       for (i = 1; i <= nn; i++) {
1175         Seg = new Draw_Segment2D(Nodes2d(Internal(2*i-1)),
1176           Nodes2d(Internal(2*i)),
1177           Draw_bleu);
1178         dout << Seg;
1179       }
1180     }
1181     dout.Flush();
1182   }
1183
1184   return 0;
1185 }
1186
1187
1188
1189
1190 //=======================================================================
1191 //function : wavefront
1192 //purpose  : 
1193 //=======================================================================
1194
1195 static Standard_Integer wavefront(Draw_Interpretor&, Standard_Integer nbarg, const char** argv)
1196 {
1197   if (nbarg < 2) return 1;
1198
1199   TopoDS_Shape S = DBRep::Get(argv[1]);
1200   if (S.IsNull()) return 1;
1201
1202   // creation du maillage s'il n'existe pas.
1203
1204   Bnd_Box B;
1205   Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1206   BRepBndLib::Add(S, B);
1207   B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1208   Standard_Real aDeflection = 
1209     MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin) * 0.004;
1210
1211   BRepMesh_IncrementalMesh aMesh (S, aDeflection);
1212
1213
1214   TopLoc_Location L;
1215   TopExp_Explorer ex;
1216
1217   Standard_Integer i, nbface = 0;
1218   Standard_Boolean OK = Standard_True;
1219   gp_Vec D1U,D1V;
1220   gp_Vec D2U,D2V,D2UV;
1221   gp_Dir Nor;
1222   gp_Pnt P;
1223   Standard_Real U, V;
1224   CSLib_DerivativeStatus Status;
1225   CSLib_NormalStatus NStat;
1226   Standard_Real x, y, z;
1227   Standard_Integer n1, n2, n3;
1228   Standard_Integer k1, k2, k3;
1229
1230   char ffile[100];
1231
1232   if (nbarg == 3) {
1233     strcpy(ffile, argv[2]);
1234     strcat(ffile, ".obj");
1235   }
1236   else  strcpy(ffile, "wave.obj");
1237   FILE* outfile = fopen(ffile, "w");
1238
1239
1240   fprintf(outfile, "%s  %s\n%s %s\n\n", "# CASCADE   ","MATRA DATAVISION", "#", ffile);
1241
1242   Standard_Integer nbNodes, totalnodes = 0, nbpolygons = 0;
1243   for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next()) {
1244     nbface++;
1245     TopoDS_Face F = TopoDS::Face(ex.Current());
1246     Handle(Poly_Triangulation) Tr = BRep_Tool::Triangulation(F, L);
1247
1248     if (!Tr.IsNull()) {
1249       nbNodes = Tr->NbNodes();
1250       const TColgp_Array1OfPnt& Nodes = Tr->Nodes();
1251
1252       // les noeuds.
1253       for (i = 1; i <= nbNodes; i++) {
1254         gp_Pnt Pnt = Nodes(i).Transformed(L.Transformation());
1255         x = Pnt.X();
1256         y = Pnt.Y();
1257         z = Pnt.Z();
1258         fprintf(outfile, "%s      %f  %f  %f\n", "v", x, y, z);
1259       }
1260
1261       fprintf(outfile, "\n%s    %d\n\n", "# number of vertex", nbNodes);
1262
1263
1264       // les normales.
1265
1266       if (Tr->HasUVNodes()) {
1267         const TColgp_Array1OfPnt2d& UVNodes = Tr->UVNodes();
1268         BRepAdaptor_Surface BS(F, Standard_False);
1269
1270         for (i = 1; i <= nbNodes; i++) {
1271           U = UVNodes(i).X();
1272           V = UVNodes(i).Y();
1273
1274           BS.D1(U,V,P,D1U,D1V);
1275           CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor);
1276           if (Status != CSLib_Done) {
1277             BS.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
1278             CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor);
1279           }
1280           if (F.Orientation() == TopAbs_REVERSED) Nor.Reverse();
1281
1282           fprintf(outfile, "%s      %f  %f  %f\n", "vn", Nor.X(), Nor.Y(), Nor.Z());
1283         }
1284
1285         fprintf(outfile, "\n%s    %d\n\n", "# number of vertex normals", nbNodes);
1286       }
1287
1288       fprintf(outfile, "%s    %d\n", "s", nbface);
1289
1290       // les triangles.
1291       Standard_Integer nbTriangles = Tr->NbTriangles();
1292       const Poly_Array1OfTriangle& triangles = Tr->Triangles();
1293
1294
1295       for (i = 1; i <= nbTriangles; i++) {
1296         if (F.Orientation()  == TopAbs_REVERSED)
1297           triangles(i).Get(n1, n3, n2);
1298         else 
1299           triangles(i).Get(n1, n2, n3);
1300         k1 = n1+totalnodes;
1301         k2 = n2+totalnodes;
1302         k3 = n3+totalnodes;
1303         fprintf(outfile, "%s %d%s%d %d%s%d %d%s%d\n", "fo", k1,"//", k1, k2,"//", k2, k3,"//", k3);
1304       }
1305       nbpolygons += nbTriangles;
1306       totalnodes += nbNodes;
1307
1308       fprintf(outfile, "\n%s    %d\n", "# number of smooth groups", nbface);
1309       fprintf(outfile, "\n%s    %d\n", "# number of polygons", nbpolygons);
1310
1311     }
1312   }
1313
1314   fclose(outfile);
1315
1316   return 0;
1317 }
1318
1319
1320 //=======================================================================
1321 //function : onetriangulation
1322 //purpose  : 
1323 //=======================================================================
1324
1325 Standard_Integer onetriangulation(Draw_Interpretor&, Standard_Integer /*nbarg*/, const char** /*argv*/)
1326 {
1327
1328   /*
1329
1330   if (nbarg < 2) return 1;
1331
1332   TopoDS_Shape S = DBRep::Get(argv[1]);
1333   if (S.IsNull()) return 1;
1334
1335   Handle(Poly_Triangulation) TFinale;
1336   char name[100];
1337   Standard_Integer nbshell = 0;
1338
1339   TopExp_Explorer ex, exs, ex2;
1340
1341   for (ex.Init(S, TopAbs_SHELL); ex.More(); ex.Next()) {
1342   nbshell++;
1343   TopoDS_Shell Sh = TopoDS::Shell(ex.Current());
1344
1345   for (exs.Init(Sh, TopAbs_Face); exs.More(); exs.Next()) {
1346   TopoDS_Face F = TopoDS::Face(exs.Current());
1347   Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L);
1348
1349   for (ex2.Init(F, TopAbs_EDGE); ex2.More(); ex2.Next()) {
1350   TopoDS_Edge edge = TopoDS::Edge(ex2.Current());
1351   const TColgp_Array1OfPnt& Nodes = T->Nodes();
1352   const Poly_Array1OfTriangle& triangles = T->Triangles();
1353
1354   if (mapedges.IsBound(edge)) {
1355   const TColStd_ListOfTransient& L = edges.Find(edge);
1356   const Handle(Poly_PolygonOnTriangulation)& P = 
1357   *(Handle(Poly_PolygonOnTriangulation)*)&(L.First());
1358   const TColStd_Array1OfInteger& NOD = P->Nodes();
1359
1360   }
1361   }
1362   }
1363
1364   Sprintf(name, "%s_%i", "tr", nbshell);
1365   DrawTrSurf::Set(name, TFinale);
1366
1367   }
1368
1369   */
1370   return 0;
1371 }
1372
1373
1374 #if 0
1375
1376 //=======================================================================
1377 //function : vb
1378 //purpose  : 
1379 //=======================================================================
1380
1381 Standard_Integer vb(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
1382 {
1383   Standard_Integer NbPoints = 1, Deg = 1;
1384
1385   for (Deg = 1; Deg <= 25; Deg++) {
1386     for (NbPoints = 1; NbPoints <= 24; NbPoints++) {
1387
1388       math_Vector GaussP(1, NbPoints), GaussW(1, NbPoints);
1389       math_Vector TheWeights(1, NbPoints), VBParam(1, NbPoints);
1390       math_Matrix VB(1, Deg+1, 1, NbPoints);
1391
1392       math::GaussPoints(NbPoints, GaussP);
1393
1394       Standard_Integer i, j, classe = Deg+1, cl1 = Deg;
1395
1396       // calcul et mise en ordre des parametres et des poids:
1397       for (i = 1; i <= NbPoints; i++) {
1398         if (i <=  (NbPoints+1)/2) {
1399           VBParam(NbPoints-i+1)  = 0.5*(1 + GaussP(i));
1400         }
1401         else {
1402           VBParam(i-(NbPoints+1)/2)  = 0.5*(1 + GaussP(i));
1403         }
1404       }
1405
1406
1407       // Calcul du VB (Valeur des fonctions de Bernstein):
1408       for (i = 1; i <= classe; i++) {
1409         for (j = 1; j <= NbPoints; j++) {
1410           VB(i,j)=PLib::Binomial(cl1,i-1)*Pow((1-VBParam(j)),classe-i)*Pow(VBParam(j),i-1);
1411         }
1412       }
1413
1414
1415       for (i = 1; i <= classe; i++) {
1416         for (j = 1; j <= NbPoints; j++) {
1417           di<< VB(i, j) << ", ";
1418         }
1419       }
1420       di << "\n" << "\n";
1421     }
1422   }
1423   return 0;
1424 }  
1425 //=======================================================================
1426 //function : extrema
1427 //purpose  : 
1428 //=======================================================================
1429
1430 Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
1431 {
1432
1433
1434   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(argv[1]);
1435
1436   Standard_Real X, Y, Z, U0;
1437   X = Draw::Atof(argv[2]);
1438   Y = Draw::Atof(argv[3]);
1439   Z = Draw::Atof(argv[4]);
1440   U0 = Draw::Atof(argv[5]);
1441
1442   gp_Pnt P(X, Y, Z);
1443   GeomAdaptor_Curve GC(C);
1444   Standard_Real tol = 1.e-09;
1445   Extrema_LocateExtPC ext(P, GC, U0, tol);
1446
1447   if (ext.IsDone()) {
1448     gp_Pnt P1 = ext.Point().Value();
1449     di <<"distance =  "<<ext.Value() << "\n";
1450     di <<"point =     "<<P1.X()<<" "<<P1.Y()<<" "<< P1.Z()<< "\n";
1451     di <<"parametre = "<<ext.Point().Parameter()<<"\n";
1452   }
1453
1454   return 0;
1455 }
1456
1457 #endif
1458
1459
1460 //=======================================================================
1461 //function : triedgepoints
1462 //purpose  : 
1463 //=======================================================================
1464
1465 Standard_Integer triedgepoints(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
1466 {
1467   if( nbarg < 2 )
1468     return 1;
1469
1470   for( Standard_Integer i = 1; i < nbarg; i++ )
1471   {
1472     TopoDS_Shape aShape = DBRep::Get(argv[i]);
1473     if ( aShape.IsNull() )
1474       continue;
1475
1476     Handle(Poly_PolygonOnTriangulation) aPoly;
1477     Handle(Poly_Triangulation)          aT;
1478     TopLoc_Location                     aLoc;
1479     TopTools_MapOfShape                 anEdgeMap;
1480     TopTools_MapIteratorOfMapOfShape    it;
1481     
1482     if( aShape.ShapeType() == TopAbs_EDGE )
1483     {
1484       anEdgeMap.Add( aShape );
1485     }
1486     else
1487     {
1488       TopExp_Explorer ex(aShape, TopAbs_EDGE);
1489       for(; ex.More(); ex.Next() )
1490         anEdgeMap.Add( ex.Current() );
1491     }
1492
1493     if ( anEdgeMap.Extent() == 0 )
1494       continue;
1495
1496     char newname[1024];
1497     strcpy(newname,argv[i]);
1498     char* p = newname;
1499     while (*p != '\0') p++;
1500     *p = '_';
1501     p++;
1502
1503     Standard_Integer nbEdge = 1;
1504     for(it.Initialize(anEdgeMap); it.More(); it.Next())
1505     {
1506       BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(it.Key()), aPoly, aT, aLoc);
1507       if ( aT.IsNull() || aPoly.IsNull() )
1508         continue;
1509       
1510       const TColgp_Array1OfPnt&      Nodes   = aT->Nodes();
1511       const TColStd_Array1OfInteger& Indices = aPoly->Nodes();
1512       const Standard_Integer         nbnodes = Indices.Length();
1513
1514       for( Standard_Integer j = 1; j <= nbnodes; j++ )
1515       {
1516         gp_Pnt P3d = Nodes(Indices(j));
1517         if( !aLoc.IsIdentity() )
1518           P3d.Transform(aLoc.Transformation());
1519
1520         if( anEdgeMap.Extent() > 1 )
1521           Sprintf(p,"%d_%d",nbEdge,j);
1522         else
1523           Sprintf(p,"%d",j);
1524               DBRep::Set( newname, BRepBuilderAPI_MakeVertex(P3d) );
1525               di.AppendElement(newname);
1526       }
1527       nbEdge++;
1528     }
1529   }
1530   return 0;
1531 }
1532
1533 //=======================================================================
1534 void  MeshTest::Commands(Draw_Interpretor& theCommands)
1535 //=======================================================================
1536 {
1537   Draw::Commands(theCommands);
1538   BRepTest::AllCommands(theCommands);
1539   GeometryTest::AllCommands(theCommands);
1540   MeshTest::PluginCommands(theCommands);
1541   const char* g;
1542
1543   g = "Mesh Commands";
1544
1545   theCommands.Add("incmesh","incmesh shape deflection [inParallel (0/1) : 0 by default]",__FILE__, incrementalmesh, g);
1546   theCommands.Add("MemLeakTest","MemLeakTest",__FILE__, MemLeakTest, g);
1547   theCommands.Add("fastdiscret","fastdiscret shape deflection [shared [nbiter]]",__FILE__, fastdiscret, g);
1548   theCommands.Add("mesh","mesh result Shape deflection",__FILE__, triangule, g);
1549   theCommands.Add("addshape","addshape meshname Shape [deflection]",__FILE__, addshape, g);
1550   //theCommands.Add("smooth","smooth meshname",__FILE__, smooth, g);
1551   //theCommands.Add("edges","edges mesh shape, highlight the edges",__FILE__,edges, g);
1552   theCommands.Add("vertices","vertices mesh shape, highlight the vertices",__FILE__,vertices, g);
1553   theCommands.Add("medge","medge mesh [-]index (0 to clear all)",__FILE__,medge, g);
1554   theCommands.Add("mvertex","mvertex mesh [-]index (0 to clear all)",__FILE__,mvertex, g);
1555   theCommands.Add("triangle","triangle mesh [-]index (0 to clear all)",__FILE__,triangle, g);
1556   //theCommands.Add("dumpvertex","dumpvertex mesh [index]",__FILE__,dumpvertex, g);
1557   //theCommands.Add("dumpedge","dumpedge mesh [index]",__FILE__,dumpedge, g);
1558   //theCommands.Add("dumptriangle","dumptriangle mesh [index]",__FILE__,dumptriangle, g);
1559
1560   theCommands.Add("tri2d", "tri2d facename",__FILE__, tri2d, g);
1561   theCommands.Add("trinfo","trinfo name, print triangles information on objects",__FILE__,trianglesinfo,g);
1562   theCommands.Add("veriftriangles","veriftriangles name, verif triangles",__FILE__,veriftriangles,g);
1563   theCommands.Add("wavefront","wavefront name",__FILE__, wavefront, g);
1564   theCommands.Add("onetriangulation","onetriangulation name",__FILE__, onetriangulation, g);
1565   theCommands.Add("triepoints", "triepoints shape1 [shape2 ...]",__FILE__, triedgepoints, g);
1566
1567 #if 0
1568   theCommands.Add("extrema","extrema ",__FILE__, extrema, g);
1569   theCommands.Add("vb","vb ",__FILE__, vb, g);
1570 #endif
1571 }