0023024: Update headers of OCCT files
[occt.git] / src / BOPTools / BOPTools_Tools.cxx
CommitLineData
b311480e 1// Created on: 2000-11-16
2// Created by: Peter KURNEV
3// Copyright (c) 2000-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <BOPTools_Tools.ixx>
23
24#include <Precision.hxx>
25
26#include <TopExp_Explorer.hxx>
27#include <TopTools_IndexedDataMapOfShapeShape.hxx>
28
29#include <TopoDS.hxx>
30#include <TopoDS_Edge.hxx>
31#include <TopoDS_Shape.hxx>
32#include <TopoDS_Vertex.hxx>
33#include <TopoDS_Iterator.hxx>
34
35#include <gp_Pnt.hxx>
36#include <gp_XYZ.hxx>
37#include <gp_Pnt2d.hxx>
38
39#include <BRep_Builder.hxx>
40#include <BRepBuilderAPI_MakeEdge.hxx>
41#include <BRep_Tool.hxx>
42
43#include <BRepAdaptor_Curve.hxx>
44#include <BRepAdaptor_Surface.hxx>
45
46#include <GeomAdaptor_Curve.hxx>
47#include <Geom_Curve.hxx>
48#include <Geom_Surface.hxx>
49#include <GeomAPI_ProjectPointOnSurf.hxx>
50#include <GeomAbs_CurveType.hxx>
51
52#include <BooleanOperations_OnceExplorer.hxx>
53
54#include <IntTools_ShrunkRange.hxx>
55#include <IntTools_Tools.hxx>
56#include <IntTools_Range.hxx>
57
58
59static
60 void CopySrc(const TopoDS_Shape& E,
61 TopTools_IndexedDataMapOfShapeShape& aMapSS,
62 TopoDS_Shape& anEdge);
63
64//=======================================================================
65// function: IsBlockInOnFace
66// purpose:
67//=======================================================================
68 Standard_Boolean BOPTools_Tools::IsBlockInOnFace (const BOPTools_PaveBlock& aPB1,
69 const TopoDS_Face& aF,
4f189102 70 const Handle(IntTools_Context)& aContext)
7fd59977 71{
72 Standard_Boolean bFlag;
73 Standard_Real f1, l1, ULD, VLD;
74 gp_Pnt2d aP2D;
75 gp_Pnt aP11, aP12;
76 //
77 // Edge's data
78 const IntTools_ShrunkRange& aSR1=aPB1.ShrunkRange();
79 const TopoDS_Edge& aE1=aSR1.Edge();
80
81 const IntTools_Range& aShrR= aSR1.ShrunkRange();
82 aShrR.Range(f1, l1);
83 //
84 Standard_Real dt=0.0075, k;//dt=0.001, k;
85 k=dt*(l1-f1);
86 f1=f1+k;
87 l1=l1-k;
88 //
89 // Treatment P11
90 BOPTools_Tools::PointOnEdge(aE1, f1, aP11);
91 //
4f189102 92 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
7fd59977 93 aProjector.Perform(aP11);
94 //
95 bFlag=aProjector.IsDone();
96 if (!bFlag) {
97 return bFlag;
98 }
99
100 aProjector.LowerDistanceParameters(ULD, VLD);
101 aP2D.SetCoord(ULD, VLD);
102 //
4f189102 103 bFlag=aContext->IsPointInOnFace (aF, aP2D);
7fd59977 104 //
105 if (!bFlag) {
106 return bFlag;
107 }
108 //
109 // Treatment P12
110 BOPTools_Tools::PointOnEdge(aE1, l1, aP12);
111 //
112 aProjector.Perform(aP12);
113 //
114 bFlag=aProjector.IsDone();
115 if (!bFlag) {
116 return bFlag;
117 }
118
119 aProjector.LowerDistanceParameters(ULD, VLD);
120 aP2D.SetCoord(ULD, VLD);
121 //
4f189102 122 bFlag=aContext->IsPointInOnFace (aF, aP2D);
7fd59977 123 //
124 if (!bFlag) {
125 return bFlag;
126 }
127 //
128 // Treatment intemediate
129 Standard_Real m1, aTolF, aTolE, aTol, aDist;
130 m1=IntTools_Tools::IntermediatePoint(f1, l1);
131 BOPTools_Tools::PointOnEdge(aE1, m1, aP12);
132 //
133 aProjector.Perform(aP12);
134 //
135 bFlag=aProjector.IsDone();
136 if (!bFlag) {
137 return bFlag;
138 }
139 //
140 aTolE=BRep_Tool::Tolerance(aE1);
141 aTolF=BRep_Tool::Tolerance(aF);
142 aTol=aTolE+aTolF;
143 aDist=aProjector.LowerDistance();
144 if (aDist > aTol){
145 return Standard_False;
146 }
147
148 aProjector.LowerDistanceParameters(ULD, VLD);
149 aP2D.SetCoord(ULD, VLD);
150 //
4f189102 151 bFlag=aContext->IsPointInOnFace (aF, aP2D);
7fd59977 152 //
153 if (!bFlag) {
154 return bFlag;
155 }
156 return bFlag;
157}
158
159//=======================================================================
160// function: IsBlocksCoinside
161// purpose:
162//=======================================================================
163 Standard_Boolean BOPTools_Tools::IsBlocksCoinside(const BOPTools_PaveBlock& aPB1,
164 const BOPTools_PaveBlock& aPB2)
165{
166 //
167 Standard_Real f1, l1, aTol1;
168 const IntTools_ShrunkRange aSR1=aPB1.ShrunkRange();
169 const TopoDS_Edge& aE1=aSR1.Edge();
170 aTol1=BRep_Tool::Tolerance(aE1);
171 aPB1.Parameters(f1, l1);
172 gp_Pnt aP11, aP12;
173 BOPTools_Tools::PointOnEdge(aE1, f1, aP11);
174 BOPTools_Tools::PointOnEdge(aE1, l1, aP12);
175 //
176 Standard_Real f2, l2, aTol2;
177 const IntTools_ShrunkRange aSR2=aPB2.ShrunkRange();
178 const TopoDS_Edge& aE2=aSR2.Edge();
179 aTol2=BRep_Tool::Tolerance(aE2);
180 aPB2.Parameters(f2, l2);
181 gp_Pnt aP21, aP22;
182 BOPTools_Tools::PointOnEdge(aE2, f2, aP21);
183 BOPTools_Tools::PointOnEdge(aE2, l2, aP22);
184 ////
185 Standard_Real aTolSum, d1121, d1122, d1222, d1221;
186
187 aTolSum=1.05*(aTol1+aTol2);
188
189 d1121=aP11.Distance(aP21);
190 if (d1121<aTolSum) {
191 d1222=aP12.Distance(aP22);
192 if (d1222<aTolSum) {
193 return Standard_True;
194 }
195 }
196 //
197 d1122=aP11.Distance(aP22);
198 if (d1122<aTolSum) {
199 d1221=aP12.Distance(aP21);
200 if (d1221<aTolSum) {
201 return Standard_True;
202 }
203 }
204 return Standard_False;
205}
206//
207//=======================================================================
208// function: UpdateVertex
209// purpose:
210//=======================================================================
211 void BOPTools_Tools::UpdateVertex (const TopoDS_Vertex& aVF,
212 const TopoDS_Vertex& aNewVertex)
213{
214 Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
215 //
216 gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
217 gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
218 aTolVF=BRep_Tool::Tolerance(aVF);
219 aTolNewVertex=BRep_Tool::Tolerance(aNewVertex);
220
221 aDist=aPVF.Distance(aPNewVertex);
222 aNewTol=aDist+aTolNewVertex;
223
224 if (aNewTol>aTolVF) {
225 BRep_Builder BB;
226 BB.UpdateVertex (aVF, aNewTol+aDTol);
227 }
228}
229//
230//=======================================================================
231// function: UpdateVertex
232// purpose:
233//=======================================================================
234 void BOPTools_Tools::UpdateVertex (const TopoDS_Edge& aE,
235 const Standard_Real aT,
236 const TopoDS_Vertex& aV)
237{
238 Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
239 gp_Pnt aPc;
240
241 gp_Pnt aPv=BRep_Tool::Pnt(aV);
242 aTolV=BRep_Tool::Tolerance(aV);
243
244 Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast);
245 aC3D->D0(aT, aPc);
246 aDist=aPv.Distance(aPc);
247 if (aDist>aTolV) {
248 BRep_Builder BB;
249 BB.UpdateVertex (aV, aDist+aDTol);
250 }
251}
252//
253//=======================================================================
254// function: UpdateVertex
255// purpose:
256//=======================================================================
257 void BOPTools_Tools::UpdateVertex (const IntTools_Curve& aC,
258 const Standard_Real aT,
259 const TopoDS_Vertex& aV)
260{
261 Standard_Real aTolV, aDist, aDTol=1.e-12;
262 gp_Pnt aPc;
263
264 gp_Pnt aPv=BRep_Tool::Pnt(aV);
265 aTolV=BRep_Tool::Tolerance(aV);
266
267 Handle(Geom_Curve) aC3D=aC.Curve();
268 aC3D->D0(aT, aPc);
269 aDist=aPv.Distance(aPc);
270 if (aDist>aTolV) {
271 BRep_Builder BB;
272 BB.UpdateVertex (aV, aDist+aDTol);
273 }
274}
275//=======================================================================
276// function: MakeSectEdge
277// purpose:
278//=======================================================================
279 void BOPTools_Tools::MakeSectEdge(const IntTools_Curve& aIC,
280 const TopoDS_Vertex& aV1,
281 const Standard_Real aP1,
282 const TopoDS_Vertex& aV2,
283 const Standard_Real aP2,
284 TopoDS_Edge& aNewEdge)
285{
286 Handle(Geom_Curve) aC=aIC.Curve ();
287
288 BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
289
290 const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
291 //
292 // Range must be as it was !
293 BRep_Builder aBB;
294 aBB.Range (aE, aP1, aP2);
295 //
296 aNewEdge=aE;
297
298}
299
300//=======================================================================
301// function: MakeSplitEdge
302// purpose:
303//=======================================================================
304 void BOPTools_Tools::MakeSplitEdge(const TopoDS_Edge& aE,
305 const TopoDS_Vertex& aV1,
306 const Standard_Real aP1,
307 const TopoDS_Vertex& aV2,
308 const Standard_Real aP2,
309 TopoDS_Edge& aNewEdge)
310{
311 Standard_Real f, l, aTol;
312 Handle(Geom_Curve) aC=BRep_Tool::Curve (aE, f, l);
313 aTol=BRep_Tool::Tolerance(aE);
314 //
315 // MakeEdge is used for chechking all input data only
316 BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
317 //ZZ const TopoDS_Edge& E1=TopoDS::Edge(aMakeEdge.Shape());
318 TopoDS_Edge E=aE;
319 E.EmptyCopy();
320
321 BRep_Builder BB;
322 BB.Add (E, aV1);
323 BB.Add (E, aV2);
324 BB.Range(E, aP1, aP2);
325 BB.UpdateEdge(E, aTol);
326 aNewEdge=E;
327}
328
329//=======================================================================
330// function: MakeNewVertex
331// purpose:
332//=======================================================================
333 void BOPTools_Tools::MakeNewVertex(const TopoDS_Vertex& aV1,
334 const TopoDS_Vertex& aV2,
335 TopoDS_Vertex& aNewVertex)
336{
337 gp_Pnt aPnt1=BRep_Tool::Pnt(aV1);
338 Standard_Real aTol1=BRep_Tool::Tolerance(aV1);
339
340 gp_Pnt aPnt2=BRep_Tool::Pnt(aV2);
341 Standard_Real aTol2=BRep_Tool::Tolerance(aV2);
342
343 Standard_Real aMaxTol, aDist;
344
345 aDist=aPnt1.Distance(aPnt2);
346 aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
347 aMaxTol=aMaxTol+0.5*aDist;
348
349 const gp_XYZ& aXYZ1=aPnt1.XYZ();
350 const gp_XYZ& aXYZ2=aPnt2.XYZ();
351 gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
352
353 gp_Pnt aNewPnt(aNewXYZ);
354 BRep_Builder aBB;
355 aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
356}
357 //=======================================================================
358// function: MakeNewVertex
359// purpose:
360//=======================================================================
361 void BOPTools_Tools::MakeNewVertex(const gp_Pnt& aP,
362 const Standard_Real aTol,
363 TopoDS_Vertex& aNewVertex)
364{
365 BRep_Builder aBB;
366 aBB.MakeVertex (aNewVertex, aP, aTol);
367}
368
369//=======================================================================
370// function: MakeNewVertex
371// purpose:
372//=======================================================================
373 void BOPTools_Tools::MakeNewVertex(const TopoDS_Edge& aE1,
374 const Standard_Real aParm1,
375 const TopoDS_Edge& aE2,
376 const Standard_Real aParm2,
377 TopoDS_Vertex& aNewVertex)
378{
379 Standard_Real aTol1, aTol2, aMaxTol, aDist;
380 gp_Pnt aPnt1, aPnt2;
381
382 PointOnEdge (aE1, aParm1, aPnt1);
383 PointOnEdge (aE2, aParm2, aPnt2);
384
385 aTol1=BRep_Tool::Tolerance(aE1);
386 aTol2=BRep_Tool::Tolerance(aE2);
387
388 aDist=aPnt1.Distance(aPnt2);
389 aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
390 aMaxTol=aMaxTol+0.5*aDist;
391
392 const gp_XYZ& aXYZ1=aPnt1.XYZ();
393 const gp_XYZ& aXYZ2=aPnt2.XYZ();
394 gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
395
396 gp_Pnt aNewPnt(aNewXYZ);
397 BRep_Builder aBB;
398 aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
399}
400//=======================================================================
401// function: MakeNewVertex
402// purpose:
403//=======================================================================
404 void BOPTools_Tools::MakeNewVertex(const TopoDS_Edge& aE1,
405 const Standard_Real aParm1,
406 const TopoDS_Face& aF1,
407 TopoDS_Vertex& aNewVertex)
408{
409 Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
410 gp_Pnt aPnt;
411
412 PointOnEdge (aE1, aParm1, aPnt);
413
414 aTol1=BRep_Tool::Tolerance(aE1);
415 aTol2=BRep_Tool::Tolerance(aF1);
416 //
417 //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
418 aMaxTol=aTol1+aTol2+delta;
419 //
420 BRep_Builder aBB;
421 aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
422}
423
424//=======================================================================
425// function: PointOnEdge
426// purpose:
427//=======================================================================
428 void BOPTools_Tools::PointOnEdge(const TopoDS_Edge& aE,
429 const Standard_Real aParm,
430 gp_Pnt& aPnt)
431{
432 Standard_Real f, l;
433 Handle(Geom_Curve) C1=BRep_Tool::Curve(aE, f, l);
434 C1->D0(aParm, aPnt);
435}
436
437//=======================================================================
438//function : CopySource
439//purpose :
440//=======================================================================
441 void BOPTools_Tools::CopySource(const TopoDS_Shape& aSS,
442 TopoDS_Shape& aSD)
443{
444 TopTools_IndexedDataMapOfShapeShape aMapSS;
445 CopySrc (aSS, aMapSS, aSD);
446}
447
448//=======================================================================
449//function : MapShapes
450//purpose :
451//=======================================================================
452 void BOPTools_Tools::MapShapes(const TopoDS_Shape& aS,
453 TopTools_IndexedMapOfShape& aM)
454{
455 aM.Add(aS);
456 TopoDS_Iterator anIt;
457 anIt.Initialize(aS);
458 for (; anIt.More(); anIt.Next()) {
459 const TopoDS_Shape& aSx=anIt.Value();
460 BOPTools_Tools::MapShapes(aSx, aM);
461 }
462}
463
464//=======================================================================
465//function : CorrectRange
466//purpose :
467//=======================================================================
468 void BOPTools_Tools::CorrectRange(const TopoDS_Edge& aE1,
469 const TopoDS_Edge& aE2,
470 const IntTools_Range& aSR,
471 IntTools_Range& aNewSR)
472{
473 Standard_Integer i;
474 Standard_Real aRes, aTolE1, aTolE2, aTF, aTL, dT;
475 BRepAdaptor_Curve aBC;
476 GeomAbs_CurveType aCT;
477 gp_Pnt aP;
478 gp_Vec aDer;
479 //
480 aNewSR=aSR;
481 //
482 //modified by NIZNHY-PKV Tue Feb 10 08:47:03 2009f
483 aBC.Initialize(aE1);
484 aCT=aBC.GetType();
485 if (aCT==GeomAbs_Line) {
486 return;
487 }
488 //modified by NIZNHY-PKV Tue Feb 10 08:47:06 2009t
489 //
490 dT=Precision::PConfusion();
491 aTF=aSR.First();
492 aTL=aSR.Last();
493 //
494 //modified by NIZNHY-PKV Tue Feb 10 08:47:39 2009f
495 /*
496 aBC.Initialize(aE1);
497 aCT=aBC.GetType();
498 */
499 //modified by NIZNHY-PKV Tue Feb 10 08:47:43 2009t
500 //
501 aTolE1=BRep_Tool::Tolerance(aE1);
502 aTolE2=BRep_Tool::Tolerance(aE2);
503 //
504 for(i=0; i<2; ++i) {
505 aRes = 2.*(aTolE1 + aTolE2);
506 //
507 if (aCT==GeomAbs_BezierCurve ||
508 aCT==GeomAbs_BSplineCurve||
509 aCT==GeomAbs_OtherCurve) {
510
511 if(!i){
512 aBC.D1 (aTF, aP, aDer);
513 }
514 else {
515 aBC.D1 (aTL, aP, aDer);
516 }
517 //
518 Standard_Real aMgn = aDer.Magnitude();
519
520 if(aMgn > 1.e-12) {
521 aRes = aRes/aMgn ;
522 }
523 else {
524 aRes = aBC.Resolution(aRes);
525 }
526 } // if (aCT==GeomAbs_BezierCurve||...
527 else {
528 aRes = aBC.Resolution(aRes);
529 }
530 //
531 if(!i) {
532 aNewSR.SetFirst (aTF+aRes);
533 }
534 else {
535 aNewSR.SetLast (aTL-aRes);
536 }
537 //
538 if ((aNewSR.Last()-aNewSR.First()) < dT) {
539 aNewSR=aSR;
540 }
541 //aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
542 }
543}
544
545//=======================================================================
546//function : CorrectRange
547//purpose :
548//=======================================================================
549 void BOPTools_Tools::CorrectRange(const TopoDS_Edge& aE,
550 const TopoDS_Face& aF,
551 const IntTools_Range& aSR,
552 IntTools_Range& aNewSR)
553{
554 Standard_Integer i;
555 Standard_Real aRes, aTolF, aTF, aTL, dT;
556 BRepAdaptor_Curve aBC;
557 GeomAbs_CurveType aCT;
558 gp_Pnt aP;
559 gp_Vec aDer;
560 //
561 aNewSR=aSR;
562 //
563 dT=Precision::PConfusion();
564 aTF=aSR.First();
565 aTL=aSR.Last();
566 //
567 aBC.Initialize(aE);
568 aCT=aBC.GetType();
569 //
570 aTolF=BRep_Tool::Tolerance(aF);
571 //
572 for(i=0; i<2; ++i) {
573 aRes =aTolF;
574
575 if (aCT==GeomAbs_BezierCurve ||
576 aCT==GeomAbs_BSplineCurve||
577 aCT==GeomAbs_OtherCurve) {
578
579 if(!i){
580 aBC.D1 (aTF, aP, aDer);
581 }
582 else {
583 aBC.D1 (aTL, aP, aDer);
584 }
585 //
586 Standard_Real aMgn = aDer.Magnitude();
587
588 if(aMgn > 1.e-12) {
589 aRes = aRes/aMgn ;
590 }
591 else {
592 aRes = aBC.Resolution(aRes);
593 }
594 } // if (aCT==GeomAbs_BezierCurve||...
595 else {
596 aRes = aBC.Resolution(aRes);
597 }
598 //
599 if(!i) {
600 aNewSR.SetFirst (aTF+aRes);
601 }
602 else {
603 aNewSR.SetLast (aTL-aRes);
604 }
605 //
606 if ((aNewSR.Last()-aNewSR.First()) < dT) {
607 aNewSR=aSR;
608 }
609 }
610}
611
612//=======================================================================
613//function : CopySrc
614//purpose :
615//=======================================================================
616void CopySrc(const TopoDS_Shape& E,
617 TopTools_IndexedDataMapOfShapeShape& aMapSS,
618 TopoDS_Shape& anEdge)
619{
620 BRep_Builder BB;
621 TopAbs_ShapeEnum aTT;
622 Standard_Integer aR;
623 aTT=E.ShapeType();
624
625 if (aMapSS.Contains(E)) {
626 anEdge=aMapSS.ChangeFromKey(E);
627 if (aTT==TopAbs_EDGE)
628 return;
629 }
630 else {
631 anEdge=E.EmptyCopied();
632 aMapSS.Add(E, anEdge);
633 }
634
635 aR=(Standard_Integer)aTT+1;
636
637 if (aR>TopAbs_VERTEX) {
638 return;
639 }
640
641 Standard_Boolean free = anEdge.Free();
642 anEdge.Free(Standard_True);
643
644 aTT=(TopAbs_ShapeEnum) aR;
645 TopExp_Explorer anExpVertices(E, aTT);
646 for (; anExpVertices.More(); anExpVertices.Next()) {
647 const TopoDS_Shape& V=anExpVertices.Current();
648 TopoDS_Shape aVertex;
649
650 CopySrc (V, aMapSS, aVertex);
651
652 aVertex.Orientation(V.Orientation());
653 BB.Add(anEdge, aVertex);
654 }
655
656 anEdge.Free(free);
657}