0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / SWDRAW / SWDRAW_ShapeFix.cxx
1 // Created on: 1999-03-09
2 // Created by: data exchange team
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 #include <SWDRAW_ShapeFix.ixx>
22
23 #include <Draw.hxx>
24 #include <DBRep.hxx>
25 #include <SWDRAW.hxx>
26 #include <gp_XYZ.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <TopoDS.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Wire.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <TopExp_Explorer.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRep_Builder.hxx>
37 #include <BRepBuilderAPI.hxx>
38 #include <BRepTopAdaptor_FClass2d.hxx>
39
40 #include <ShapeBuild_ReShape.hxx>
41 #include <ShapeAnalysis_Edge.hxx>
42 #include <ShapeAnalysis_WireOrder.hxx>
43 #include <ShapeAnalysis_WireVertex.hxx>
44 #include <ShapeAnalysis_Wire.hxx>
45 #include <ShapeExtend_WireData.hxx>
46 #include <ShapeFix.hxx>
47 #include <ShapeFix_ShapeTolerance.hxx>
48 #include <ShapeFix_Wire.hxx>
49 #include <ShapeFix_WireVertex.hxx>
50 #include <ShapeFix_Wireframe.hxx>
51 #include <ShapeFix_Face.hxx>
52 #include <ShapeFix_Shape.hxx>
53 #include <Precision.hxx>
54 #include <ShapeExtend_DataMapOfShapeListOfMsg.hxx>
55 #include <ShapeExtend_MsgRegistrator.hxx>
56 #include <ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg.hxx>
57 #include <Message_ListIteratorOfListOfMsg.hxx>
58 #include <Message_Msg.hxx>
59 #include <TCollection_AsciiString.hxx>
60 #include <TColStd_DataMapIteratorOfDataMapOfAsciiStringInteger.hxx>
61 #include <TColStd_DataMapOfAsciiStringInteger.hxx>
62 #include <TopTools_MapOfShape.hxx>
63 #include <TopTools_DataMapOfShapeListOfShape.hxx>
64 #include <TopAbs_State.hxx>
65
66 #include <Draw_ProgressIndicator.hxx>
67 #include <ShapeAnalysis_FreeBounds.hxx>
68 #include <TopTools_HSequenceOfShape.hxx>
69 #include <BRep_Builder.hxx>
70 #include <TopTools_IndexedMapOfShape.hxx>
71 #include <TopExp.hxx>
72
73 #ifdef AIX
74 #include <strings.h>
75 #endif
76 #include <stdio.h>
77 #include <ShapeExtend_WireData.hxx>
78
79 //=======================================================================
80 //function : edgesameparam
81 //purpose  : 
82 //=======================================================================
83
84 static Standard_Integer edgesameparam (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
85 {
86 //  const Standard_CString arg1 = argv[1];
87   const Standard_CString arg2 (argc > 2 ? argv[2] : NULL);
88 //        ****    Edge:SameParameter         ****
89   if (argc < 2) { di<<"shapename ,  option f to force, else only Edges not-SameParameter are computed"<<"\n"; return 1 /* Error */; }
90   TopoDS_Shape Shape = DBRep::Get(argv[1]);
91
92   if (!ShapeFix::SameParameter(Shape, (argc > 2 && arg2[0] == 'f') , BRepBuilderAPI::Precision()) )
93     di<<"Some edges were not processed"<<"\n";
94   di<<"\n";
95   return 0; // Done
96 }
97
98 //=======================================================================
99 //function : settolerance
100 //purpose  : 
101 //=======================================================================
102
103 static Standard_Integer settolerance (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
104 {
105   if (argc < 3) {
106     di<<    "myshape val   : forces tolerances at <val>"<<"\n"
107       <<      "myshape < max : sets maximum tolerance to <max>"<<"\n"
108         <<    "myshape > min : sets minimum tolerance to <min>"<<"\n"
109           <<  "myshape min max : bounds tolerances between <min> and <max>"<<"\n"
110             <<"myshape mode=v-e-f other args : idem but only on vertex-edge-face"<<"\n";
111     return (argc < 2 ? 0 : 1 /* Error */);
112   }
113   Standard_CString arg1 = argv[1];
114   Standard_CString arg2 = argv[2];
115   TopoDS_Shape Shape = DBRep::Get(arg1);
116   if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
117   char mod2 = arg2[0];
118   Standard_Integer premarg = 2;
119   TopAbs_ShapeEnum styp = TopAbs_SHAPE;
120   if (mod2 == 'v') { styp = TopAbs_VERTEX; premarg = 3; }
121   if (mod2 == 'e') { styp = TopAbs_EDGE;   premarg = 3; }
122   if (mod2 == 'w') { styp = TopAbs_WIRE;   premarg = 3; }
123   if (mod2 == 'f') { styp = TopAbs_FACE;   premarg = 3; }
124   if (mod2 == 'a') { styp = TopAbs_SHAPE;  premarg = 3; }
125
126   Standard_Real tmin,tmax;
127   mod2 = argv[premarg][0];
128   if (mod2 == '=') tmin = tmax = Draw::Atof (argv[argc-1]);
129   else if (mod2 == '<') { tmin = 0; tmax = Draw::Atof (argv[argc-1]); }
130   else if (mod2 == '>') { tmin = Draw::Atof (argv[argc-1]); tmax = 0; }
131   else { tmin = Draw::Atof (argv[premarg]);  tmax = Draw::Atof (argv[argc-1]); }
132
133   if (argc == premarg + 1 || tmin == tmax) di<<"Setting Tolerance to "<<tmin<<"\n";
134   else if (tmax < tmin) di<<"Minimum Tolerance to "<<tmin<<"\n";
135   else if (tmin <= 0)   di<<"Maximum Tolerance to "<<tmax<<"\n";
136   else                  di<<"Tolerance Limited between "<<tmin<<" and "<<tmax<<"\n";
137   ShapeFix_ShapeTolerance sat;
138   sat.LimitTolerance (Shape,tmin,tmax,styp);
139   return 0; // Done
140 }
141
142 //=======================================================================
143 //function : stwire
144 //purpose  : 
145 //=======================================================================
146
147 static Standard_Integer stwire (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
148 {
149   if (argc < 2) { // help
150     di<<"Donner nom shape depart + nom shape resultat + option"<<"\n";
151     di<<"Options de chargement :  x add connected  (sinon add simple)\n"
152       <<  "Options de traitement :  l fix little/BRepBuilderAPI\n"
153       <<"Options de sortie : aucune make simple\n"
154       <<"  m MakeAPI r avec reorder  v vertex\n"
155       <<"Autres (se cumulent) :  q quid(stats)"<<"\n";
156     return 0;
157   }
158   if (argc < 4) { di<<"stwire tout court pour help"<<"\n"; return 1 /* Error */; }
159   Standard_CString arg1 = argv[1];
160   Standard_CString arg2 = argv[2];
161
162 //  Options
163   Standard_Integer i;  int ox,ol,om,orint,oq,ov;  ox=ol=om=orint=oq=ov=0;
164   for (i = 3; i < argc; i ++) {
165     int valopt = 1;
166     char opt = argv[i][0];
167     if (opt == '+')   opt = argv[i][1];
168     if (opt == '-') { opt = argv[i][1]; valopt = 0; }
169     switch (opt) {
170     case 'l' : ol = valopt; break;
171     case 'm' : om = valopt; break;
172     case 'q' : oq = valopt; break;
173     case 'r' : orint = valopt; break;
174     case 'v' : ov = valopt; break;
175     case 'x' : ox = valopt; break;
176     default : break;
177     }
178   }
179   TopoDS_Shape Shape = DBRep::Get(arg1);
180   if (Shape.IsNull()) { di<<arg1<<" inconnu"<<"\n"; return 1 /* Error */; }
181
182 //  On y va
183   Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData;
184   Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
185   saw->Load ( sbwd );
186   
187   TopoDS_Shape awire;  // en principe un Wire
188   if (Shape.ShapeType() == TopAbs_WIRE) {
189     awire = Shape;
190   } else if (Shape.ShapeType() == TopAbs_FACE) {
191     saw->SetFace (TopoDS::Face(Shape));
192     TopExp_Explorer expw(Shape,TopAbs_WIRE);
193     if (expw.More()) awire = expw.Current();
194     saw->SetPrecision (BRepBuilderAPI::Precision());
195   }
196   if (awire.IsNull()) {
197     di<<"Neither FACE nor WIRE : "<<arg1<<"\n";
198     di<<"Considering as list of edges ..."<<"\n";
199     awire = Shape;
200 //    return 1 /* Error */;
201   }
202
203 // Chargement : normal ou par connected(oriented)
204 //  if (ox) {
205     for (TopExp_Explorer exp(Shape,TopAbs_EDGE); exp.More(); exp.Next()) {
206       TopoDS_Edge E = TopoDS::Edge (exp.Current());
207       Standard_Integer orient = saw->CheckShapeConnect (E);
208       di<<"Orientation : "<<orient<<" LowerDist : "<< saw->MinDistance3d() << "\n";
209       if (ox) sbwd->AddOriented (E,orient);
210       else sbwd->Add (E);
211     }
212 //  }
213 //  else sbwd->Init (awire);
214   
215   Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
216   sfw->Init ( saw );
217
218 //   Traitement en cours
219   if (ol) {
220     Standard_Integer nb = sfw->NbEdges();
221     for (i = 1; i <= nb; i ++) {
222       Standard_Boolean stat = sfw->FixSmall (i, Standard_True, 0.0);
223       //cout<<"FixSmall for"<<i<<(stat ? " done" : " not done"); //:sw <<" StatusFix="<<STW.StatusFix()<<"\n";
224       di<<"FixSmall for"<<i;
225       if (!stat) {
226         di<<" not done";
227       } else {
228         di<<" done";
229       }
230       if ( sfw->LastFixStatus ( ShapeExtend_FAIL ) ) di << " (failed)";
231       di << "\n";
232     }
233   }
234
235 //  Traitement
236   if (orint) {  // reorder ?
237     ShapeAnalysis_WireOrder WO ( (Shape.ShapeType() != TopAbs_FACE), BRepBuilderAPI::Precision());
238
239     Standard_Integer stwo = saw->CheckOrder (WO);
240     Standard_Integer nb = WO.NbEdges();
241     di<<"Reorder status : "<<stwo<<"  NbEdges="<<nb<<"\n";
242     for (i = 1; i <= nb; i ++) {
243       Standard_Integer iord = WO.Ordered(i);
244       di<<"Edge n0 "<<i;
245       if ( sbwd->Edge(iord).Orientation() == TopAbs_REVERSED) di<<" REV";
246       else di<<" FWD";
247       di<<" ordered to "<<iord<<" Gap="<<WO.Gap(i)<<"\n";
248     }
249     di<<"Reorder not yet done"<<"\n";
250     sfw->FixReorder (WO);
251 //   Mais on n execute pas
252   }
253
254 //  Statistiques
255   if (oq) {
256     ShapeAnalysis_Edge sae;
257     Standard_Integer nb = sbwd->NbEdges();
258     di<<"NbEdges : "<<nb<<"\n";
259     for (i = 1; i <= nb; i ++) {
260       TopoDS_Edge E = sbwd->Edge(i);
261       di<<"Edge "<<i;
262       if (E.Orientation() == TopAbs_REVERSED) di<<" REV";
263       else di<<" FWD";
264       if (BRep_Tool::Degenerated(E)) di<<" DGNR";
265       if (sbwd->IsSeam(i))        di<<" SEAM_WIRE";
266       if (Shape.ShapeType() == TopAbs_FACE &&
267           sae.IsSeam(E,TopoDS::Face(Shape)))  di<<" SEAM_FACE";
268       if (Shape.ShapeType() == TopAbs_FACE ) {
269         if (sae.HasPCurve(E,TopoDS::Face(Shape)))     di<<" PCU";
270         else di<<" NO_PCU";
271       }
272       if (sae.HasCurve3d(E))    di<<" C3D";
273       else di<<" NO_C3D";
274       if (sae.IsClosed3d(E))  di<<" CLOSED";
275       di<<"\n";
276     }
277   }
278
279 //  Resultat
280   TopoDS_Wire result;
281   if (ov) {
282     ShapeAnalysis_WireVertex sawv;
283     sawv.Init ( sbwd, saw->Precision() );
284     sawv.Analyze();
285     Standard_Integer nb = sbwd->NbEdges();
286     di<<"Nb(End)Vertex : "<<nb<<"\n";
287     for (i = 1; i <= nb; i ++) {
288       gp_XYZ pos; Standard_Real upre,ufol;
289       Standard_Integer stat = sawv.Data (i,pos,upre,ufol);
290       di<<i<<" : ";
291       switch (stat) {
292       case 0 : di<<"Same Vertex"<<"\n"; break;
293       case 1 : di<<"Same Coords with recorded precisions (but not Same Vertex)"<<"\n"; break;
294       case 2 : di<<"Close (with preci="<< saw->Precision()<<")"<<"\n"; break;
295       case 3 : di<<"End of "<<i<<" OK, Start of "<<(i == nb ? 1 : i+1)<<" at U="<<ufol; break;
296       case 4 : di<<"End of "<<i<<" at U="<<upre<<", Start of "<<(i == nb ? 1 : i+1)<<" OK"; break;
297       case 5 : di<<"Intersection, End of "<<i<<" at U="<<upre<<", Start of "<<(i == nb ? 1 : i+1)<<" at U="<<ufol; break;
298         default : di<<"Disjoined"<<"\n";
299       }
300       if (stat >= 3 && stat <= 5) di<<"\n   - Position : "<<pos.X()<<"  "<<pos.Y()<<"  "<<pos.Z()<<"\n";
301     }
302     ShapeFix_WireVertex sfwv;
303     sfwv.Init ( sawv );
304     di<<"Nb Fixed Vertex : "<< sfwv.Fix() <<"\n";
305   }
306   /*
307   if (oc) {
308     if ( Shape.ShapeType() == TopAbs_FACE ) {
309       Correct_Wire CW ( TopoDS::Face(Shape) );
310       Standard_Integer i, nb = sbwd->NbEdges();
311       Standard_Integer num = 1;
312       for (i = 1; i <= nb; i ++)  CW.Add (sbwd->Edge(i));
313       CW.Perform ( saw->Precision() );
314       nb = CW.NbWires();
315       if (nb != 1) {
316         //  On prend celui qui a le plus d edges
317         Standard_Integer nbe, maxe = 0;
318         for (i = 1; i <= nb; i ++) {
319           TopoDS_Wire wir = CW.Wire(i);
320           nbe = 0;
321           for (TopoDS_Iterator ite(wir); ite.More(); ite.Next()) nbe ++;
322           if (nbe > maxe) { num = i; maxe = nbe; }
323         }
324         di<<"Correct_Wire produced "<<nb<<" Wires, taken n0 "<<num<<"\n";
325       }
326       result = CW.Wire (num);
327     }
328     else di << "Cannot apply Correct_Wire: face not defined" << "\n";
329   }
330   */
331   else if (om) result = sbwd->WireAPIMake();
332   else         result = sbwd->Wire();
333   if (result.IsNull()) {
334     di<<"Pas de resultat, desole"<<"\n";
335     return 1;  // Fail
336   }
337   DBRep::Set (arg2,result);
338   return 0; // Done
339 }
340
341 //=======================================================================
342 //function : reface
343 //purpose  : 
344 //=======================================================================
345
346 static Standard_Integer reface (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
347 {
348   if (argc < 3) { di<<"Donner un nom de SHAPE (SHELL ou FACE) + un nom de RESULTAT"<<"\n"; return 1 /* Error */; }
349   Standard_CString arg1 = argv[1];
350   Standard_CString arg2 = argv[2];
351   TopoDS_Shape Shape = DBRep::Get(arg1);
352   if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
353
354   Standard_Boolean rebuild = Standard_False;
355
356   Handle(ShapeFix_Face) STF = new ShapeFix_Face;
357 //  Options ?
358   Standard_Integer i; // svv Jan11 2000 : porting on DEC
359   for (i = 3; i < argc; i ++) {
360     Standard_Boolean valopt = Standard_True;
361     char opt = argv[i][0];
362     if (opt == '+')   opt = argv[i][1];
363     if (opt == '-') { opt = argv[i][1]; valopt = Standard_False; }
364     //cout<<(valopt ? ".." : ".. NO");
365     if (!valopt) {
366       di<<".. NO";
367     } else {
368       di<<"..";
369     }
370
371     if (opt == 'R') { di<<" REBUILD-ANYWAY .."; rebuild = valopt; }
372     if (opt == 'd') { di<<" fix-dgnr .."; STF->FixWireTool()->FixDegeneratedMode() = valopt; }
373     if (opt == 'r') { di<<" fix-reorder-wire .."; STF->FixWireTool()->FixReorderMode()    = valopt; }
374     if (opt == 'k') {
375     }
376   }
377
378   TopoDS_Face  face;
379   ShapeBuild_ReShape resh;
380
381   Standard_Integer nbf = 0, nbfc = 0;
382   for (TopExp_Explorer EF (Shape,TopAbs_FACE); EF.More(); EF.Next()) {
383     TopoDS_Face F = TopoDS::Face (EF.Current());    face = F;
384     nbf ++;
385     Standard_Boolean newface = Standard_False;
386 //    on va voir si ShapeTool_Face trouve qqchose a redire
387 //:sw    ShapeTool_Wire STW;
388 //:sw    STW.SetFace (F);
389
390     STF->Init (F);  // qui fait tout
391     STF->Perform();
392     face = STF->Face();
393     newface = STF->Status(ShapeExtend_DONE) || rebuild;
394     if (newface) { nbfc ++; resh.Replace (F,face); }
395   }
396   if (nbfc > 0) {
397     di<<"Faces reprises par ShapeFix_Face : "<<nbfc<<"\n";
398     DBRep::Set (arg2,resh.Apply (Shape,TopAbs_FACE,2));
399     return 0; // Done
400   }
401   else di<<"ShapeFix_Face n a rien trouve a redire"<<"\n";
402   return 0;
403 }
404
405
406 //=======================================================================
407 //function : fixshape
408 //purpose  : 
409 //=======================================================================
410
411 static Standard_Integer fixshape (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
412 {
413   Handle(ShapeExtend_MsgRegistrator) msg = new ShapeExtend_MsgRegistrator;
414   Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
415   sfs->SetMsgRegistrator ( msg );
416   
417   Standard_CString res = 0;
418   Standard_Integer par = 0, mess=0;
419   for ( Standard_Integer i=1; i < argc; i++ ) {
420     if ( argv[i][0] == '-' || argv[i][0] == '+' || argv[i][0] == '*' ) {
421       Standard_Integer val = ( argv[i][0] == '-' ? 0 : argv[i][0] == '+' ? 1 : -1 );
422       switch ( argv[i][1] ) {
423       case 'l': sfs->FixWireTool()->FixLackingMode()          = val; break;
424       case 'o': sfs->FixFaceTool()->FixOrientationMode()      = val; break;
425       case 'h': sfs->FixWireTool()->FixShiftedMode()          = val; break;
426       case 'm': sfs->FixFaceTool()->FixMissingSeamMode()      = val; break;
427       case 'd': sfs->FixWireTool()->FixDegeneratedMode()      = val; break;
428       case 's': sfs->FixWireTool()->FixSmallMode()            = val; break;
429       case 'i': sfs->FixWireTool()->FixSelfIntersectionMode() = val; break;
430       case 'n': sfs->FixWireTool()->FixNotchedEdgesMode()     = val; break;
431       case '?': mess                                          = val; break;
432       }
433       continue;
434     }
435     else {
436       switch ( par ) {
437       case 0: res = argv[i];                       break;
438       case 1: {
439         TopoDS_Shape initShape =  DBRep::Get(argv[i]);
440         if(initShape.IsNull()) continue;
441         sfs->Init ( initShape );
442       } break;
443       case 2: sfs->SetPrecision   (Draw::Atof(argv[i])); break;
444       case 3: sfs->SetMaxTolerance(Draw::Atof(argv[i])); break;
445       }
446     }
447     par++;
448   }
449
450   if ( par <2 ) {
451     di << "Use: " << argv[0] << " result shape [tolerance [max_tolerance]] [switches]" << "\n"; 
452     di << "Switches allow to tune parameters of ShapeFix" << "\n"; 
453     di << "The following syntax is used: <symbol><parameter>" << "\n"; 
454     di << "- symbol may be - to set parameter off, + to set on or * to set default" << "\n"; 
455     di << "- parameters are identified by letters:" << "\n"; 
456     di << "  l - FixLackingMode" << "\n"; 
457     di << "  o - FixOrientationMode" << "\n"; 
458     di << "  h - FixShiftedMode" << "\n"; 
459     di << "  m - FixMissingSeamMode" << "\n"; 
460     di << "  d - FixDegeneratedMode" << "\n"; 
461     di << "  s - FixSmallMode" << "\n"; 
462     di << "  i - FixSelfIntersectionMode" << "\n"; 
463     di << "  n - FixNotchedEdgesMode" << "\n"; 
464     di << "For enhanced message output, use switch '+?'" << "\n"; 
465     return 1;
466   }
467
468   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
469   sfs->Perform (aProgress);
470   DBRep::Set (res,sfs->Shape());
471
472   if ( mess ) 
473   {
474     TColStd_DataMapOfAsciiStringInteger aMapOfNumberOfFixes;
475     Standard_SStream aSStream;
476     TopoDS_Compound aCompound;
477     BRep_Builder aBuilder;
478     aBuilder.MakeCompound (aCompound);
479     const ShapeExtend_DataMapOfShapeListOfMsg &map = msg->MapShape();
480     // Counting the number of each type of fixes. If the switch '*?' store all modified shapes in compound.
481     for ( ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg it ( map ); it.More(); it.Next() )
482     {
483       for ( Message_ListIteratorOfListOfMsg iter ( it.Value() ); iter.More(); iter.Next() )
484       {
485         if ( aMapOfNumberOfFixes.IsBound ( iter.Value().Value() ) )
486         {
487           aMapOfNumberOfFixes ( iter.Value().Value() )++;
488         }
489         else
490         {
491           aMapOfNumberOfFixes.Bind ( iter.Value().Value(), 1 );
492         }
493       }
494       if ( mess < 0 )
495       {
496         aBuilder.Add ( aCompound, it.Key() );
497       }
498     }
499     
500     aSStream << " Fix" << setw (58) << "Count\n";
501     aSStream << " ------------------------------------------------------------\n";
502     for ( TColStd_DataMapIteratorOfDataMapOfAsciiStringInteger anIter ( aMapOfNumberOfFixes ); anIter.More(); anIter.Next() )
503     {
504       aSStream << " " << anIter.Key() << setw ( 60 - anIter.Key().Length() ) << anIter.Value() << "\n";
505     }
506     aSStream << " ------------------------------------------------------------\n";
507     di << aSStream;
508
509     if ( mess < 0 )
510     {
511       char buff[256];
512       Sprintf ( buff, "%s_%s", res, "m" );
513       di << " Modified shapes saved in compound: " << buff;
514       DBRep::Set (buff, aCompound);
515     }
516   }
517   
518   return 0; // Done
519 }
520
521 //=======================================================================
522 //function : fixgaps
523 //purpose  : 
524 //=======================================================================
525
526 Standard_Integer fixgaps(Draw_Interpretor& di, Standard_Integer n, const char** a)
527 {
528   if (n < 3) return 1;
529   
530   TopoDS_Shape S = DBRep::Get(a[2]);
531   if (S.IsNull()) {
532     di << " Shape is null" << "\n";
533     return 1;
534   }
535
536   Handle(ShapeFix_Wireframe) SFWF = new ShapeFix_Wireframe(S);
537   Standard_Real prec = ( n >3 ? Draw::Atof(a[3]) : 0. );
538   SFWF->SetPrecision(prec);
539   if ( SFWF->FixWireGaps() ) {
540     DBRep::Set(a[1],SFWF->Shape());
541     di<<" Wireframe gaps fixed on shape"<<"\n";
542   }
543
544   return 0;
545 }
546
547 //=======================================================================
548 //function : fixsmall
549 //purpose  : 
550 //=======================================================================
551
552 Standard_Integer fixsmall(Draw_Interpretor& di, Standard_Integer n, const char** a)
553 {
554   if (n < 3) return 1;
555   
556   TopoDS_Shape S = DBRep::Get(a[2]);
557   if (S.IsNull()) {
558     di << " Shape is null" << "\n";
559     return 1;
560   }
561
562   Standard_Real prec = (n == 4)? Draw::Atof(a[3]) : 1.;
563   ShapeFix_Wireframe SFWF(S);
564   SFWF.SetPrecision(prec);
565   
566   if (SFWF.FixSmallEdges()) {
567     DBRep::Set(a[1],SFWF.Shape());
568     di<<" Small edges fixed on shape"<<"\n";
569   }
570
571   return 0;
572 }
573
574 //=======================================================================
575 //function : fixsmalledges
576 //purpose  : 
577 //=======================================================================
578
579 static Standard_Integer fixsmalledges(Draw_Interpretor& di, Standard_Integer n, const char** a)
580 {
581   if( n < 3) {
582     di<<"Invalid number of arguments"<<"\n";
583     return 1;
584   }
585   TopoDS_Shape Sh = DBRep::Get(a[2]);
586  
587   Standard_Integer k = 3;
588   Standard_Real tol = 100000;
589   Standard_Integer mode = 2;
590   Standard_Real tolang = M_PI/2;
591   if(n > k) 
592     tol = Draw::Atof(a[k++]);
593   
594   if(n > k) 
595     mode=  Draw::Atoi(a[k++]);
596    
597   if(n > k) 
598     tolang = Draw::Atof(a[k++]);
599      
600   Handle(ShapeFix_Wireframe) aSfwr = new ShapeFix_Wireframe();
601   Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape;
602   aSfwr->SetContext(aReShape);
603   aSfwr->Load(Sh);
604   aSfwr->SetPrecision(tol);
605   Standard_Boolean aModeDrop = Standard_True;
606   if(mode == 2) 
607     aModeDrop = Standard_False;
608    
609   TopTools_MapOfShape theSmallEdges, theMultyEdges;
610   TopTools_DataMapOfShapeListOfShape theEdgeToFaces,theFaceWithSmall;
611   aSfwr->CheckSmallEdges(theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges);
612   aSfwr->MergeSmallEdges (theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges, aModeDrop,tolang);
613    //aSfwr->FixSmallEdges(); 
614   TopoDS_Shape resShape =  aSfwr->Shape();;
615   DBRep::Set ( a[1], resShape );
616   return 0;
617 }
618
619 //=======================================================================
620 //function : checkoverlapedges
621 //purpose  : 
622 //=======================================================================
623
624 static Standard_Integer checkoverlapedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
625 {
626    if( n < 3) {
627      di<<"Invalid number of arguments"<<"\n";
628      return 1;
629    }
630    TopoDS_Shape Sh1 = DBRep::Get(a[1]);
631    TopoDS_Shape Sh2 = DBRep::Get(a[2]);
632    if(Sh1.IsNull() || Sh2.IsNull()) {
633      di<<"Invalid arguments"<<"\n";
634      return 1;
635    }
636    TopoDS_Edge e1 = TopoDS::Edge(Sh1);
637    TopoDS_Edge e2 = TopoDS::Edge(Sh2);
638    if(e1.IsNull() || e2.IsNull()) {
639      di<<"Invalid type of arguments"<<"\n";
640      return 1;
641    }
642    Standard_Real aTol = Precision::Confusion();
643    Standard_Real aDistDomain = 0.0;
644    Standard_Integer k = 3;
645    if(k < n)
646      aTol = Draw::Atof(a[k++]);
647    if(k < n)
648      aDistDomain = Draw::Atof(a[k++]);
649    
650    ShapeAnalysis_Edge sae;
651    if(sae.CheckOverlapping(e1,e2,aTol,aDistDomain)) {
652      if(aDistDomain ==0.0)
653        di<<"Edges is overlaping comletly"<<"\n";
654      else {
655         di<<"Edges is overlaped"<<"\n";
656         di<<"with tolerance = "<<aTol<<"\n";
657         di<<"on segment length = "<<aDistDomain<<"\n";
658      }
659    }
660    else di<<"Edges is not overlaped"<<"\n";
661    return 0;
662 }
663
664 //=======================================================================
665 //function : checkfclass2d
666 //purpose  : 
667 //=======================================================================
668
669 static Standard_Integer checkfclass2d(Draw_Interpretor& di, Standard_Integer n, const char** a)
670 {
671   if( n < 4) {
672     di<<"Invalid number of arguments"<<"\n";
673     return 1;
674   }
675   TopoDS_Shape Sh1 = DBRep::Get(a[1]);
676   Standard_Real ucoord = Draw::Atof(a[2]);
677   Standard_Real vcoord = Draw::Atof(a[3]);
678   if(Sh1.IsNull() || Sh1.ShapeType()!= TopAbs_FACE) {
679     di<<"Invalid arguments"<<"\n";
680     return 1;
681   }
682   TopoDS_Face aFace = TopoDS::Face(Sh1);
683   gp_Pnt2d p2d(ucoord,vcoord);
684   BRepTopAdaptor_FClass2d f2d(aFace,Precision::Confusion());
685   TopAbs_State stat = f2d.Perform(p2d);
686   if(stat == TopAbs_OUT)
687     di<<"Point is OUT"<<"\n";
688   else if(stat == TopAbs_IN)
689     di<<"Point is IN"<<"\n";
690   else if(stat == TopAbs_ON)
691     di<<"Point is ON"<<"\n";
692   else
693     di<<"Point is UNKNOWN"<<"\n";
694   return 0;
695 }
696
697 static Standard_Integer connectedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
698 {
699   if( n < 3) {
700     di<<"Invalid number of arguments. Should be : result shape [toler shared]"<<"\n";
701     return 1;
702   }
703   TopoDS_Shape aSh1 = DBRep::Get(a[2]);
704   if(aSh1.IsNull()) {
705     di<<"Shape is null"<<"\n";
706     return 1;
707   }
708   Standard_Real aTol = Precision::Confusion();
709   if( n > 3)
710     aTol = Draw::Atof(a[3]);
711   
712   Standard_Boolean shared = Standard_True;
713   if( n > 4)
714     shared = (Draw::Atoi(a[4]) == 1);
715   TopExp_Explorer aExpE(aSh1,TopAbs_EDGE);
716   Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
717   Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
718   TopTools_IndexedMapOfShape aMapEdges;
719   for( ; aExpE.More(); aExpE.Next())
720   {
721     aSeqEdges->Append(aExpE.Current());
722     aMapEdges.Add(aExpE.Current());
723   }
724   
725   ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges,aTol,shared,aSeqWires );
726   TopoDS_Compound aComp;
727   BRep_Builder aB;
728   aB.MakeCompound(aComp);
729   Standard_Integer i = 1;
730   for( ; i <= aSeqWires->Length() ; i++)
731   {
732     TopoDS_Shape aW = aSeqWires->Value(i);
733     di<<"Wire - "<<i<<" : "<<"\n";
734     
735     TopExp_Explorer aExp1(aW, TopAbs_EDGE);
736     for( ; aExp1.More(); aExp1.Next())
737     {
738       if(shared)
739       {
740         Standard_Integer ind = aMapEdges.FindIndex(aExp1.Current());
741         di<<ind<<" ";
742       }
743        else
744       {
745         TopoDS_Vertex aV1, aV2;
746         TopExp::Vertices(TopoDS::Edge(aExp1.Current()), aV1,aV2);
747         gp_Pnt aP = BRep_Tool::Pnt(aV1);
748         di<<aP.X()<<" "<<aP.Y()<<" "<<aP.Z()<<"\n";
749       }
750     }
751    
752     di<<"\n";
753     aB.Add( aComp,aSeqWires->Value(i));
754   }
755   DBRep::Set(a[1],aComp);
756   return 0;
757   
758 }
759
760 //=======================================================================
761 //function : InitCommands
762 //purpose  : 
763 //=======================================================================
764
765  void SWDRAW_ShapeFix::InitCommands(Draw_Interpretor& theCommands) 
766 {
767   static Standard_Integer initactor = 0;
768   if (initactor) return;  initactor = 1;
769   
770   Standard_CString g = SWDRAW::GroupName();
771   
772   theCommands.Add ("edgesameparam","nom shape draw ou * [+ option force]",
773                    __FILE__,edgesameparam,g);
774   theCommands.Add ("settolerance","shape [mode=v-e-f-a] val(fix value) or tolmin tolmax",
775                    __FILE__,settolerance,g);
776   theCommands.Add ("stwire","stwire tout court pour help complet",
777                    __FILE__,stwire,g);
778   theCommands.Add ("reface","shape result : controle sens wire",
779                    __FILE__,reface,g);
780   theCommands.Add ("fixshape","res shape [preci [maxpreci]] [{switches}]",
781                    __FILE__,fixshape,g);
782 //  theCommands.Add ("testfill","result edge1 edge2",
783 //                 __FILE__,XSHAPE_testfill,g);
784   theCommands.Add ("fixwgaps","result shape [toler=0]",
785                    __FILE__,fixgaps,g);
786   theCommands.Add ("fixsmall","result shape [toler=1.]",
787                    __FILE__,fixsmall,g);
788   theCommands.Add ("fixsmalledges","result shape [toler mode amxangle]",
789                    __FILE__,fixsmalledges,g);
790   theCommands.Add ("checkoverlapedges","edge1 edge2 [toler domaindist]",
791                    __FILE__,checkoverlapedges,g);
792   theCommands.Add ("checkfclass2d","face ucoord vcoord",
793                    __FILE__,checkfclass2d,g);
794   theCommands.Add ("connectedges","res shape [toler shared]",
795                    __FILE__,connectedges,g);
796   
797 }
798