1 // Created on: 1999-03-09
2 // Created by: data exchange team
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepBuilderAPI.hxx>
21 #include <BRepTopAdaptor_FClass2d.hxx>
24 #include <Draw_ProgressIndicator.hxx>
25 #include <gp_Pnt2d.hxx>
27 #include <Precision.hxx>
28 #include <ShapeAnalysis_Edge.hxx>
29 #include <ShapeAnalysis_FreeBounds.hxx>
30 #include <ShapeAnalysis_WireOrder.hxx>
31 #include <ShapeBuild_ReShape.hxx>
32 #include <ShapeExtend_MsgRegistrator.hxx>
33 #include <ShapeFix.hxx>
34 #include <ShapeFix_FixSmallFace.hxx>
35 #include <ShapeFix_Shape.hxx>
36 #include <ShapeFix_ShapeTolerance.hxx>
37 #include <ShapeFix_Wire.hxx>
38 #include <ShapeFix_Wireframe.hxx>
39 #include <ShapeFix_WireVertex.hxx>
41 #include <SWDRAW_ShapeFix.hxx>
42 #include <TCollection_AsciiString.hxx>
43 #include <TColStd_DataMapOfAsciiStringInteger.hxx>
44 #include <TopAbs_State.hxx>
46 #include <TopExp_Explorer.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Iterator.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <TopoDS_Wire.hxx>
53 #include <TopTools_DataMapOfShapeListOfShape.hxx>
54 #include <TopTools_HSequenceOfShape.hxx>
55 #include <TopTools_IndexedMapOfShape.hxx>
56 #include <TopTools_MapOfShape.hxx>
63 //=======================================================================
64 //function : edgesameparam
66 //=======================================================================
68 static Standard_Integer edgesameparam (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
70 // const Standard_CString arg1 = argv[1];
71 const Standard_CString arg2 (argc > 2 ? argv[2] : NULL);
72 // **** Edge:SameParameter ****
73 if (argc < 2) { di<<"shapename , option f to force, else only Edges not-SameParameter are computed\n"; return 1 /* Error */; }
74 TopoDS_Shape Shape = DBRep::Get(argv[1]);
76 if (!ShapeFix::SameParameter(Shape, (argc > 2 && arg2[0] == 'f') , BRepBuilderAPI::Precision()) )
77 di<<"Some edges were not processed\n";
82 //=======================================================================
83 //function : settolerance
85 //=======================================================================
87 static Standard_Integer settolerance (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
90 di<< "myshape val : forces tolerances at <val>\n"
91 << "myshape < max : sets maximum tolerance to <max>\n"
92 << "myshape > min : sets minimum tolerance to <min>\n"
93 << "myshape min max : bounds tolerances between <min> and <max>\n"
94 <<"myshape mode=v-e-f other args : idem but only on vertex-edge-face\n";
95 return (argc < 2 ? 0 : 1 /* Error */);
97 Standard_CString arg1 = argv[1];
98 Standard_CString arg2 = argv[2];
99 TopoDS_Shape Shape = DBRep::Get(arg1);
100 if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
102 Standard_Integer premarg = 2;
103 TopAbs_ShapeEnum styp = TopAbs_SHAPE;
104 if (mod2 == 'v') { styp = TopAbs_VERTEX; premarg = 3; }
105 if (mod2 == 'e') { styp = TopAbs_EDGE; premarg = 3; }
106 if (mod2 == 'w') { styp = TopAbs_WIRE; premarg = 3; }
107 if (mod2 == 'f') { styp = TopAbs_FACE; premarg = 3; }
108 if (mod2 == 'a') { styp = TopAbs_SHAPE; premarg = 3; }
110 Standard_Real tmin,tmax;
111 mod2 = argv[premarg][0];
112 if (mod2 == '=') tmin = tmax = Draw::Atof (argv[argc-1]);
113 else if (mod2 == '<') { tmin = 0; tmax = Draw::Atof (argv[argc-1]); }
114 else if (mod2 == '>') { tmin = Draw::Atof (argv[argc-1]); tmax = 0; }
115 else { tmin = Draw::Atof (argv[premarg]); tmax = Draw::Atof (argv[argc-1]); }
117 if (argc == premarg + 1 || tmin == tmax) di<<"Setting Tolerance to "<<tmin<<"\n";
118 else if (tmax < tmin) di<<"Minimum Tolerance to "<<tmin<<"\n";
119 else if (tmin <= 0) di<<"Maximum Tolerance to "<<tmax<<"\n";
120 else di<<"Tolerance Limited between "<<tmin<<" and "<<tmax<<"\n";
121 ShapeFix_ShapeTolerance sat;
122 sat.LimitTolerance (Shape,tmin,tmax,styp);
126 //=======================================================================
129 //=======================================================================
131 static Standard_Integer stwire (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
133 if (argc < 2) { // help
134 di<<"Donner nom shape depart + nom shape resultat + option\n";
135 di<<"Options de chargement : x add connected (sinon add simple)\n"
136 << "Options de traitement : l fix little/BRepBuilderAPI\n"
137 <<"Options de sortie : aucune make simple\n"
138 <<" m MakeAPI r avec reorder v vertex\n"
139 <<"Autres (se cumulent) : q quid(stats)\n";
142 if (argc < 4) { di<<"stwire tout court pour help\n"; return 1 /* Error */; }
143 Standard_CString arg1 = argv[1];
144 Standard_CString arg2 = argv[2];
147 Standard_Integer i; int ox,ol,om,orint,oq,ov; ox=ol=om=orint=oq=ov=0;
148 for (i = 3; i < argc; i ++) {
150 char opt = argv[i][0];
151 if (opt == '+') opt = argv[i][1];
152 if (opt == '-') { opt = argv[i][1]; valopt = 0; }
154 case 'l' : ol = valopt; break;
155 case 'm' : om = valopt; break;
156 case 'q' : oq = valopt; break;
157 case 'r' : orint = valopt; break;
158 case 'v' : ov = valopt; break;
159 case 'x' : ox = valopt; break;
163 TopoDS_Shape Shape = DBRep::Get(arg1);
164 if (Shape.IsNull()) { di<<arg1<<" inconnu\n"; return 1 /* Error */; }
167 Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData;
168 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
171 TopoDS_Shape awire; // en principe un Wire
172 if (Shape.ShapeType() == TopAbs_WIRE) {
174 } else if (Shape.ShapeType() == TopAbs_FACE) {
175 saw->SetFace (TopoDS::Face(Shape));
176 TopExp_Explorer expw(Shape,TopAbs_WIRE);
177 if (expw.More()) awire = expw.Current();
178 saw->SetPrecision (BRepBuilderAPI::Precision());
180 if (awire.IsNull()) {
181 di<<"Neither FACE nor WIRE : "<<arg1<<"\n";
182 di<<"Considering as list of edges ...\n";
184 // return 1 /* Error */;
187 // Chargement : normal ou par connected(oriented)
189 for (TopExp_Explorer exp(Shape,TopAbs_EDGE); exp.More(); exp.Next()) {
190 TopoDS_Edge E = TopoDS::Edge (exp.Current());
191 Standard_Integer orient = saw->CheckShapeConnect (E);
192 di<<"Orientation : "<<orient<<" LowerDist : "<< saw->MinDistance3d() << "\n";
193 if (ox) sbwd->AddOriented (E,orient);
197 // else sbwd->Init (awire);
199 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
202 // Traitement en cours
204 Standard_Integer nb = sfw->NbEdges();
205 for (i = 1; i <= nb; i ++) {
206 Standard_Boolean stat = sfw->FixSmall (i, Standard_True, 0.0);
207 //std::cout<<"FixSmall for"<<i<<(stat ? " done" : " not done"); //:sw <<" StatusFix="<<STW.StatusFix()<<"\n";
208 di<<"FixSmall for"<<i;
214 if ( sfw->LastFixStatus ( ShapeExtend_FAIL ) ) di << " (failed)";
220 if (orint) { // reorder ?
221 ShapeAnalysis_WireOrder WO ( (Shape.ShapeType() != TopAbs_FACE), BRepBuilderAPI::Precision());
223 Standard_Integer stwo = saw->CheckOrder (WO);
224 Standard_Integer nb = WO.NbEdges();
225 di<<"Reorder status : "<<stwo<<" NbEdges="<<nb<<"\n";
226 for (i = 1; i <= nb; i ++) {
227 Standard_Integer iord = WO.Ordered(i);
229 if ( sbwd->Edge(iord).Orientation() == TopAbs_REVERSED) di<<" REV";
231 di<<" ordered to "<<iord<<" Gap="<<WO.Gap(i)<<"\n";
233 di<<"Reorder not yet done\n";
234 sfw->FixReorder (WO);
235 // Mais on n execute pas
240 ShapeAnalysis_Edge sae;
241 Standard_Integer nb = sbwd->NbEdges();
242 di<<"NbEdges : "<<nb<<"\n";
243 for (i = 1; i <= nb; i ++) {
244 TopoDS_Edge E = sbwd->Edge(i);
246 if (E.Orientation() == TopAbs_REVERSED) di<<" REV";
248 if (BRep_Tool::Degenerated(E)) di<<" DGNR";
249 if (sbwd->IsSeam(i)) di<<" SEAM_WIRE";
250 if (Shape.ShapeType() == TopAbs_FACE &&
251 sae.IsSeam(E,TopoDS::Face(Shape))) di<<" SEAM_FACE";
252 if (Shape.ShapeType() == TopAbs_FACE ) {
253 if (sae.HasPCurve(E,TopoDS::Face(Shape))) di<<" PCU";
256 if (sae.HasCurve3d(E)) di<<" C3D";
258 if (sae.IsClosed3d(E)) di<<" CLOSED";
266 ShapeAnalysis_WireVertex sawv;
267 sawv.Init ( sbwd, saw->Precision() );
269 Standard_Integer nb = sbwd->NbEdges();
270 di<<"Nb(End)Vertex : "<<nb<<"\n";
271 for (i = 1; i <= nb; i ++) {
272 gp_XYZ pos; Standard_Real upre,ufol;
273 Standard_Integer stat = sawv.Data (i,pos,upre,ufol);
276 case 0 : di<<"Same Vertex\n"; break;
277 case 1 : di<<"Same Coords with recorded precisions (but not Same Vertex)\n"; break;
278 case 2 : di<<"Close (with preci="<< saw->Precision()<<")\n"; break;
279 case 3 : di<<"End of "<<i<<" OK, Start of "<<(i == nb ? 1 : i+1)<<" at U="<<ufol; break;
280 case 4 : di<<"End of "<<i<<" at U="<<upre<<", Start of "<<(i == nb ? 1 : i+1)<<" OK"; break;
281 case 5 : di<<"Intersection, End of "<<i<<" at U="<<upre<<", Start of "<<(i == nb ? 1 : i+1)<<" at U="<<ufol; break;
282 default : di<<"Disjoined\n";
284 if (stat >= 3 && stat <= 5) di<<"\n - Position : "<<pos.X()<<" "<<pos.Y()<<" "<<pos.Z()<<"\n";
286 ShapeFix_WireVertex sfwv;
288 di<<"Nb Fixed Vertex : "<< sfwv.Fix() <<"\n";
292 if ( Shape.ShapeType() == TopAbs_FACE ) {
293 Correct_Wire CW ( TopoDS::Face(Shape) );
294 Standard_Integer i, nb = sbwd->NbEdges();
295 Standard_Integer num = 1;
296 for (i = 1; i <= nb; i ++) CW.Add (sbwd->Edge(i));
297 CW.Perform ( saw->Precision() );
300 // On prend celui qui a le plus d edges
301 Standard_Integer nbe, maxe = 0;
302 for (i = 1; i <= nb; i ++) {
303 TopoDS_Wire wir = CW.Wire(i);
305 for (TopoDS_Iterator ite(wir); ite.More(); ite.Next()) nbe ++;
306 if (nbe > maxe) { num = i; maxe = nbe; }
308 di<<"Correct_Wire produced "<<nb<<" Wires, taken n0 "<<num<<"\n";
310 result = CW.Wire (num);
312 else di << "Cannot apply Correct_Wire: face not defined\n";
315 else if (om) result = sbwd->WireAPIMake();
316 else result = sbwd->Wire();
317 if (result.IsNull()) {
318 di<<"Pas de resultat, desole\n";
321 DBRep::Set (arg2,result);
325 //=======================================================================
328 //=======================================================================
330 static Standard_Integer reface (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
332 if (argc < 3) { di<<"Donner un nom de SHAPE (SHELL ou FACE) + un nom de RESULTAT\n"; return 1 /* Error */; }
333 Standard_CString arg1 = argv[1];
334 Standard_CString arg2 = argv[2];
335 TopoDS_Shape Shape = DBRep::Get(arg1);
336 if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
338 Standard_Boolean rebuild = Standard_False;
340 Handle(ShapeFix_Face) STF = new ShapeFix_Face;
342 Standard_Integer i; // svv Jan11 2000 : porting on DEC
343 for (i = 3; i < argc; i ++) {
344 Standard_Boolean valopt = Standard_True;
345 char opt = argv[i][0];
346 if (opt == '+') opt = argv[i][1];
347 if (opt == '-') { opt = argv[i][1]; valopt = Standard_False; }
348 //std::cout<<(valopt ? ".." : ".. NO");
355 if (opt == 'R') { di<<" REBUILD-ANYWAY .."; rebuild = valopt; }
356 if (opt == 'd') { di<<" fix-dgnr .."; STF->FixWireTool()->FixDegeneratedMode() = valopt; }
357 if (opt == 'r') { di<<" fix-reorder-wire .."; STF->FixWireTool()->FixReorderMode() = valopt; }
363 ShapeBuild_ReShape resh;
365 Standard_Integer nbfc = 0;
366 for (TopExp_Explorer EF (Shape,TopAbs_FACE); EF.More(); EF.Next()) {
367 TopoDS_Face F = TopoDS::Face (EF.Current()); face = F;
368 Standard_Boolean newface = Standard_False;
369 // on va voir si ShapeTool_Face trouve qqchose a redire
370 //:sw ShapeTool_Wire STW;
371 //:sw STW.SetFace (F);
373 STF->Init (F); // qui fait tout
376 newface = STF->Status(ShapeExtend_DONE) || rebuild;
377 if (newface) { nbfc ++; resh.Replace (F,face); }
380 di<<"Faces reprises par ShapeFix_Face : "<<nbfc<<"\n";
381 DBRep::Set (arg2,resh.Apply (Shape,TopAbs_FACE,2));
384 else di<<"ShapeFix_Face n a rien trouve a redire\n";
389 //=======================================================================
390 //function : fixshape
392 //=======================================================================
394 static Standard_Integer fixshape (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
396 Handle(ShapeExtend_MsgRegistrator) msg = new ShapeExtend_MsgRegistrator;
397 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
398 sfs->SetMsgRegistrator ( msg );
400 Standard_CString res = 0;
401 Standard_Integer par = 0, mess=0;
402 for ( Standard_Integer i=1; i < argc; i++ )
404 if (strlen(argv[i]) == 2 &&
405 (argv[i][0] == '-' || argv[i][0] == '+' || argv[i][0] == '*'))
407 Standard_Integer val = ( argv[i][0] == '-' ? 0 : argv[i][0] == '+' ? 1 : -1 );
408 switch ( argv[i][1] ) {
409 case 'l': sfs->FixWireTool()->FixLackingMode() = val; break;
410 case 'o': sfs->FixFaceTool()->FixOrientationMode() = val; break;
411 case 'h': sfs->FixWireTool()->FixShiftedMode() = val; break;
412 case 'm': sfs->FixFaceTool()->FixMissingSeamMode() = val; break;
413 case 'd': sfs->FixWireTool()->FixDegeneratedMode() = val; break;
414 case 's': sfs->FixWireTool()->FixSmallMode() = val; break;
415 case 'i': sfs->FixWireTool()->FixSelfIntersectionMode() = val; break;
416 case 'n': sfs->FixWireTool()->FixNotchedEdgesMode() = val; break;
417 case '?': mess = val; break;
421 else if (!strcmp(argv[i], "-maxtaila"))
428 sfs->FixWireTool()->SetMaxTailAngle(Draw::Atof(argv[i]) * (M_PI / 180));
430 else if (!strcmp(argv[i], "-maxtailw"))
437 sfs->FixWireTool()->SetMaxTailWidth(Draw::Atof(argv[i]));
438 sfs->FixWireTool()->FixTailMode() = 1;
443 case 0: res = argv[i]; break;
445 TopoDS_Shape initShape = DBRep::Get(argv[i]);
446 if(initShape.IsNull()) continue;
447 sfs->Init ( initShape );
449 case 2: sfs->SetPrecision (Draw::Atof(argv[i])); break;
450 case 3: sfs->SetMaxTolerance(Draw::Atof(argv[i])); break;
457 di << "Use: " << argv[0] << " result shape [tolerance [max_tolerance]] [switches]\n"
458 "[-maxtaila <degrees>] [-maxtailw <width>]\n";
459 di << "Switches allow to tune parameters of ShapeFix\n";
460 di << "The following syntax is used: <symbol><parameter>\n";
461 di << "- symbol may be - to set parameter off, + to set on or * to set default\n";
462 di << "- parameters are identified by letters:\n";
463 di << " l - FixLackingMode\n";
464 di << " o - FixOrientationMode\n";
465 di << " h - FixShiftedMode\n";
466 di << " m - FixMissingSeamMode\n";
467 di << " d - FixDegeneratedMode\n";
468 di << " s - FixSmallMode\n";
469 di << " i - FixSelfIntersectionMode\n";
470 di << " n - FixNotchedEdgesMode\n";
471 di << "For enhanced message output, use switch '+?'\n";
475 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
476 sfs->Perform (aProgress->Start());
477 DBRep::Set (res,sfs->Shape());
481 TColStd_DataMapOfAsciiStringInteger aMapOfNumberOfFixes;
482 Standard_SStream aSStream;
483 TopoDS_Compound aCompound;
484 BRep_Builder aBuilder;
485 aBuilder.MakeCompound (aCompound);
486 const ShapeExtend_DataMapOfShapeListOfMsg &map = msg->MapShape();
487 // Counting the number of each type of fixes. If the switch '*?' store all modified shapes in compound.
488 for ( ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg it ( map ); it.More(); it.Next() )
490 for ( Message_ListIteratorOfListOfMsg iter ( it.Value() ); iter.More(); iter.Next() )
492 if ( aMapOfNumberOfFixes.IsBound ( iter.Value().Value() ) )
494 aMapOfNumberOfFixes ( iter.Value().Value() )++;
498 aMapOfNumberOfFixes.Bind ( iter.Value().Value(), 1 );
503 aBuilder.Add ( aCompound, it.Key() );
507 aSStream << " Fix" << std::setw (58) << "Count\n";
508 aSStream << " ------------------------------------------------------------\n";
509 for ( TColStd_DataMapIteratorOfDataMapOfAsciiStringInteger anIter ( aMapOfNumberOfFixes ); anIter.More(); anIter.Next() )
511 aSStream << " " << anIter.Key() << std::setw ( 60 - anIter.Key().Length() ) << anIter.Value() << "\n";
513 aSStream << " ------------------------------------------------------------\n";
519 Sprintf ( buff, "%s_%s", res, "m" );
520 di << " Modified shapes saved in compound: " << buff;
521 DBRep::Set (buff, aCompound);
528 //=======================================================================
531 //=======================================================================
533 Standard_Integer fixgaps(Draw_Interpretor& di, Standard_Integer n, const char** a)
537 TopoDS_Shape S = DBRep::Get(a[2]);
539 di << " Shape is null\n";
543 Handle(ShapeFix_Wireframe) SFWF = new ShapeFix_Wireframe(S);
544 Standard_Real prec = ( n >3 ? Draw::Atof(a[3]) : 0. );
545 SFWF->SetPrecision(prec);
546 if ( SFWF->FixWireGaps() ) {
547 DBRep::Set(a[1],SFWF->Shape());
548 di<<" Wireframe gaps fixed on shape\n";
554 //=======================================================================
555 //function : fixsmall
557 //=======================================================================
559 Standard_Integer fixsmall(Draw_Interpretor& di, Standard_Integer n, const char** a)
563 TopoDS_Shape S = DBRep::Get(a[2]);
565 di << " Shape is null\n";
569 Standard_Real prec = (n == 4)? Draw::Atof(a[3]) : 1.;
570 ShapeFix_Wireframe SFWF(S);
571 SFWF.SetPrecision(prec);
573 if (SFWF.FixSmallEdges()) {
574 DBRep::Set(a[1],SFWF.Shape());
575 di<<" Small edges fixed on shape\n";
581 //=======================================================================
582 //function : fixsmalledges
584 //=======================================================================
586 static Standard_Integer fixsmalledges(Draw_Interpretor& di, Standard_Integer n, const char** a)
589 di<<"Invalid number of arguments\n";
592 TopoDS_Shape Sh = DBRep::Get(a[2]);
594 Standard_Integer k = 3;
595 Standard_Real tol = 100000;
596 Standard_Integer mode = 2;
597 Standard_Real tolang = M_PI/2;
599 tol = Draw::Atof(a[k++]);
602 mode= Draw::Atoi(a[k++]);
605 tolang = Draw::Atof(a[k++]);
607 Handle(ShapeFix_Wireframe) aSfwr = new ShapeFix_Wireframe();
608 Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape;
609 aSfwr->SetContext(aReShape);
611 aSfwr->SetPrecision(tol);
612 Standard_Boolean aModeDrop = Standard_True;
614 aModeDrop = Standard_False;
616 TopTools_MapOfShape theSmallEdges, theMultyEdges;
617 TopTools_DataMapOfShapeListOfShape theEdgeToFaces,theFaceWithSmall;
618 aSfwr->CheckSmallEdges(theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges);
619 aSfwr->MergeSmallEdges (theSmallEdges,theEdgeToFaces,theFaceWithSmall, theMultyEdges, aModeDrop,tolang);
620 //aSfwr->FixSmallEdges();
621 TopoDS_Shape resShape = aSfwr->Shape();
622 DBRep::Set ( a[1], resShape );
626 //=======================================================================
627 //function : fixsmallfaces
629 //=======================================================================
631 Standard_Integer fixsmallfaces (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
635 theDI << "Use: " << theArgv[0] << " result shape [tolerance]";
639 TopoDS_Shape aShape = DBRep::Get(theArgv[2]);
640 if (aShape.IsNull()) {
641 theDI << "Error: Shape " << theArgv[2] << " is null\n";
645 Standard_Real aPrec = (theArgc < 4 ? 1. : Draw::Atof(theArgv[3]));
647 ShapeFix_FixSmallFace aFixSmallFaces;
648 aFixSmallFaces.Init (aShape);
649 aFixSmallFaces.SetPrecision(aPrec);
650 aFixSmallFaces.Perform();
651 if (! aFixSmallFaces.Shape().IsSame (aShape))
653 theDI << "Small faces are removed";
654 aShape = aFixSmallFaces.Shape();
657 DBRep::Set (theArgv[1], aShape);
662 //=======================================================================
663 //function : checkoverlapedges
665 //=======================================================================
667 static Standard_Integer checkoverlapedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
670 di<<"Invalid number of arguments\n";
673 TopoDS_Shape Sh1 = DBRep::Get(a[1]);
674 TopoDS_Shape Sh2 = DBRep::Get(a[2]);
675 if(Sh1.IsNull() || Sh2.IsNull()) {
676 di<<"Invalid arguments\n";
679 TopoDS_Edge e1 = TopoDS::Edge(Sh1);
680 TopoDS_Edge e2 = TopoDS::Edge(Sh2);
681 if(e1.IsNull() || e2.IsNull()) {
682 di<<"Invalid type of arguments\n";
686 if (BRep_Tool::Degenerated(e1))
688 di << a[1] << " is degenerated\n";
692 if (BRep_Tool::Degenerated(e2))
694 di << a[2] << " is degenerated\n";
698 Standard_Real aTol = Precision::Confusion();
699 Standard_Real aDistDomain = 0.0;
700 Standard_Integer k = 3;
702 aTol = Draw::Atof(a[k++]);
704 aDistDomain = Draw::Atof(a[k++]);
706 ShapeAnalysis_Edge sae;
707 if(sae.CheckOverlapping(e1,e2,aTol,aDistDomain)) {
708 if(aDistDomain ==0.0)
709 di<<"Edges are overlapping completely\n";
711 di<<"Edges are overlapped\n";
712 di<<"with tolerance = "<<aTol<<"\n";
713 di<<"on segment length = "<<aDistDomain<<"\n";
716 else di<<"Edges are not overlapped\n";
720 //=======================================================================
721 //function : checkfclass2d
723 //=======================================================================
725 static Standard_Integer checkfclass2d(Draw_Interpretor& di, Standard_Integer n, const char** a)
728 di<<"Invalid number of arguments\n";
731 TopoDS_Shape Sh1 = DBRep::Get(a[1]);
732 Standard_Real ucoord = Draw::Atof(a[2]);
733 Standard_Real vcoord = Draw::Atof(a[3]);
734 if(Sh1.IsNull() || Sh1.ShapeType()!= TopAbs_FACE) {
735 di<<"Invalid arguments\n";
738 Standard_Real tol = Precision::Confusion();
744 TopoDS_Face aFace = TopoDS::Face(Sh1);
745 gp_Pnt2d p2d(ucoord,vcoord);
746 BRepTopAdaptor_FClass2d f2d(aFace, tol);
747 TopAbs_State stat = f2d.Perform(p2d);
748 if(stat == TopAbs_OUT)
749 di<<"Point is OUT\n";
750 else if(stat == TopAbs_IN)
752 else if(stat == TopAbs_ON)
755 di<<"Point is UNKNOWN\n";
759 static Standard_Integer connectedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
762 di<<"Invalid number of arguments. Should be : result shape [toler shared]\n";
765 TopoDS_Shape aSh1 = DBRep::Get(a[2]);
767 di<<"Shape is null\n";
770 Standard_Real aTol = Precision::Confusion();
772 aTol = Draw::Atof(a[3]);
774 Standard_Boolean shared = Standard_True;
776 shared = (Draw::Atoi(a[4]) == 1);
777 TopExp_Explorer aExpE(aSh1,TopAbs_EDGE);
778 Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
779 Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
780 TopTools_IndexedMapOfShape aMapEdges;
781 for( ; aExpE.More(); aExpE.Next())
783 aSeqEdges->Append(aExpE.Current());
784 aMapEdges.Add(aExpE.Current());
787 ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges,aTol,shared,aSeqWires );
788 TopoDS_Compound aComp;
790 aB.MakeCompound(aComp);
791 Standard_Integer i = 1;
792 for( ; i <= aSeqWires->Length() ; i++)
794 TopoDS_Shape aW = aSeqWires->Value(i);
795 di<<"Wire - "<<i<<" : \n";
797 TopExp_Explorer aExp1(aW, TopAbs_EDGE);
798 for( ; aExp1.More(); aExp1.Next())
802 Standard_Integer ind = aMapEdges.FindIndex(aExp1.Current());
807 TopoDS_Vertex aV1, aV2;
808 TopExp::Vertices(TopoDS::Edge(aExp1.Current()), aV1,aV2);
809 gp_Pnt aP = BRep_Tool::Pnt(aV1);
810 di<<aP.X()<<" "<<aP.Y()<<" "<<aP.Z()<<"\n";
815 aB.Add( aComp,aSeqWires->Value(i));
817 DBRep::Set(a[1],aComp);
822 //=======================================================================
823 //function : InitCommands
825 //=======================================================================
827 void SWDRAW_ShapeFix::InitCommands(Draw_Interpretor& theCommands)
829 static Standard_Integer initactor = 0;
836 Standard_CString g = SWDRAW::GroupName();
838 theCommands.Add ("edgesameparam","nom shape draw ou * [+ option force]",
839 __FILE__,edgesameparam,g);
840 theCommands.Add ("settolerance","shape [mode=v-e-f-a] val(fix value) or tolmin tolmax",
841 __FILE__,settolerance,g);
842 theCommands.Add ("stwire","stwire tout court pour help complet",
844 theCommands.Add ("reface","shape result : controle sens wire",
846 theCommands.Add ("fixshape",
847 "res shape [preci [maxpreci]] [{switches}]\n"
848 " [-maxtaila <degrees>] [-maxtailw <width>]",
849 __FILE__,fixshape,g);
850 // theCommands.Add ("testfill","result edge1 edge2",
851 // __FILE__,XSHAPE_testfill,g);
852 theCommands.Add ("fixwgaps","result shape [toler=0]",
854 theCommands.Add ("fixsmall","result shape [toler=1.]",
855 __FILE__,fixsmall,g);
856 theCommands.Add ("fixsmalledges","result shape [toler mode amxangle]",
857 __FILE__,fixsmalledges,g);
858 theCommands.Add ("fixsmallfaces","result shape [toler=1.]",
859 __FILE__,fixsmallfaces,g);
860 theCommands.Add ("checkoverlapedges","edge1 edge2 [toler domaindist]",
861 __FILE__,checkoverlapedges,g);
862 theCommands.Add ("checkfclass2d","face ucoord vcoord [tol]",
863 __FILE__,checkfclass2d,g);
864 theCommands.Add ("connectedges","res shape [toler shared]",
865 __FILE__,connectedges,g);