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