0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / SWDRAW / SWDRAW_ShapeFix.cxx
CommitLineData
b311480e 1// Created on: 1999-03-09
2// Created by: data exchange team
3// Copyright (c) 1999-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
91322f44 17
999d2599 18#include <BRep_Builder.hxx>
42cf5bc1 19#include <BRep_Tool.hxx>
7fd59977 20#include <BRepBuilderAPI.hxx>
21#include <BRepTopAdaptor_FClass2d.hxx>
42cf5bc1 22#include <DBRep.hxx>
23#include <Draw.hxx>
24#include <Draw_ProgressIndicator.hxx>
25#include <gp_Pnt2d.hxx>
26#include <gp_XYZ.hxx>
42cf5bc1 27#include <Precision.hxx>
7fd59977 28#include <ShapeAnalysis_Edge.hxx>
42cf5bc1 29#include <ShapeAnalysis_FreeBounds.hxx>
7fd59977 30#include <ShapeAnalysis_WireOrder.hxx>
42cf5bc1 31#include <ShapeBuild_ReShape.hxx>
42cf5bc1 32#include <ShapeExtend_MsgRegistrator.hxx>
7fd59977 33#include <ShapeFix.hxx>
c3cca015 34#include <ShapeFix_FixSmallFace.hxx>
42cf5bc1 35#include <ShapeFix_Shape.hxx>
7fd59977 36#include <ShapeFix_ShapeTolerance.hxx>
37#include <ShapeFix_Wire.hxx>
7fd59977 38#include <ShapeFix_Wireframe.hxx>
42cf5bc1 39#include <ShapeFix_WireVertex.hxx>
40#include <SWDRAW.hxx>
41#include <SWDRAW_ShapeFix.hxx>
7fd59977 42#include <TCollection_AsciiString.hxx>
999d2599 43#include <TColStd_DataMapOfAsciiStringInteger.hxx>
7fd59977 44#include <TopAbs_State.hxx>
42cf5bc1 45#include <TopExp.hxx>
46#include <TopExp_Explorer.hxx>
47#include <TopoDS.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>
974c25ed 54#include <TopTools_HSequenceOfShape.hxx>
974c25ed 55#include <TopTools_IndexedMapOfShape.hxx>
42cf5bc1 56#include <TopTools_MapOfShape.hxx>
b485ee79 57
7fd59977 58#ifdef AIX
59#include <strings.h>
60#endif
61#include <stdio.h>
7fd59977 62
63//=======================================================================
64//function : edgesameparam
65//purpose :
66//=======================================================================
67
68static Standard_Integer edgesameparam (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
69{
70// const Standard_CString arg1 = argv[1];
71 const Standard_CString arg2 (argc > 2 ? argv[2] : NULL);
72// **** Edge:SameParameter ****
586db386 73 if (argc < 2) { di<<"shapename , option f to force, else only Edges not-SameParameter are computed\n"; return 1 /* Error */; }
7fd59977 74 TopoDS_Shape Shape = DBRep::Get(argv[1]);
75
76 if (!ShapeFix::SameParameter(Shape, (argc > 2 && arg2[0] == 'f') , BRepBuilderAPI::Precision()) )
586db386 77 di<<"Some edges were not processed\n";
7fd59977 78 di<<"\n";
79 return 0; // Done
80}
81
82//=======================================================================
83//function : settolerance
84//purpose :
85//=======================================================================
86
87static Standard_Integer settolerance (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
88{
89 if (argc < 3) {
586db386 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";
7fd59977 95 return (argc < 2 ? 0 : 1 /* Error */);
96 }
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 */; }
101 char mod2 = arg2[0];
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; }
109
110 Standard_Real tmin,tmax;
111 mod2 = argv[premarg][0];
91322f44 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]); }
7fd59977 116
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);
123 return 0; // Done
124}
125
126//=======================================================================
127//function : stwire
128//purpose :
129//=======================================================================
130
131static Standard_Integer stwire (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
132{
133 if (argc < 2) { // help
586db386 134 di<<"Donner nom shape depart + nom shape resultat + option\n";
7fd59977 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"
586db386 139 <<"Autres (se cumulent) : q quid(stats)\n";
7fd59977 140 return 0;
141 }
586db386 142 if (argc < 4) { di<<"stwire tout court pour help\n"; return 1 /* Error */; }
7fd59977 143 Standard_CString arg1 = argv[1];
144 Standard_CString arg2 = argv[2];
145
146// Options
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 ++) {
149 int valopt = 1;
150 char opt = argv[i][0];
151 if (opt == '+') opt = argv[i][1];
152 if (opt == '-') { opt = argv[i][1]; valopt = 0; }
153 switch (opt) {
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;
160 default : break;
161 }
162 }
163 TopoDS_Shape Shape = DBRep::Get(arg1);
586db386 164 if (Shape.IsNull()) { di<<arg1<<" inconnu\n"; return 1 /* Error */; }
7fd59977 165
166// On y va
167 Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData;
168 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
169 saw->Load ( sbwd );
170
171 TopoDS_Shape awire; // en principe un Wire
172 if (Shape.ShapeType() == TopAbs_WIRE) {
173 awire = Shape;
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());
179 }
180 if (awire.IsNull()) {
181 di<<"Neither FACE nor WIRE : "<<arg1<<"\n";
586db386 182 di<<"Considering as list of edges ...\n";
7fd59977 183 awire = Shape;
184// return 1 /* Error */;
185 }
186
187// Chargement : normal ou par connected(oriented)
188// if (ox) {
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);
194 else sbwd->Add (E);
195 }
196// }
197// else sbwd->Init (awire);
198
199 Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
200 sfw->Init ( saw );
201
202// Traitement en cours
203 if (ol) {
204 Standard_Integer nb = sfw->NbEdges();
205 for (i = 1; i <= nb; i ++) {
206 Standard_Boolean stat = sfw->FixSmall (i, Standard_True, 0.0);
04232180 207 //std::cout<<"FixSmall for"<<i<<(stat ? " done" : " not done"); //:sw <<" StatusFix="<<STW.StatusFix()<<"\n";
7fd59977 208 di<<"FixSmall for"<<i;
209 if (!stat) {
210 di<<" not done";
211 } else {
212 di<<" done";
213 }
214 if ( sfw->LastFixStatus ( ShapeExtend_FAIL ) ) di << " (failed)";
215 di << "\n";
216 }
217 }
218
219// Traitement
220 if (orint) { // reorder ?
221 ShapeAnalysis_WireOrder WO ( (Shape.ShapeType() != TopAbs_FACE), BRepBuilderAPI::Precision());
222
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);
228 di<<"Edge n0 "<<i;
229 if ( sbwd->Edge(iord).Orientation() == TopAbs_REVERSED) di<<" REV";
230 else di<<" FWD";
231 di<<" ordered to "<<iord<<" Gap="<<WO.Gap(i)<<"\n";
232 }
586db386 233 di<<"Reorder not yet done\n";
7fd59977 234 sfw->FixReorder (WO);
235// Mais on n execute pas
236 }
237
238// Statistiques
239 if (oq) {
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);
245 di<<"Edge "<<i;
246 if (E.Orientation() == TopAbs_REVERSED) di<<" REV";
247 else di<<" FWD";
248 if (BRep_Tool::Degenerated(E)) di<<" DGNR";
249 if (sbwd->IsSeam(i)) di<<" SEAM_WIRE";
250 if (Shape.ShapeType() == TopAbs_FACE &&
eafb234b 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";
254 else di<<" NO_PCU";
255 }
7fd59977 256 if (sae.HasCurve3d(E)) di<<" C3D";
257 else di<<" NO_C3D";
258 if (sae.IsClosed3d(E)) di<<" CLOSED";
259 di<<"\n";
260 }
261 }
262
263// Resultat
264 TopoDS_Wire result;
265 if (ov) {
266 ShapeAnalysis_WireVertex sawv;
267 sawv.Init ( sbwd, saw->Precision() );
268 sawv.Analyze();
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);
274 di<<i<<" : ";
275 switch (stat) {
586db386 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;
7fd59977 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;
586db386 282 default : di<<"Disjoined\n";
7fd59977 283 }
284 if (stat >= 3 && stat <= 5) di<<"\n - Position : "<<pos.X()<<" "<<pos.Y()<<" "<<pos.Z()<<"\n";
285 }
286 ShapeFix_WireVertex sfwv;
287 sfwv.Init ( sawv );
288 di<<"Nb Fixed Vertex : "<< sfwv.Fix() <<"\n";
289 }
290 /*
291 if (oc) {
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() );
298 nb = CW.NbWires();
299 if (nb != 1) {
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);
304 nbe = 0;
305 for (TopoDS_Iterator ite(wir); ite.More(); ite.Next()) nbe ++;
306 if (nbe > maxe) { num = i; maxe = nbe; }
307 }
308 di<<"Correct_Wire produced "<<nb<<" Wires, taken n0 "<<num<<"\n";
309 }
310 result = CW.Wire (num);
311 }
586db386 312 else di << "Cannot apply Correct_Wire: face not defined\n";
7fd59977 313 }
314 */
315 else if (om) result = sbwd->WireAPIMake();
316 else result = sbwd->Wire();
317 if (result.IsNull()) {
586db386 318 di<<"Pas de resultat, desole\n";
7fd59977 319 return 1; // Fail
320 }
321 DBRep::Set (arg2,result);
322 return 0; // Done
323}
324
325//=======================================================================
326//function : reface
327//purpose :
328//=======================================================================
329
330static Standard_Integer reface (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
331{
586db386 332 if (argc < 3) { di<<"Donner un nom de SHAPE (SHELL ou FACE) + un nom de RESULTAT\n"; return 1 /* Error */; }
7fd59977 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 */; }
337
338 Standard_Boolean rebuild = Standard_False;
339
340 Handle(ShapeFix_Face) STF = new ShapeFix_Face;
341// Options ?
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; }
04232180 348 //std::cout<<(valopt ? ".." : ".. NO");
7fd59977 349 if (!valopt) {
350 di<<".. NO";
351 } else {
352 di<<"..";
353 }
354
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; }
358 if (opt == 'k') {
359 }
360 }
361
362 TopoDS_Face face;
363 ShapeBuild_ReShape resh;
364
92e0a76a 365 Standard_Integer nbfc = 0;
7fd59977 366 for (TopExp_Explorer EF (Shape,TopAbs_FACE); EF.More(); EF.Next()) {
367 TopoDS_Face F = TopoDS::Face (EF.Current()); face = F;
7fd59977 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);
372
373 STF->Init (F); // qui fait tout
374 STF->Perform();
375 face = STF->Face();
376 newface = STF->Status(ShapeExtend_DONE) || rebuild;
377 if (newface) { nbfc ++; resh.Replace (F,face); }
378 }
379 if (nbfc > 0) {
380 di<<"Faces reprises par ShapeFix_Face : "<<nbfc<<"\n";
381 DBRep::Set (arg2,resh.Apply (Shape,TopAbs_FACE,2));
382 return 0; // Done
383 }
586db386 384 else di<<"ShapeFix_Face n a rien trouve a redire\n";
7fd59977 385 return 0;
386}
387
388
389//=======================================================================
390//function : fixshape
391//purpose :
392//=======================================================================
393
394static Standard_Integer fixshape (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
395{
396 Handle(ShapeExtend_MsgRegistrator) msg = new ShapeExtend_MsgRegistrator;
397 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
398 sfs->SetMsgRegistrator ( msg );
399
400 Standard_CString res = 0;
401 Standard_Integer par = 0, mess=0;
fbf3becf 402 for ( Standard_Integer i=1; i < argc; i++ )
403 {
404 if (strlen(argv[i]) == 2 &&
405 (argv[i][0] == '-' || argv[i][0] == '+' || argv[i][0] == '*'))
406 {
7fd59977 407 Standard_Integer val = ( argv[i][0] == '-' ? 0 : argv[i][0] == '+' ? 1 : -1 );
408 switch ( argv[i][1] ) {
999d2599
D
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;
7fd59977 418 }
419 continue;
420 }
fbf3becf 421 else if (!strcmp(argv[i], "-maxtaila"))
422 {
423 if (++i >= argc)
424 {
425 break;
426 }
427
428 sfs->FixWireTool()->SetMaxTailAngle(Draw::Atof(argv[i]) * (M_PI / 180));
429 }
430 else if (!strcmp(argv[i], "-maxtailw"))
431 {
432 if (++i >= argc)
433 {
434 break;
435 }
436
437 sfs->FixWireTool()->SetMaxTailWidth(Draw::Atof(argv[i]));
438 sfs->FixWireTool()->FixTailMode() = 1;
439 }
440 else
441 {
7fd59977 442 switch ( par ) {
443 case 0: res = argv[i]; break;
444 case 1: {
445 TopoDS_Shape initShape = DBRep::Get(argv[i]);
446 if(initShape.IsNull()) continue;
447 sfs->Init ( initShape );
448 } break;
91322f44 449 case 2: sfs->SetPrecision (Draw::Atof(argv[i])); break;
450 case 3: sfs->SetMaxTolerance(Draw::Atof(argv[i])); break;
7fd59977 451 }
452 }
453 par++;
454 }
455
456 if ( par <2 ) {
fbf3becf 457 di << "Use: " << argv[0] << " result shape [tolerance [max_tolerance]] [switches]\n"
586db386 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";
7fd59977 472 return 1;
473 }
b485ee79
KD
474
475 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
7e785937 476 sfs->Perform (aProgress->Start());
7fd59977 477 DBRep::Set (res,sfs->Shape());
b485ee79 478
999d2599
D
479 if ( mess )
480 {
481 TColStd_DataMapOfAsciiStringInteger aMapOfNumberOfFixes;
482 Standard_SStream aSStream;
483 TopoDS_Compound aCompound;
484 BRep_Builder aBuilder;
485 aBuilder.MakeCompound (aCompound);
7fd59977 486 const ShapeExtend_DataMapOfShapeListOfMsg &map = msg->MapShape();
999d2599
D
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() )
489 {
490 for ( Message_ListIteratorOfListOfMsg iter ( it.Value() ); iter.More(); iter.Next() )
491 {
492 if ( aMapOfNumberOfFixes.IsBound ( iter.Value().Value() ) )
493 {
494 aMapOfNumberOfFixes ( iter.Value().Value() )++;
495 }
496 else
497 {
498 aMapOfNumberOfFixes.Bind ( iter.Value().Value(), 1 );
499 }
7fd59977 500 }
999d2599
D
501 if ( mess < 0 )
502 {
503 aBuilder.Add ( aCompound, it.Key() );
504 }
505 }
506
04232180 507 aSStream << " Fix" << std::setw (58) << "Count\n";
999d2599
D
508 aSStream << " ------------------------------------------------------------\n";
509 for ( TColStd_DataMapIteratorOfDataMapOfAsciiStringInteger anIter ( aMapOfNumberOfFixes ); anIter.More(); anIter.Next() )
510 {
04232180 511 aSStream << " " << anIter.Key() << std::setw ( 60 - anIter.Key().Length() ) << anIter.Value() << "\n";
999d2599
D
512 }
513 aSStream << " ------------------------------------------------------------\n";
514 di << aSStream;
515
516 if ( mess < 0 )
517 {
518 char buff[256];
91322f44 519 Sprintf ( buff, "%s_%s", res, "m" );
999d2599
D
520 di << " Modified shapes saved in compound: " << buff;
521 DBRep::Set (buff, aCompound);
7fd59977 522 }
523 }
524
525 return 0; // Done
526}
527
528//=======================================================================
529//function : fixgaps
530//purpose :
531//=======================================================================
532
533Standard_Integer fixgaps(Draw_Interpretor& di, Standard_Integer n, const char** a)
534{
535 if (n < 3) return 1;
536
537 TopoDS_Shape S = DBRep::Get(a[2]);
538 if (S.IsNull()) {
586db386 539 di << " Shape is null\n";
7fd59977 540 return 1;
541 }
542
543 Handle(ShapeFix_Wireframe) SFWF = new ShapeFix_Wireframe(S);
91322f44 544 Standard_Real prec = ( n >3 ? Draw::Atof(a[3]) : 0. );
7fd59977 545 SFWF->SetPrecision(prec);
546 if ( SFWF->FixWireGaps() ) {
547 DBRep::Set(a[1],SFWF->Shape());
586db386 548 di<<" Wireframe gaps fixed on shape\n";
7fd59977 549 }
550
551 return 0;
552}
553
554//=======================================================================
555//function : fixsmall
556//purpose :
557//=======================================================================
558
559Standard_Integer fixsmall(Draw_Interpretor& di, Standard_Integer n, const char** a)
560{
561 if (n < 3) return 1;
562
563 TopoDS_Shape S = DBRep::Get(a[2]);
564 if (S.IsNull()) {
586db386 565 di << " Shape is null\n";
7fd59977 566 return 1;
567 }
568
91322f44 569 Standard_Real prec = (n == 4)? Draw::Atof(a[3]) : 1.;
7fd59977 570 ShapeFix_Wireframe SFWF(S);
571 SFWF.SetPrecision(prec);
572
573 if (SFWF.FixSmallEdges()) {
574 DBRep::Set(a[1],SFWF.Shape());
586db386 575 di<<" Small edges fixed on shape\n";
7fd59977 576 }
577
578 return 0;
579}
580
581//=======================================================================
582//function : fixsmalledges
583//purpose :
584//=======================================================================
585
586static Standard_Integer fixsmalledges(Draw_Interpretor& di, Standard_Integer n, const char** a)
587{
588 if( n < 3) {
586db386 589 di<<"Invalid number of arguments\n";
7fd59977 590 return 1;
591 }
592 TopoDS_Shape Sh = DBRep::Get(a[2]);
593
594 Standard_Integer k = 3;
595 Standard_Real tol = 100000;
596 Standard_Integer mode = 2;
c6541a0c 597 Standard_Real tolang = M_PI/2;
7fd59977 598 if(n > k)
91322f44 599 tol = Draw::Atof(a[k++]);
7fd59977 600
601 if(n > k)
91322f44 602 mode= Draw::Atoi(a[k++]);
7fd59977 603
604 if(n > k)
91322f44 605 tolang = Draw::Atof(a[k++]);
7fd59977 606
607 Handle(ShapeFix_Wireframe) aSfwr = new ShapeFix_Wireframe();
608 Handle(ShapeBuild_ReShape) aReShape = new ShapeBuild_ReShape;
609 aSfwr->SetContext(aReShape);
610 aSfwr->Load(Sh);
611 aSfwr->SetPrecision(tol);
612 Standard_Boolean aModeDrop = Standard_True;
613 if(mode == 2)
614 aModeDrop = Standard_False;
615
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();
8c2d3314 621 TopoDS_Shape resShape = aSfwr->Shape();
7fd59977 622 DBRep::Set ( a[1], resShape );
623 return 0;
624}
625
c3cca015 626//=======================================================================
627//function : fixsmallfaces
628//purpose :
629//=======================================================================
630
631Standard_Integer fixsmallfaces (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
632{
633 if (theArgc < 3)
634 {
d99f0355 635 theDI << "Use: " << theArgv[0] << " result shape [tolerance]";
c3cca015 636 return 1;
637 }
638
639 TopoDS_Shape aShape = DBRep::Get(theArgv[2]);
640 if (aShape.IsNull()) {
641 theDI << "Error: Shape " << theArgv[2] << " is null\n";
642 return 1;
643 }
644
645 Standard_Real aPrec = (theArgc < 4 ? 1. : Draw::Atof(theArgv[3]));
646
647 ShapeFix_FixSmallFace aFixSmallFaces;
648 aFixSmallFaces.Init (aShape);
649 aFixSmallFaces.SetPrecision(aPrec);
650 aFixSmallFaces.Perform();
651 if (! aFixSmallFaces.Shape().IsSame (aShape))
652 {
653 theDI << "Small faces are removed";
654 aShape = aFixSmallFaces.Shape();
655 }
656
657 DBRep::Set (theArgv[1], aShape);
658
659 return 0;
660}
661
7fd59977 662//=======================================================================
663//function : checkoverlapedges
664//purpose :
665//=======================================================================
666
667static Standard_Integer checkoverlapedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
668{
669 if( n < 3) {
586db386 670 di<<"Invalid number of arguments\n";
7fd59977 671 return 1;
672 }
673 TopoDS_Shape Sh1 = DBRep::Get(a[1]);
674 TopoDS_Shape Sh2 = DBRep::Get(a[2]);
675 if(Sh1.IsNull() || Sh2.IsNull()) {
586db386 676 di<<"Invalid arguments\n";
7fd59977 677 return 1;
678 }
679 TopoDS_Edge e1 = TopoDS::Edge(Sh1);
680 TopoDS_Edge e2 = TopoDS::Edge(Sh2);
681 if(e1.IsNull() || e2.IsNull()) {
586db386 682 di<<"Invalid type of arguments\n";
7fd59977 683 return 1;
684 }
7d0496dd 685
686 if (BRep_Tool::Degenerated(e1))
687 {
688 di << a[1] << " is degenerated\n";
689 return 1;
690 }
691
692 if (BRep_Tool::Degenerated(e2))
693 {
694 di << a[2] << " is degenerated\n";
695 return 1;
696 }
697
7fd59977 698 Standard_Real aTol = Precision::Confusion();
699 Standard_Real aDistDomain = 0.0;
700 Standard_Integer k = 3;
701 if(k < n)
91322f44 702 aTol = Draw::Atof(a[k++]);
7fd59977 703 if(k < n)
91322f44 704 aDistDomain = Draw::Atof(a[k++]);
7fd59977 705
706 ShapeAnalysis_Edge sae;
707 if(sae.CheckOverlapping(e1,e2,aTol,aDistDomain)) {
708 if(aDistDomain ==0.0)
7b5e532f 709 di<<"Edges are overlapping completely\n";
7fd59977 710 else {
7b5e532f 711 di<<"Edges are overlapped\n";
7fd59977 712 di<<"with tolerance = "<<aTol<<"\n";
713 di<<"on segment length = "<<aDistDomain<<"\n";
714 }
715 }
7b5e532f 716 else di<<"Edges are not overlapped\n";
7fd59977 717 return 0;
718}
719
720//=======================================================================
721//function : checkfclass2d
722//purpose :
723//=======================================================================
724
725static Standard_Integer checkfclass2d(Draw_Interpretor& di, Standard_Integer n, const char** a)
726{
727 if( n < 4) {
586db386 728 di<<"Invalid number of arguments\n";
7fd59977 729 return 1;
730 }
731 TopoDS_Shape Sh1 = DBRep::Get(a[1]);
91322f44 732 Standard_Real ucoord = Draw::Atof(a[2]);
733 Standard_Real vcoord = Draw::Atof(a[3]);
7fd59977 734 if(Sh1.IsNull() || Sh1.ShapeType()!= TopAbs_FACE) {
586db386 735 di<<"Invalid arguments\n";
7fd59977 736 return 1;
737 }
e2447a80 738 Standard_Real tol = Precision::Confusion();
739 if (n > 4)
740 {
741 tol = Atof(a[4]);
742 }
743
7fd59977 744 TopoDS_Face aFace = TopoDS::Face(Sh1);
745 gp_Pnt2d p2d(ucoord,vcoord);
e2447a80 746 BRepTopAdaptor_FClass2d f2d(aFace, tol);
7fd59977 747 TopAbs_State stat = f2d.Perform(p2d);
748 if(stat == TopAbs_OUT)
586db386 749 di<<"Point is OUT\n";
7fd59977 750 else if(stat == TopAbs_IN)
586db386 751 di<<"Point is IN\n";
7fd59977 752 else if(stat == TopAbs_ON)
586db386 753 di<<"Point is ON\n";
7fd59977 754 else
586db386 755 di<<"Point is UNKNOWN\n";
7fd59977 756 return 0;
757}
758
974c25ed
G
759static Standard_Integer connectedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
760{
761 if( n < 3) {
586db386 762 di<<"Invalid number of arguments. Should be : result shape [toler shared]\n";
974c25ed
G
763 return 1;
764 }
765 TopoDS_Shape aSh1 = DBRep::Get(a[2]);
766 if(aSh1.IsNull()) {
586db386 767 di<<"Shape is null\n";
974c25ed
G
768 return 1;
769 }
770 Standard_Real aTol = Precision::Confusion();
771 if( n > 3)
91322f44 772 aTol = Draw::Atof(a[3]);
974c25ed
G
773
774 Standard_Boolean shared = Standard_True;
775 if( n > 4)
91322f44 776 shared = (Draw::Atoi(a[4]) == 1);
974c25ed
G
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())
782 {
783 aSeqEdges->Append(aExpE.Current());
784 aMapEdges.Add(aExpE.Current());
785 }
786
787 ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges,aTol,shared,aSeqWires );
788 TopoDS_Compound aComp;
789 BRep_Builder aB;
790 aB.MakeCompound(aComp);
791 Standard_Integer i = 1;
792 for( ; i <= aSeqWires->Length() ; i++)
793 {
794 TopoDS_Shape aW = aSeqWires->Value(i);
586db386 795 di<<"Wire - "<<i<<" : \n";
974c25ed
G
796
797 TopExp_Explorer aExp1(aW, TopAbs_EDGE);
798 for( ; aExp1.More(); aExp1.Next())
799 {
800 if(shared)
801 {
802 Standard_Integer ind = aMapEdges.FindIndex(aExp1.Current());
803 di<<ind<<" ";
804 }
92e0a76a 805 else
974c25ed
G
806 {
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";
811 }
812 }
813
814 di<<"\n";
815 aB.Add( aComp,aSeqWires->Value(i));
816 }
817 DBRep::Set(a[1],aComp);
818 return 0;
819
820}
821
7fd59977 822//=======================================================================
823//function : InitCommands
824//purpose :
825//=======================================================================
826
827 void SWDRAW_ShapeFix::InitCommands(Draw_Interpretor& theCommands)
828{
829 static Standard_Integer initactor = 0;
c48e2889 830 if (initactor)
831 {
832 return;
833 }
834 initactor = 1;
7fd59977 835
836 Standard_CString g = SWDRAW::GroupName();
837
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",
843 __FILE__,stwire,g);
844 theCommands.Add ("reface","shape result : controle sens wire",
845 __FILE__,reface,g);
fbf3becf 846 theCommands.Add ("fixshape",
847"res shape [preci [maxpreci]] [{switches}]\n"
848" [-maxtaila <degrees>] [-maxtailw <width>]",
7fd59977 849 __FILE__,fixshape,g);
850// theCommands.Add ("testfill","result edge1 edge2",
851// __FILE__,XSHAPE_testfill,g);
852 theCommands.Add ("fixwgaps","result shape [toler=0]",
853 __FILE__,fixgaps,g);
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);
c3cca015 858 theCommands.Add ("fixsmallfaces","result shape [toler=1.]",
859 __FILE__,fixsmallfaces,g);
7fd59977 860 theCommands.Add ("checkoverlapedges","edge1 edge2 [toler domaindist]",
861 __FILE__,checkoverlapedges,g);
e2447a80 862 theCommands.Add ("checkfclass2d","face ucoord vcoord [tol]",
7fd59977 863 __FILE__,checkfclass2d,g);
974c25ed
G
864 theCommands.Add ("connectedges","res shape [toler shared]",
865 __FILE__,connectedges,g);
866
7fd59977 867}