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