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