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