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