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