b311480e |
1 | // Created on: 2000-03-16 |
973c2be1 |
2 | // Copyright (c) 2000-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
973c2be1 |
6 | // This library is free software; you can redistribute it and / or modify it |
7 | // under the terms of the GNU Lesser General Public version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
15 | #include <BOPTest.ixx> |
7fd59977 |
16 | #include <stdio.h> |
7fd59977 |
17 | #include <TCollection_AsciiString.hxx> |
18 | #include <TColStd_IndexedMapOfTransient.hxx> |
7fd59977 |
19 | #include <TopoDS_Shape.hxx> |
20 | #include <TopoDS_Vertex.hxx> |
91322f44 |
21 | #include <Draw.hxx> |
7fd59977 |
22 | #include <DBRep.hxx> |
7fd59977 |
23 | #include <gp_Pnt2d.hxx> |
24 | |
25 | #include <Geom_Curve.hxx> |
26 | #include <Geom2d_Curve.hxx> |
27 | #include <Geom_Surface.hxx> |
28 | |
29 | #include <TopoDS.hxx> |
30 | #include <TopoDS_Vertex.hxx> |
31 | #include <TopoDS_Edge.hxx> |
32 | #include <TopoDS_Face.hxx> |
33 | |
34 | #include <TopAbs_Orientation.hxx> |
35 | |
36 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
37 | #include <TopTools_ListOfShape.hxx> |
38 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
39 | #include <TopTools_MapOfShape.hxx> |
40 | #include <TopTools_IndexedMapOfShape.hxx> |
41 | |
42 | #include <BRep_TVertex.hxx> |
43 | #include <BRep_TEdge.hxx> |
44 | #include <BRep_ListOfCurveRepresentation.hxx> |
45 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
46 | #include <BRep_CurveRepresentation.hxx> |
47 | #include <BRep_Tool.hxx> |
48 | #include <BRep_Builder.hxx> |
49 | #include <BRep_TFace.hxx> |
50 | |
51 | #include <TopLoc_Location.hxx> |
52 | |
53 | #include <BRepLib.hxx> |
54 | |
55 | #include <TopExp.hxx> |
56 | #include <TopExp_Explorer.hxx> |
57 | |
58 | static |
59 | Standard_Integer breducetolerance (Draw_Interpretor&, Standard_Integer, const char** ); |
60 | static |
61 | Standard_Integer btolx (Draw_Interpretor&, Standard_Integer, const char** ); |
62 | static |
63 | Standard_Integer bopaddpcs (Draw_Interpretor&, Standard_Integer, const char** ); |
64 | // |
65 | static |
66 | void ProcessVertex(const TopoDS_Vertex&, |
4e57c75e |
67 | const TopTools_ListOfShape&, |
68 | const TopTools_ListOfShape&); |
7fd59977 |
69 | static |
70 | void ProcessEdge(const TopoDS_Edge&, const Standard_Real); |
71 | |
72 | static |
73 | void ReduceVertexTolerance (const TopoDS_Shape&); |
74 | |
75 | static |
76 | void ReduceFaceTolerance (const TopoDS_Shape&); |
77 | |
78 | static |
79 | void ReduceEdgeTolerance (const TopoDS_Shape&, const Standard_Real); |
80 | |
81 | |
82 | //======================================================================= |
83 | //function : TolerCommands |
84 | //purpose : |
85 | //======================================================================= |
86 | void BOPTest::TolerCommands(Draw_Interpretor& theCommands) |
87 | { |
88 | static Standard_Boolean done = Standard_False; |
89 | if (done) |
90 | return; |
91 | |
92 | done = Standard_True; |
93 | // Chapter's name |
94 | const char* g = "CCR commands"; |
95 | // |
96 | theCommands.Add("breducetolerance" , "Use >breducetolerance Shape [maxTol=0.01]", __FILE__, breducetolerance, g); |
97 | theCommands.Add("btolx" , "Use >btolx Shape [minTol=1.e-7]", __FILE__, btolx, g); |
98 | theCommands.Add("bopaddpcs" , "Use >bopaddpcs Shape" , __FILE__, bopaddpcs, g); |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : btolx |
103 | //purpose : |
104 | //======================================================================= |
105 | Standard_Integer btolx(Draw_Interpretor& di, Standard_Integer n, const char** a) |
106 | { |
107 | if (n<2) { |
108 | di << " Use >btolx Shape [minTol=1.e-7]\n"; |
109 | return 1; |
110 | } |
111 | |
112 | TopoDS_Shape aS = DBRep::Get(a[1]); |
113 | |
114 | if (aS.IsNull()) { |
115 | di << " Null shape is not allowed \n"; |
116 | return 1; |
117 | } |
118 | // |
119 | Standard_Real aTolEMin=1.e-7; |
120 | if (n==3) { |
91322f44 |
121 | aTolEMin=Draw::Atof(a[2]); |
7fd59977 |
122 | } |
123 | // |
124 | // Edge Tolerances |
125 | ReduceEdgeTolerance(aS, aTolEMin); |
126 | // |
127 | // Face Tolerances |
128 | ReduceFaceTolerance(aS); |
129 | // |
130 | // Vertex Tolerances |
131 | ReduceVertexTolerance(aS); |
132 | // |
133 | BRepLib::SameParameter(aS, 1.e-7, Standard_True); |
134 | // |
135 | DBRep::Set (a[1], aS); |
136 | return 0; |
137 | } |
138 | //======================================================================= |
139 | //function : ReduceEdgeTolerance |
140 | //purpose : |
141 | //======================================================================= |
142 | void ReduceEdgeTolerance (const TopoDS_Shape& aS, const Standard_Real aTolTreshold) |
143 | { |
144 | Standard_Integer i, aNbE; |
145 | TopTools_IndexedMapOfShape aEMap; |
146 | // |
147 | TopExp::MapShapes(aS, TopAbs_EDGE, aEMap); |
148 | // |
149 | aNbE=aEMap.Extent(); |
150 | for (i=1; i<=aNbE; i++) { |
151 | const TopoDS_Edge& aE= TopoDS::Edge(aEMap(i)); |
152 | |
153 | ProcessEdge(aE, aTolTreshold); |
154 | } |
155 | } |
156 | //======================================================================= |
157 | //function : ReduceFaceTolerance |
158 | //purpose : |
159 | //======================================================================= |
160 | void ReduceFaceTolerance (const TopoDS_Shape& aS) |
161 | { |
162 | Standard_Integer i, j, aNbF, aNbE; |
163 | Standard_Real aTolE, aTolx, aTolEMin; |
164 | TopTools_IndexedMapOfShape aFMap, aEMap; |
165 | // |
166 | aTolEMin=1.e-7; |
167 | // |
168 | TopExp::MapShapes(aS, TopAbs_FACE, aFMap); |
169 | aNbF=aFMap.Extent(); |
170 | for (i=1; i<=aNbF; i++) { |
171 | aTolx=1.e6; |
172 | const TopoDS_Face& aF= TopoDS::Face(aFMap(i)); |
173 | Handle(BRep_TFace)& aTF = *((Handle(BRep_TFace)*)&aF.TShape()); |
174 | // |
175 | TopExp::MapShapes(aF, TopAbs_EDGE, aEMap); |
176 | aNbE=aEMap.Extent(); |
177 | for (j=1; j<=aNbE; ++j) { |
178 | const TopoDS_Edge& aE= TopoDS::Edge(aEMap(j)); |
179 | aTolE =BRep_Tool::Tolerance(aE); |
180 | if (aTolE<aTolx) { |
181 | aTolx=aTolE; |
182 | } |
183 | } |
184 | aTolE=(aTolx>aTolEMin) ? aTolx : aTolEMin; |
185 | aTF->Tolerance(aTolE); |
186 | } |
187 | } |
188 | //======================================================================= |
189 | //function : ReduceVertexTolerance |
190 | //purpose : |
191 | //======================================================================= |
192 | void ReduceVertexTolerance (const TopoDS_Shape& aS) |
193 | { |
194 | Standard_Integer i, aNbV; |
195 | TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap; |
196 | |
197 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap); |
198 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap); |
199 | |
200 | aNbV=aVEMap.Extent(); |
201 | for (i=1; i<=aNbV; i++) { |
202 | const TopoDS_Vertex& aV= TopoDS::Vertex(aVEMap.FindKey(i)); |
203 | const TopTools_ListOfShape& aLE=aVEMap(i); |
204 | const TopTools_ListOfShape& aLF=aVFMap.FindFromKey(aV); |
205 | |
206 | ProcessVertex(aV, aLE, aLF); |
207 | } |
208 | } |
209 | //======================================================================= |
210 | //function : ProcessEdge |
211 | //purpose : |
212 | //======================================================================= |
213 | void ProcessEdge(const TopoDS_Edge& aE, const Standard_Real aTolTreshold) |
214 | { |
215 | Standard_Integer i, aNb=23; |
216 | Standard_Real aTolE, aD2, aTolMax2, aT1, aT2, aT, dT; |
217 | gp_Pnt aPC3D, aP3D; |
218 | gp_Pnt2d aPC2D; |
219 | |
220 | //TopTools_ListIteratorOfListOfShape anIt;// Wng in Gcc 3.0 |
221 | BRep_ListIteratorOfListOfCurveRepresentation itcr; |
222 | // |
223 | Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aT1, aT2); |
224 | if (aC3D.IsNull()) { |
225 | return; |
226 | } |
227 | // |
228 | dT=(aT2-aT1)/aNb; |
229 | // |
230 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); |
231 | const TopLoc_Location& Eloc = aE.Location(); |
232 | // |
233 | aTolMax2=-1.e6; |
234 | const BRep_ListOfCurveRepresentation& aLCR=TE->Curves(); |
235 | // |
236 | itcr.Initialize(aLCR); |
237 | for (; itcr.More(); itcr.Next()) { |
238 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
239 | const TopLoc_Location& loc = cr->Location(); |
240 | TopLoc_Location L = (Eloc * loc);//.Predivided(aV.Location()); |
241 | // |
242 | // 3D-Curve |
243 | if (cr->IsCurve3D()) { |
244 | continue; |
245 | } |
246 | // |
247 | // 2D-Curve |
248 | else if (cr->IsCurveOnSurface()) { |
249 | const Handle(Geom2d_Curve)& aC2D = cr->PCurve(); |
250 | if (aC2D.IsNull()) { |
251 | continue; |
252 | } |
253 | // Surface |
254 | const Handle(Geom_Surface)& aS=cr->Surface(); |
255 | // |
256 | // 2D-point treatment |
257 | for (i=0; i<=aNb; ++i) { |
258 | aT=aT1+i*dT; |
259 | if (i==aNb) { |
260 | aT=aT2; |
261 | } |
262 | aPC3D=aC3D->Value(aT); |
263 | aPC2D=aC2D->Value(aT); |
264 | aS->D0(aPC2D.X(), aPC2D.Y(), aP3D); |
265 | aP3D.Transform(L.Transformation()); |
266 | aD2=aPC3D.SquareDistance(aP3D); |
267 | if (aD2 > aTolMax2) { |
268 | aTolMax2=aD2; |
269 | } |
270 | } |
271 | } //if (cr->IsCurveOnSurface()) |
272 | }//for (; itcr.More(); itcr.Next()) |
273 | |
274 | //######################################################### |
275 | // |
276 | if (aTolMax2<0.){ |
277 | return; |
278 | } |
279 | // |
280 | aTolE =BRep_Tool::Tolerance(aE); |
281 | // |
282 | aTolMax2=sqrt(aTolMax2); |
283 | |
284 | //printf(" aTolMax=%15.10lf, aTolWas=%15.10lf\n", aTolMax2, aTolE); |
285 | |
286 | Standard_Real aTolSet; |
287 | aTolSet=(aTolMax2>aTolTreshold) ? aTolMax2 : aTolTreshold; |
288 | |
289 | TE->Tolerance(aTolSet); |
290 | } |
291 | //======================================================================= |
292 | //function : ProcessVertex |
293 | //purpose : |
294 | //======================================================================= |
295 | void ProcessVertex(const TopoDS_Vertex& aV, |
296 | const TopTools_ListOfShape& aLE, |
297 | const TopTools_ListOfShape& aLF) |
298 | { |
299 | Standard_Real aTol, aTol2, aD2, aTolMax2, aTolE, aParam; |
300 | gp_Pnt aPC3D; |
301 | gp_Pnt2d aPC2D; |
302 | TopAbs_Orientation anOrV; |
303 | |
304 | TopTools_ListIteratorOfListOfShape anIt; |
305 | TopTools_MapOfShape aProcessedEdges; |
306 | TopExp_Explorer aVExp; |
307 | |
308 | BRep_ListIteratorOfListOfCurveRepresentation itcr; |
309 | // |
310 | aTolMax2=-1.e6; |
311 | // |
312 | Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape()); |
313 | const gp_Pnt& aPV3D = TV->Pnt(); |
314 | aTol =BRep_Tool::Tolerance(aV); |
315 | aTol2=aTol*aTol; |
316 | // |
317 | anIt.Initialize(aLE); |
318 | for (; anIt.More(); anIt.Next()) { |
319 | const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value()); |
320 | // |
321 | if (aProcessedEdges.Contains(aE)) { |
322 | continue; |
323 | } |
324 | aProcessedEdges.Add(aE); |
325 | // |
326 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); |
327 | const TopLoc_Location& Eloc = aE.Location(); |
328 | // |
329 | aVExp.Init(aE, TopAbs_VERTEX); |
330 | for (; aVExp.More(); aVExp.Next()) { |
331 | const TopoDS_Vertex& aVx=TopoDS::Vertex(aVExp.Current()); |
332 | // |
333 | if (!aVx.IsSame(aV)) { |
334 | continue; |
335 | } |
336 | // |
337 | anOrV=aVx.Orientation(); |
338 | if (!(anOrV==TopAbs_FORWARD || anOrV==TopAbs_REVERSED)) { |
339 | continue; |
340 | } |
341 | // |
342 | const BRep_ListOfCurveRepresentation& aLCR=TE->Curves(); |
343 | itcr.Initialize(aLCR); |
344 | for (; itcr.More(); itcr.Next()) { |
345 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
346 | const TopLoc_Location& loc = cr->Location(); |
347 | TopLoc_Location L = (Eloc * loc).Predivided(aV.Location()); |
348 | // |
349 | // 3D-Curve |
350 | if (cr->IsCurve3D()) { |
351 | const Handle(Geom_Curve)& aC3D = cr->Curve3D(); |
352 | // |
353 | if (aC3D.IsNull()) { |
354 | continue; |
355 | } |
356 | // 3D-point treatment |
357 | aParam=BRep_Tool::Parameter(aVx, aE); |
358 | aPC3D= aC3D->Value(aParam); |
359 | aPC3D.Transform(L.Transformation()); |
360 | aD2=aPV3D.SquareDistance(aPC3D); |
361 | if (aD2 > aTolMax2) { |
362 | aTolMax2=aD2; |
363 | } |
364 | // |
365 | }//if (cr->IsCurve3D()) |
366 | // |
367 | // 2D-Curve |
368 | else if (cr->IsCurveOnSurface()) { |
369 | const Handle(Geom2d_Curve)& aC2D = cr->PCurve(); |
370 | if (aC2D.IsNull()) { |
371 | continue; |
372 | } |
373 | // Surface |
374 | const Handle(Geom_Surface)& aS=cr->Surface(); |
375 | // |
376 | // 2D-point treatment |
377 | aParam=BRep_Tool::Parameter(aVx, aE, aS, L); |
378 | aPC2D=aC2D->Value(aParam); |
379 | aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D); |
380 | aPC3D.Transform(L.Transformation()); |
381 | aD2=aPV3D.SquareDistance(aPC3D); |
382 | if (aD2 > aTolMax2) { |
383 | aTolMax2=aD2; |
384 | } |
385 | } //if (cr->IsCurveOnSurface()) |
386 | |
387 | }//for (; itcr.More(); itcr.Next()) |
388 | }//for (; aVExp.More(); aVExp.Next()) |
389 | }//for (; anIt.More(); anIt.Next()) |
390 | //######################################################### |
391 | // |
392 | // Reducing |
393 | if (aTolMax2<0.){ |
394 | return; |
395 | } |
396 | // |
397 | aTolMax2=sqrt(aTolMax2); |
398 | if (aTolMax2>aTol) { |
399 | return; |
400 | } |
401 | // |
402 | aProcessedEdges.Clear(); |
403 | anIt.Initialize(aLE); |
404 | for (; anIt.More(); anIt.Next()) { |
405 | const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value()); |
406 | |
407 | if (aProcessedEdges.Contains(aE)) { |
408 | continue; |
409 | } |
410 | aProcessedEdges.Add(aE); |
411 | |
412 | aTolE =BRep_Tool::Tolerance(aE); |
413 | if (aTolMax2 < aTolE) { |
414 | aTolMax2=aTolE; |
415 | } |
416 | } |
417 | // |
418 | aProcessedEdges.Clear(); |
419 | anIt.Initialize(aLF); |
420 | for (; anIt.More(); anIt.Next()) { |
421 | const TopoDS_Face& aF=TopoDS::Face(anIt.Value()); |
422 | |
423 | if (aProcessedEdges.Contains(aF)) { |
424 | continue; |
425 | } |
426 | aProcessedEdges.Add(aF); |
427 | |
428 | aTolE =BRep_Tool::Tolerance(aF); |
429 | if (aTolMax2 < aTolE) { |
430 | aTolMax2=aTolE; |
431 | } |
432 | } |
433 | // |
434 | if (aTolMax2>aTol) { |
435 | return; |
436 | } |
437 | // |
438 | // Update Tolerance |
439 | TV->Tolerance(aTolMax2); |
440 | } |
441 | //======================================================================= |
442 | //function : breducetolerance |
443 | //purpose : |
444 | //======================================================================= |
445 | Standard_Integer breducetolerance(Draw_Interpretor& di, |
446 | Standard_Integer n, |
447 | const char** a) |
448 | { |
449 | if (n<2) { |
450 | di << " Use >bupdatetolerance Shape\n"; |
451 | return 1; |
452 | } |
453 | |
454 | TopoDS_Shape aS = DBRep::Get(a[1]); |
455 | |
456 | if (aS.IsNull()) { |
457 | di << " Null shape is not allowed \n"; |
458 | return 1; |
459 | } |
460 | ReduceVertexTolerance(aS); |
461 | DBRep::Set (a[1], aS); |
462 | |
463 | return 0; |
464 | } |
465 | // |
466 | // |
467 | static |
468 | void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di); |
469 | |
470 | //======================================================================= |
471 | //function : bopaddpcs |
472 | //purpose : Some Edgesdo not contain P-Curveson Faces to which they belong to. |
473 | // These faces usually based on Geom_Plane surface. |
474 | // To prevent sophisticated treatment the Command "bopaddpcs: |
475 | // adds P-Curves for the edges . |
476 | //======================================================================= |
477 | Standard_Integer bopaddpcs(Draw_Interpretor& di, Standard_Integer n, const char** a) |
478 | { |
479 | if (n<2) { |
480 | di << " Use >bopaddpcs Shape\n"; |
481 | return 1; |
482 | } |
483 | |
484 | TopoDS_Shape aS = DBRep::Get(a[1]); |
485 | |
486 | if (aS.IsNull()) { |
487 | di << " Null shape is not allowed \n"; |
488 | return 1; |
489 | } |
490 | // |
491 | PreparePCurves(aS, di); |
492 | // |
493 | DBRep::Set (a[1], aS); |
494 | return 0; |
495 | } |
496 | |
497 | //======================================================================= |
498 | //function : PreparePCurves |
499 | //purpose : |
500 | //======================================================================= |
501 | void PreparePCurves(const TopoDS_Shape& aShape, Draw_Interpretor& di) |
502 | { |
503 | Standard_Integer i, aNbE; |
504 | Standard_Real aTolE, aT1, aT2; |
505 | TopTools_IndexedDataMapOfShapeListOfShape aEFMap; |
506 | TopLoc_Location aLoc; |
507 | Handle(Geom_Curve) aC3D; |
508 | Handle(Geom2d_Curve) aC2D; |
509 | BRep_Builder aBB; |
510 | // |
511 | TopExp::MapShapesAndAncestors (aShape, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
512 | // |
513 | aNbE=aEFMap.Extent(); |
514 | for (i=1; i<=aNbE; ++i) { |
515 | const TopoDS_Edge& aE=TopoDS::Edge(aEFMap.FindKey(i)); |
516 | // |
517 | if (BRep_Tool::Degenerated(aE)) { |
518 | continue; |
519 | } |
520 | // |
521 | aC3D=BRep_Tool::Curve(aE, aT1, aT2); |
522 | if (aC3D.IsNull()) { |
523 | continue; |
524 | } |
525 | aTolE=BRep_Tool::Tolerance(aE); |
526 | // |
527 | const TopTools_ListOfShape& aLF=aEFMap(i); |
528 | TopTools_ListIteratorOfListOfShape aFIt(aLF); |
529 | for (; aFIt.More(); aFIt.Next()) { |
530 | const TopoDS_Face& aF=TopoDS::Face(aFIt.Value()); |
531 | // |
532 | // Map of surfaces on which the edge lays . |
533 | TColStd_IndexedMapOfTransient aSCRMap; |
534 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); |
535 | const BRep_ListOfCurveRepresentation& aLCR=TE->Curves(); |
536 | BRep_ListIteratorOfListOfCurveRepresentation itcr; |
537 | itcr.Initialize(aLCR); |
538 | for (; itcr.More(); itcr.Next()) { |
539 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
540 | // |
541 | if (cr->IsCurveOnSurface()) { |
542 | const Handle(Geom_Surface)& aSCR=cr->Surface(); |
543 | aSCRMap.Add(aSCR); |
544 | } |
545 | // |
546 | } |
547 | // |
548 | const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc); |
549 | if (!aSCRMap.Contains(aS)) { |
550 | // try to obtain 2D curve |
551 | aC2D=BRep_Tool::CurveOnSurface(aE, aS, aLoc, aT1, aT2); |
552 | if (aC2D.IsNull()) { |
553 | di << " Warning: Can not obtain P-Curve\n"; |
554 | continue; |
555 | } |
556 | else { |
557 | aBB.UpdateEdge(aE, aC2D, aF, aTolE); |
558 | } |
559 | } |
560 | } |
561 | } |
562 | } |