0023884: Boolean Fuse between two faces fails
[occt.git] / src / IntTools / IntTools_Tools.cxx
CommitLineData
b311480e 1// Created on: 2000-11-16
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
7fd59977 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
973c2be1 7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <IntTools_Tools.ixx>
17
18#include <Precision.hxx>
19
20#include <TopExp_Explorer.hxx>
21#include <TopTools_IndexedDataMapOfShapeShape.hxx>
22
23#include <TopoDS.hxx>
24#include <TopoDS_Shape.hxx>
25#include <TopoDS_Vertex.hxx>
26#include <TopoDS_Edge.hxx>
27#include <TopoDS_Face.hxx>
28#include <TopoDS_Wire.hxx>
29#include <TopLoc_Location.hxx>
30
31#include <BRep_Builder.hxx>
32#include <BRep_Tool.hxx>
33#include <BRepAdaptor_Surface.hxx>
34#include <BRepAdaptor_Curve.hxx>
35#include <BRepAdaptor_Surface.hxx>
36
37#include <gp_Pnt.hxx>
38#include <gp_Pnt2d.hxx>
39#include <gp.hxx>
40#include <gp_Lin.hxx>
41#include <gp_Dir.hxx>
42#include <gp_Ax1.hxx>
43
44#include <Geom_Curve.hxx>
45#include <GeomAdaptor_Surface.hxx>
46#include <Geom_Surface.hxx>
47#include <GeomAPI_ProjectPointOnSurf.hxx>
48#include <GeomAPI_ProjectPointOnCurve.hxx>
49#include <GeomAdaptor_Curve.hxx>
50#include <GeomAbs_CurveType.hxx>
51#include <Geom_Line.hxx>
52#include <Geom2d_Curve.hxx>
53#include <Geom_BoundedCurve.hxx>
54#include <Geom_Geometry.hxx>
55#include <Geom_TrimmedCurve.hxx>
56#include <Geom2d_TrimmedCurve.hxx>
57
58#include <IntTools_FClass2d.hxx>
59#include <IntTools_Curve.hxx>
60#include <IntTools_SequenceOfCurves.hxx>
61
62static
63 void ParabolaTolerance(const Handle(Geom_Curve)& ,
64 const Standard_Real ,
65 const Standard_Real ,
66 const Standard_Real ,
67 Standard_Real& ,
68 Standard_Real& );
69
70//=======================================================================
71//function : HasInternalEdge
72//purpose :
73//=======================================================================
74 Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW)
75{
76 Standard_Boolean bFlag=Standard_True;
77
78 TopExp_Explorer anExp(aW, TopAbs_EDGE);
79 for (; anExp.More(); anExp.Next()) {
80 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
81 TopAbs_Orientation anOr=aE.Orientation();
82 if (anOr==TopAbs_INTERNAL) {
83 return bFlag;
84 }
85 }
86 return !bFlag;
87}
88
89//=======================================================================
90//function : IsClosed
91//purpose :
92//=======================================================================
93 Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D)
94{
cf8e963a 95 Standard_Boolean bRet;
96 Standard_Real aF, aL, aDist, aPC;
7fd59977 97 gp_Pnt aP1, aP2;
cf8e963a 98
7fd59977 99 Handle (Geom_BoundedCurve) aGBC=
100 Handle (Geom_BoundedCurve)::DownCast(aC3D);
101 if (aGBC.IsNull()) {
102 return Standard_False;
103 }
cf8e963a 104
7fd59977 105 aF=aC3D->FirstParameter();
106 aL=aC3D-> LastParameter();
107
108 aC3D->D0(aF, aP1);
109 aC3D->D0(aL, aP2);
110
cf8e963a 111
112 //
113 //modified by NIZNHY-PKV Mon Jul 04 11:58:23 2011f
114 aPC=Precision::Confusion();
115 aPC=aPC*aPC;
116 aDist=aP1.SquareDistance(aP2);
117 bRet=aDist<aPC;
118 return bRet;
119 //
120 //aDist=aP1.Distance(aP2);
121 //return (aDist < Precision::Confusion());
122 //modified by NIZNHY-PKV Mon Jul 04 11:59:50 2011t
7fd59977 123}
124
125//=======================================================================
126//function : RejectLines
127//purpose :
128//=======================================================================
129 void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn,
130 IntTools_SequenceOfCurves& aSOut)
131{
132 Standard_Integer i, j, aNb;
133 Standard_Boolean bFlag;
134 Handle (Geom_Curve) aC3D;
135
136 gp_Dir aD1, aD2;
137
138 aSOut.Clear();
139
140 aNb=aSIn.Length();
141 for (i=1; i<=aNb; i++) {
142 const IntTools_Curve& IC=aSIn(i);
143 aC3D=IC.Curve();
144 //
145 Handle (Geom_TrimmedCurve) aGTC=
146 Handle (Geom_TrimmedCurve)::DownCast(aC3D);
147
148 if (!aGTC.IsNull()) {
149 aC3D=aGTC->BasisCurve();
150 IntTools_Curve* pIC=(IntTools_Curve*) &IC;
151 pIC->SetCurve(aC3D);
152 }
153 //
154 Handle (Geom_Line) aGLine=
155 Handle (Geom_Line)::DownCast(aC3D);
156
157 if (aGLine.IsNull()) {
158 aSOut.Clear();
159 for (j=1; j<=aNb; j++) {
160 aSOut.Append(aSIn(j));
161 }
162 return;
163 }
164 //
165 gp_Lin aLin=aGLine->Lin();
166 aD2=aLin.Direction();
167 if (i==1) {
168 aSOut.Append(IC);
169 aD1=aD2;
170 continue;
171 }
172
173 bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2);
174 if (!bFlag) {
175 aSOut.Append(IC);
176 return;
177 }
178 }
179}
180
181//=======================================================================
182//function : IsDirsCoinside
183//purpose :
184//=======================================================================
185 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2)
186{
187 Standard_Boolean bFlag;
188 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
189 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
190 Standard_Real dLim=0.0002, d;
191 d=P1.Distance (P2);
192 bFlag= (d<dLim || fabs (2.-d)<dLim);
193 return bFlag;
194}
195
196//=======================================================================
197//function : IsDirsCoinside
198//purpose :
199//=======================================================================
200 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1,
201 const gp_Dir& D2,
202 const Standard_Real dLim)
203{
204 Standard_Boolean bFlag;
205 Standard_Real d;
206 //
207 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
208 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
209 d=P1.Distance (P2);
210 bFlag= (d<dLim || fabs (2.-d)<dLim);
211 return bFlag;
212}
213//=======================================================================
214//function : SplitCurve
215//purpose :
216//=======================================================================
217 Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC,
218 IntTools_SequenceOfCurves& aCvs)
219{
220 Handle (Geom_Curve) aC3D =IC.Curve();
221 if(aC3D.IsNull())
222 return 0;
223 //
224 Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d();
225 Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d();
226 Standard_Boolean bIsClosed;
227
228 bIsClosed=IntTools_Tools::IsClosed(aC3D);
229 if (!bIsClosed) {
230 return 0;
231 }
232
233 Standard_Real aF, aL, aMid;
234
235 //
236 aF=aC3D->FirstParameter();
237 aL=aC3D->LastParameter();
238 aMid=0.5*(aF+aL);
7fd59977 239 GeomAdaptor_Curve aGAC(aC3D);
240 GeomAbs_CurveType aCT=aGAC.GetType();
241 if (aCT==GeomAbs_BSplineCurve ||
242 aCT==GeomAbs_BezierCurve) {
243 //aMid=0.5*aMid;
244 aMid=IntTools_Tools::IntermediatePoint(aF, aL);
245 }
7fd59977 246 //
247 Handle(Geom_Curve) aC3DNewF, aC3DNewL;
248 aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid);
249 aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL);
250
251 //
252 Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L;
253 //
254 if(!aC2D1.IsNull()) {
255 aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid);
256 aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL);
257 }
258
259 if(!aC2D2.IsNull()) {
260 aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid);
261 aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL);
262 }
263 //
264
265 IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F);
266 IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L);
267 //
268 aCvs.Append(aIC1);
269 //
270 aCvs.Append(aIC2);
271 //
272 return 2;
273}
274
275//=======================================================================
276//function : IntermediatePoint
277//purpose :
278//=======================================================================
279 Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst,
280 const Standard_Real aLast)
281{
c6541a0c 282 //define parameter division number as 10*e^(-M_PI) = 0.43213918
7fd59977 283 const Standard_Real PAR_T = 0.43213918;
284 Standard_Real aParm;
285 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
286 return aParm;
287}
288
289//=======================================================================
290//function : IsVertex
291//purpose :
292//=======================================================================
293 Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP,
294 const Standard_Real aTolPV,
295 const TopoDS_Vertex& aV)
296{
cf8e963a 297 Standard_Boolean bRet;
7fd59977 298 Standard_Real aTolV, aD, dTol;
299 gp_Pnt aPv;
300
301 aTolV=BRep_Tool::Tolerance(aV);
302 //
7fd59977 303 dTol=Precision::Confusion();
304 aTolV=aTolV+aTolPV+dTol;
7fd59977 305 //
306 aPv=BRep_Tool::Pnt(aV);
cf8e963a 307 //
308 //modified by NIZNHY-PKV Mon Jul 04 12:00:37 2011f
309 aD=aPv.SquareDistance(aP);
310 aTolV=aTolV*aTolV;
311 bRet=(aD<=aTolV);
312 return bRet;
313 //
314 //aD=aPv.Distance(aP);
315 //return (aD<=aTolV);
316 //modified by NIZNHY-PKV Mon Jul 04 12:00:40 2011t
7fd59977 317}
318
319
320//=======================================================================
321//function : IsVertex
322//purpose :
323//=======================================================================
324 Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt)
325{
326 Standard_Boolean anIsVertex;
327 Standard_Real aParam;
328
329 const TopoDS_Edge& aE1=aCmnPrt.Edge1();
330 const IntTools_Range& aR1=aCmnPrt.Range1();
331 aParam=0.5*(aR1.First()+aR1.Last());
332 anIsVertex=IntTools_Tools::IsVertex (aE1, aParam);
333
334 if (anIsVertex) {
335 return Standard_True;
336 }
337
338 const TopoDS_Edge& aE2=aCmnPrt.Edge2();
339 const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2();
340 const IntTools_Range& aR2=aRs2(1);
341 aParam=0.5*(aR2.First()+aR2.Last());
342 anIsVertex=IntTools_Tools::IsVertex (aE2, aParam);
343 if (anIsVertex) {
344 return Standard_True;
345 }
346 return Standard_False;
347}
348
349//=======================================================================
350//function : IsVertex
351//purpose :
352//=======================================================================
353 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
354 const TopoDS_Vertex& aV,
355 const Standard_Real t)
356{
357 Standard_Real aTolV, aTolV2, d2;
358 gp_Pnt aPv, aPt;
359
360 BRepAdaptor_Curve aBAC(aE);
361 aBAC.D0(t, aPt);
362
363 aTolV=BRep_Tool::Tolerance(aV);
364 aTolV2=aTolV*aTolV;
365 aPv=BRep_Tool::Pnt(aV);
366 d2=aPv.SquareDistance (aPt);
367 if (d2 < aTolV2) {
368 return Standard_True;
369 }
370 return Standard_False;
371}
372//=======================================================================
373//function : IsVertex
374//purpose :
375//=======================================================================
376 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
377 const Standard_Real t)
378{
379 Standard_Real aTolV, aTolV2, d2;
380 TopoDS_Vertex aV;
381 gp_Pnt aPv, aPt;
382
383 BRepAdaptor_Curve aBAC(aE);
384 aBAC.D0(t, aPt);
385
386 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
387 for (; anExp.More(); anExp.Next()) {
388 aV=TopoDS::Vertex (anExp.Current());
389 aTolV=BRep_Tool::Tolerance(aV);
390 aTolV2=aTolV*aTolV;
391 aTolV2=1.e-12;
392 aPv=BRep_Tool::Pnt(aV);
393 d2=aPv.SquareDistance (aPt);
394 if (d2 < aTolV2) {
395 return Standard_True;
396 }
397 }
398 return Standard_False;
399}
400
401
402//=======================================================================
403//function : ComputeVV
404//purpose :
405//=======================================================================
406 Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1,
407 const TopoDS_Vertex& aV2)
408{
409 Standard_Real aTolV1, aTolV2, aTolSum, d;
410 gp_Pnt aP1, aP2;
411
412 aTolV1=BRep_Tool::Tolerance(aV1);
413 aTolV2=BRep_Tool::Tolerance(aV2);
414 aTolSum=aTolV1+aTolV2;
cf8e963a 415
7fd59977 416 aP1=BRep_Tool::Pnt(aV1);
417 aP2=BRep_Tool::Pnt(aV2);
cf8e963a 418 //modified by NIZNHY-PKV Mon Jul 04 11:55:52 2011f
419 aTolSum=aTolSum*aTolSum;
420 d=aP1.SquareDistance(aP2);
421 //d=aP1.Distance(aP2);
422 //modified by NIZNHY-PKV Mon Jul 04 11:55:53 2011t
7fd59977 423 if (d<aTolSum) {
424 return 0;
425 }
426 return -1;
427}
428
429//=======================================================================
430//function : MakeFaceFromWireAndFace
431//purpose :
432//=======================================================================
433 void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW,
434 const TopoDS_Face& aF,
435 TopoDS_Face& aFNew)
436{
437 TopoDS_Face aFF;
438 aFF=aF;
439 aFF.Orientation(TopAbs_FORWARD);
440 aFNew=TopoDS::Face (aFF.EmptyCopied());
441 BRep_Builder BB;
442 BB.Add(aFNew, aW);
443}
444
445//=======================================================================
446//function : ClassifyPointByFace
447//purpose :
448//=======================================================================
449 TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
450 const gp_Pnt2d& aP2d)
451{
452 Standard_Real aFaceTolerance;
453 TopAbs_State aState;
454
455 aFaceTolerance=BRep_Tool::Tolerance(aF);
456 IntTools_FClass2d aClass2d(aF, aFaceTolerance);
457 aState=aClass2d.Perform(aP2d);
458
459 return aState;
460}
461
462//=======================================================================
463//function : IsMiddlePointsEqual
464//purpose :
465//=======================================================================
466 Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1,
467 const TopoDS_Edge& aE2)
468
469{
cf8e963a 470 Standard_Boolean bRet;
471 Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2;
7fd59977 472 gp_Pnt aP1, aP2;
473
474 aTol1=BRep_Tool::Tolerance(aE1);
475 Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1);
476 m1=0.5*(f1+l1);
477 C1->D0(m1, aP1);
478
479 aTol2=BRep_Tool::Tolerance(aE2);
480 Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2);
481 m2=0.5*(f2+l2);
482 C2->D0(m2, aP2);
483
484 aSumTol=aTol1+aTol2;
cf8e963a 485 //modified by NIZNHY-PKV Mon Jul 04 12:02:20 2011f
486 aSumTol=aSumTol*aSumTol;
487 aD2=aP1.SquareDistance(aP2);
488 bRet=aD2<aSumTol;
489 return bRet;
490 //
491 //if (aP1.Distance(aP2) < aSumTol) {
492 // return Standard_True;
493 //}
494 //return Standard_False;
495 //modified by NIZNHY-PKV Mon Jul 04 12:02:24 2011t
7fd59977 496}
497
498//=======================================================================
499//function : CurveTolerance
500//purpose :
501//=======================================================================
502 Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D,
503 const Standard_Real aTolBase)
504{
505 Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax;
506
507 aTolReached=aTolBase;
508 //
509 if (aC3D.IsNull()) {
510 return aTolReached;
511 }
512 //
513 Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D);
514 if (aCT3D.IsNull()) {
515 return aTolReached;
516 }
517 //
518 aTolMin=aTolBase;
519 aTolMax=aTolBase;
520 //
521 aTf=aCT3D->FirstParameter();
522 aTl=aCT3D->LastParameter();
523 //
524 GeomAdaptor_Curve aGAC(aCT3D);
525 GeomAbs_CurveType aCType=aGAC.GetType();
526 //
527 if (aCType==GeomAbs_Parabola) {
528 Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve();
529 ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax);
530 aTolReached=aTolMax;
531 }
532 //
533 return aTolReached;
534}
535
536#include <Geom_Parabola.hxx>
537#include <gp_Parab.hxx>
538//=======================================================================
539//function : ParabolaTolerance
540//purpose :
541//=======================================================================
542void ParabolaTolerance(const Handle(Geom_Curve)& aC3D,
543 const Standard_Real aTf,
544 const Standard_Real aTl,
545 const Standard_Real aTol,
546 Standard_Real& aTolMin,
547 Standard_Real& aTolMax)
548{
549
550 aTolMin=aTol;
551 aTolMax=aTol;
552
553 Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D);
554 if (aGP.IsNull()){
555 return;
556 }
557
558 Standard_Integer aNbPoints;
559 Standard_Real aFocal, aX1, aX2, aTol1, aTol2;
560 gp_Pnt aPf, aPl;
561 gp_Parab aParab=aGP->Parab();
562 gp_Ax1 aXAxis=aParab.XAxis();
563 Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis);
564
565 aFocal=aGP->Focal();
566 if (aFocal==0.) {
567 return;
568 }
569 //
570 // aTol1
571 aTol1=aTol;
572 aX1=0.;
573 aGP->D0(aTf, aPf);
574 GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis);
575 aNbPoints=aProj1.NbPoints();
576 if (aNbPoints) {
577 aX1=aProj1.LowerDistanceParameter();
578 }
579 if (aX1>=0.) {
580 aTol1=aTol*sqrt(0.5*aX1/aFocal);
581 }
582 if (aTol1==0.) {
583 aTol1=aTol;
584 }
585 //
586 // aTol2
587 aTol2=aTol;
588 aX2=0.;
589 aGP->D0(aTl, aPl);
590 GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis);
591 aNbPoints=aProj2.NbPoints();
592 if (aNbPoints) {
593 aX2=aProj2.LowerDistanceParameter();
594 }
595
596 if (aX2>=0.) {
597 aTol2=aTol*sqrt(0.5*aX2/aFocal);
598 }
599 if (aTol2==0.) {
600 aTol2=aTol;
601 }
602 //
603 aTolMax=(aTol1>aTol2) ? aTol1 : aTol2;
604 aTolMin=(aTol1<aTol2) ? aTol1 : aTol2;
605}
606