Adding of testing cases from subgroups 937 940 and 941 of CHL group
[occt.git] / src / BOPTools / BOPTools_Tools3D.cxx
CommitLineData
b311480e 1// Created on: 2001-04-05
2// Created by: Peter KURNEV
3// Copyright (c) 2001-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#include <BOPTools_Tools3D.ixx>
22
23#include <TopExp.hxx>
24#include <TopExp_Explorer.hxx>
25
26#include <TopoDS.hxx>
27#include <TopoDS_Shape.hxx>
28#include <TopoDS_Edge.hxx>
29#include <TopoDS_Face.hxx>
30#include <TopoDS_Vertex.hxx>
31
32#include <TopTools_MapOfShape.hxx>
33#include <TopTools_MapIteratorOfMapOfShape.hxx>
34#include <TopTools_ListOfShape.hxx>
35#include <TopTools_ListIteratorOfListOfShape.hxx>
36#include <TopTools_IndexedMapOfShape.hxx>
37#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38
39#include <BRep_Builder.hxx>
40#include <BRep_Tool.hxx>
41#include <BRepTools.hxx>
42#include <BRepAdaptor_Surface.hxx>
43
44#include <gp_Vec2d.hxx>
45#include <gp_Pnt2d.hxx>
46#include <gp_Lin2d.hxx>
47#include <gp_Dir2d.hxx>
48#include <gp_Vec.hxx>
49#include <gp_Dir.hxx>
50#include <gp_Pln.hxx>
51
52#include <Geom2d_Curve.hxx>
53#include <Geom2d_TrimmedCurve.hxx>
54#include <Geom2d_Line.hxx>
55
56#include <Geom_Curve.hxx>
57#include <Geom_Surface.hxx>
58#include <Geom_BSplineSurface.hxx>
59#include <Geom_BezierSurface.hxx>
60
61#include <GeomAdaptor_Surface.hxx>
62
63#include <IntTools_Tools.hxx>
64
65#include <BOPTools_Tools2D.hxx>
66
67#include <GProp_GProps.hxx>
68#include <BRepGProp.hxx>
69#include <BRepBndLib.hxx>
70#include <Bnd_Box.hxx>
71
72
73
74static
75 void PointNearE (const TopoDS_Edge& aE,
76 const TopoDS_Face& aF,
77 const Standard_Real aT,
78 gp_Pnt& aPInFace,
79 const Standard_Boolean aSt);
80
81static Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1,
82 const TopoDS_Face& F2,
83 const TopoDS_Face& F3);
84
85//=======================================================================
86//function : RemoveSims
87//purpose :
88//=======================================================================
89 void BOPTools_Tools3D::RemoveSims (const TopoDS_Shape& aS,
4f189102 90 const Handle(IntTools_Context)& aContext)
7fd59977 91{
92 TopExp_Explorer anExp(aS, TopAbs_FACE);
93 for (; anExp.More(); anExp.Next()) {
94 const TopoDS_Face& aF=TopoDS::Face(anExp.Current());
95 //
96 BOPTools_Tools3D::RemoveSims (aF, aContext);
97 }
98}
99
100//=======================================================================
101//function : RemoveSims
102//purpose :
103//=======================================================================
104 void BOPTools_Tools3D::RemoveSims (const TopoDS_Face& aFF,
4f189102 105 const Handle(IntTools_Context)& aContext)
7fd59977 106{
107 Standard_Boolean anIsClosed, anIsPointInFace1, anIsPointInFace2;
108 Standard_Real aT1, aT2, aT, aX, aY, dt=1.e-7, aTol;
109 BRep_Builder BB;
110 gp_Vec2d aV2D, aV2Dx;
111 gp_Pnt2d aP2D, aP2Dx;
112 TopAbs_Orientation anOri;
113 Handle(Geom2d_Curve) aC2Dx;
114 //
115 TopoDS_Face aF=aFF;
116 aF.Orientation(TopAbs_FORWARD);
117 //
118 TopExp_Explorer anExpW (aF, TopAbs_WIRE);
119 for (; anExpW.More(); anExpW.Next()) {
120
121 TopTools_MapOfShape aMap, aMapToAdd, aMapToRemove;
122 const TopoDS_Shape& aW=anExpW.Current();
123
124 TopExp_Explorer anExp(aW, TopAbs_EDGE);
125 for (; anExp.More(); anExp.Next()) {
126 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
127 //
128 if (BRep_Tool::Degenerated(aE)){
129 continue;
130 }
131 //
132 anIsClosed=BRep_Tool::IsClosed(aE, aF);
133 if (anIsClosed) {
134 if (aMap.Contains(aE)) {
135 continue;
136 }
137 aMap.Add(aE);
138 aTol=BRep_Tool::Tolerance(aE);
139
140 Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
141 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
142 aC2D-> D1(aT, aP2D, aV2D);
143
144 anOri=aE.Orientation();
145 if (anOri==TopAbs_REVERSED) {
146 aV2D.Reverse();
147 }
148
149 aV2D.Normalize();
150 aX=aV2D.X();
151 aY=aV2D.Y();
152 aV2Dx.SetCoord(-aY, aX);
153
154 aP2Dx.SetX(aP2D.X()+dt*aV2Dx.X());
155 aP2Dx.SetY(aP2D.Y()+dt*aV2Dx.Y());
156 //
4f189102 157 anIsPointInFace1=aContext->IsPointInFace(aF, aP2Dx);
7fd59977 158 //
159 aP2Dx.SetX(aP2D.X()-dt*aV2Dx.X());
160 aP2Dx.SetY(aP2D.Y()-dt*aV2Dx.Y());
161 //
4f189102 162 anIsPointInFace2=aContext->IsPointInFace(aF, aP2Dx);
7fd59977 163 //
164
165 if (anIsPointInFace1 && anIsPointInFace2) {
166 continue;
167 }
168 //
169 TopoDS_Edge aEx=aE;
170
171 aEx.EmptyCopy();
172 TopExp_Explorer anExpV(aE, TopAbs_VERTEX);
173 for (; anExpV.More(); anExpV.Next()) {
174 const TopoDS_Shape& aVx=anExpV.Current();
175 BB.Add (aEx, aVx);
176 }
177
178 BB.UpdateEdge(aEx, aTol);
179 //
180 if (anIsPointInFace1) {
181 if (anOri==TopAbs_REVERSED) {
182 // Remove Forward
183 BB.UpdateEdge(aEx, aC2Dx, aF, aTol);
184 BB.UpdateEdge(aEx, aC2D , aF, aTol);
185 aEx.Orientation(TopAbs_REVERSED);
186 }
187 else {
188 // Remove Reversed
189 BB.UpdateEdge(aEx, aC2Dx, aF, aTol);
190 BB.UpdateEdge(aEx, aC2D , aF, aTol);
191 aEx.Orientation(TopAbs_FORWARD);
192 }
193 aMapToAdd.Add(aEx);
194 aMapToRemove.Add(aE);
195 }
196 }
197 }// next Edge
198 //
199 TopoDS_Shape* pW= (TopoDS_Shape*)&aW;
200 pW->Free(Standard_True);
201
202 TopTools_MapIteratorOfMapOfShape anIt(aMapToRemove);
203 for (; anIt.More(); anIt.Next()) {
204 const TopoDS_Shape& aSR=anIt.Key();
205 BB.Remove(*pW, aSR);
206 }
207 anIt.Initialize(aMapToAdd);
208 for (; anIt.More(); anIt.Next()) {
209 const TopoDS_Shape& aSA=anIt.Key();
210 BB.Add(*pW, aSA);
211 }
212
213 }// next Wire
214}
215
216//=======================================================================
217//function : SubShapesAmount
218//purpose :
219//=======================================================================
220 Standard_Integer BOPTools_Tools3D::SubShapesAmount (const TopoDS_Shape& aS,
221 const TopAbs_ShapeEnum aType)
222{
223 Standard_Integer aNb;
224 TopTools_IndexedMapOfShape aM;
225 TopExp::MapShapes(aS, aType, aM);
226 aNb=aM.Extent();
227 return aNb;
228}
229
230//=======================================================================
231//function : IsConvexWire
232//purpose :
233//=======================================================================
234 Standard_Boolean BOPTools_Tools3D::IsConvexWire (const TopoDS_Wire& aW)
235{
236 Standard_Boolean aFlag;
237 Standard_Integer aNbV, aNbE;
238
239 aNbV=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_VERTEX);
240 aNbE=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_EDGE);
241 aFlag=aNbV <= aNbE;
242 return aFlag;
243}
244
245//=======================================================================
246//function : DoSplitSEAMOnFace
247//purpose :
248//=======================================================================
249 void BOPTools_Tools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
250 const TopoDS_Face& aF)
251{
252 Standard_Boolean bIsUPeriodic, bIsLeft;
253 Standard_Real aTol, a, b, anUPeriod, aT, anU, dU=1.e-7, anU1;
254 Standard_Real aScPr;
255 gp_Pnt2d aP2D;
256 gp_Vec2d aVec2D;
257 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
258 Handle(Geom2d_Curve) C2D1;
259 Handle(Geom2d_Line) aLD1;
260 Handle(Geom_Surface) aS;
261 BRep_Builder BB;
262 TopoDS_Edge aSp;
263 //
264 aSp=aSplit;
265 aSp.Orientation(TopAbs_FORWARD);
266
267 aTol=BRep_Tool::Tolerance(aSp);
268
269 aS=BRep_Tool::Surface(aF);
270 bIsUPeriodic=aS->IsUPeriodic();
271
272 anUPeriod=0.;
273 if (bIsUPeriodic) {
274 anUPeriod=aS->UPeriod();
275 }
276 else {
277 //modified by NIZNHY-PKV Fri Jul 11 09:54:43 2008f
278 Standard_Boolean bIsUClosed;
279 Standard_Real aUmin, aUmax, aVmin, aVmax;
280 Handle(Geom_BSplineSurface) aBS;
281 Handle(Geom_BezierSurface) aBZ;
282 //
283 bIsUClosed=Standard_False;
284 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
285 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
286 //
287 if (!aBS.IsNull()) {
288 bIsUClosed=aBS->IsUClosed();
289 aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
290 }
291 else if (!aBZ.IsNull()) {
292 bIsUClosed=aBZ->IsUClosed();
293 aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
294 }
295 if (!bIsUClosed) {
296 return;
297 }
298 //
299 anUPeriod=aUmax-aUmin;
300 //modified by NIZNHY-PKV Fri Jul 11 09:54:49 2008t
301 }
302 //
303 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
304 //modified by NIZNHY-PKV Fri Jul 11 09:55:10 2008f
305 /*
306 aLD1=Handle(Geom2d_Line)::DownCast(C2D1);
307 if (aLD1.IsNull()) {
308 return;
309 }
310 */
311 //modified by NIZNHY-PKV Fri Jul 11 09:55:14 2008t
312 //
313 aT=BOPTools_Tools2D::IntermediatePoint(a, b);
314 C2D1->D1(aT, aP2D, aVec2D);
315 gp_Dir2d aDir2D1(aVec2D);
316
317 //
318 gp_Dir2d aDOY(0.,1.);
319 aScPr=aDir2D1*aDOY;
320 //
321 //
322 anU=aP2D.X();
323 if (fabs (anU) < dU) {
324 bIsLeft=Standard_True;
325 anU1=anU+anUPeriod;
326 }
327 else if (fabs (anU-anUPeriod) < dU) {
328 bIsLeft=Standard_False;
329 anU1=anU-anUPeriod;
330 }
331 else {
332 return;
333 }
334 //
335
336
337 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
338 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b);
339
340 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
341 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b);
342 gp_Vec2d aTrV(anU1-anU, 0.);
343 aC2->Translate(aTrV);
344 //
345 if (!bIsLeft) {
346 if (aScPr<0.) {
347 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
348 }
349 else {
350 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
351 }
352 }
353 else {
354 if (aScPr<0.) {
355 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
356 }
357 else {
358 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
359 }
360 }
361 //
362}
363//=======================================================================
364//function : DoSplitSEAMOnFace
365//purpose :
366//=======================================================================
367Standard_Boolean BOPTools_Tools3D::DoSplitSEAMOnFace(const TopoDS_Edge& theSplit,
368 const TopoDS_Edge& theSeam,
369 const TopoDS_Face& theFace,
370 Standard_Boolean& IsReversed)
371{
372 Standard_Real aTol, f, l, a, b, aPeriod, aT, aParTolerance = 1.e-07;
373 Standard_Boolean bIsUPeriodic = Standard_False;
374 Standard_Boolean bIsVPeriodic = Standard_False;
375 BRep_Builder BB;
376 gp_Pnt2d aP2D;
377 gp_Vec2d aVec2D;
378
379
380 TopoDS_Edge aSp = theSplit;
381 aSp.Orientation(TopAbs_FORWARD);
382 TopoDS_Edge aSeamF = theSeam;
383 aSeamF.Orientation(TopAbs_FORWARD);
384 TopoDS_Edge aSeamR = theSeam;
385 aSeamR.Orientation(TopAbs_REVERSED);
386
387 aTol=BRep_Tool::Tolerance(aSp);
388
389 Handle(Geom2d_Curve) C2D1 = BRep_Tool::CurveOnSurface(aSp, theFace, f, l);
390 Handle(Geom2d_Curve) C2D2 = BRep_Tool::CurveOnSurface(aSeamF, theFace, a, b);
391 Handle(Geom2d_Curve) C2D3 = BRep_Tool::CurveOnSurface(aSeamR, theFace, a, b);
392 //
393 Handle(Geom2d_TrimmedCurve) atr = Handle(Geom2d_TrimmedCurve)::DownCast(C2D1);
394 Handle(Geom2d_Line) aLD1;
395
396 if(!atr.IsNull()) {
397 aLD1 = Handle(Geom2d_Line)::DownCast(atr->BasisCurve());
398 }
399 else {
400 aLD1 = Handle(Geom2d_Line)::DownCast(C2D1);
401 }
402
403 if (aLD1.IsNull()) {
404 return Standard_False;
405 }
406 aT = BOPTools_Tools2D::IntermediatePoint(f, l);
407 C2D1->D1(aT, aP2D, aVec2D);
408 gp_Dir2d aDir2D(aVec2D);
409
410 gp_Vec2d aVec2D1, aVec2D2;
411 gp_Pnt2d aP2D1, aP2D2;
412 C2D2->D1(((a+b) * 0.5), aP2D1, aVec2D1);
413 C2D3->D1(((a+b) * 0.5), aP2D2, aVec2D2);
414
415 Handle(Geom_Surface) aS=BRep_Tool::Surface(theFace);
416 bIsUPeriodic = aS->IsUPeriodic();
417 bIsVPeriodic = aS->IsVPeriodic();
418
419 for(Standard_Integer i = 0; i < 2; i++) {
420 Standard_Boolean bIsPeriodic = (i == 0) ? bIsUPeriodic : bIsVPeriodic;
421
422 if(!bIsPeriodic)
423 continue;
424
425 aPeriod = (i == 0) ? aS->UPeriod() : aS->VPeriod();
426
427 Standard_Real aParameter = (i == 0) ? aP2D.X() : aP2D.Y();
428 Standard_Real aParameter1 = (i == 0) ? aP2D1.X() : aP2D1.Y();
429 Standard_Real aParameter2 = (i == 0) ? aP2D2.X() : aP2D2.Y();
430
431 Standard_Boolean bIsLower = Standard_False, found = Standard_False;
432 Standard_Boolean bIsFirst = Standard_False;
433 Standard_Real aScPr = 0.;
434
435 if (fabs (aParameter - aParameter1) < aParTolerance) {
436 bIsLower = (aParameter < aParameter2);
437 bIsFirst = Standard_True;
438 aScPr = aDir2D * aVec2D1;
439 }
440 else if (fabs (aParameter - aParameter2) < aParTolerance) {
441 bIsLower = (aParameter < aParameter1);
442 bIsFirst = Standard_False;
443 aScPr = aDir2D * aVec2D2;
444 }
445 found = (fabs(aScPr) > aParTolerance);
446
447 if(found) {
448 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
449
450 aTmpC1 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
451 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, f, l);
452
453 aTmpC2 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
454 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, f, l);
455 gp_Vec2d aTrV;
456
457 if(i == 0) {
458 if(bIsLower)
459 aTrV.SetX(aPeriod);
460 else
461 aTrV.SetX(-aPeriod);
462 aTrV.SetY(0.);
463 }
464 else {
465 if(bIsLower)
466 aTrV.SetY(aPeriod);
467 else
468 aTrV.SetY(-aPeriod);
469 aTrV.SetX(0.);
470 }
471 aC2->Translate(aTrV);
472 //
473 IsReversed = (aScPr < 0.);
474 Standard_Boolean bIsReverseOrder = (!IsReversed) ? !bIsFirst : bIsFirst;
475
476 if(bIsReverseOrder) {
477 BB.UpdateEdge(aSp, aC2, aC1, theFace, aTol);
478 }
479 else {
480 BB.UpdateEdge(aSp, aC1, aC2, theFace, aTol);
481 }
482 return Standard_True;
483 }
484 }
485 return Standard_False;
486}
487//=======================================================================
488//function :IsSplitToReverse1
489//purpose :
490//=======================================================================
491 Standard_Boolean BOPTools_Tools3D::IsSplitToReverse1 (const TopoDS_Edge& aEF1,
492 const TopoDS_Edge& aEF2,
4f189102 493 const Handle(IntTools_Context)& aContext)
7fd59977 494{
495 Standard_Boolean aFlag;
496 Standard_Real aT1, aT2, aScPr, a, b;
497 gp_Vec aV1, aV2;
498 gp_Pnt aP;
499
500
501 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b);
502 aT1=BOPTools_Tools2D::IntermediatePoint(a, b);
503 aC1->D0(aT1, aP);
504 aFlag=BOPTools_Tools2D::EdgeTangent(aEF1, aT1, aV1);
505
506 if(!aFlag) {
507 return Standard_False;
508 }
509
510 gp_Dir aDT1(aV1);
511 //
4f189102 512 aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2);
8fb480b3
P
513 if(!aFlag) {
514 return Standard_False;
515 }
7fd59977 516 //
517 aFlag=BOPTools_Tools2D::EdgeTangent(aEF2, aT2, aV2);
518 if(!aFlag) {
519 return Standard_False;
520 }
521
522 gp_Dir aDT2(aV2);
523
524 aScPr=aDT1*aDT2;
525
526 return (aScPr<0.);
527}
528
529//=======================================================================
530//function : EdgeOrientation
531//purpose :
532//=======================================================================
533 TopAbs_Orientation BOPTools_Tools3D::EdgeOrientation (const TopoDS_Edge& aE,
534 const TopoDS_Face& aF1,
535 const TopoDS_Face& aF2)
536{
537 Standard_Real aScPr;
538 gp_Dir aDTE, aDNF1, aDNF2, aDTN;
539
540 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1);
541 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2);
542
543 aDTN=aDNF1^aDNF2;
544
545 BOPTools_Tools2D::TangentOnEdge(aE, aDTE);
546
547 aScPr=aDTN*aDTE;
548
549 TopAbs_Orientation anOr;
550
551 anOr=TopAbs_FORWARD;
552 if (aScPr<0.) {
553 anOr=TopAbs_REVERSED;
554 }
555 return anOr;
556}
557//=======================================================================
558//function : IsTouchCase
559//purpose :
560//=======================================================================
561 Standard_Boolean BOPTools_Tools3D::IsTouchCase(const TopoDS_Edge& aE,
562 const TopoDS_Face& aF1,
563 const TopoDS_Face& aF2)
564{
565 gp_Dir aDNF1, aDNF2;
566
567
568 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1);
569 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2);
570
571 Standard_Boolean bIsDirsCoinside;
572 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
573 return bIsDirsCoinside;
574}
575//=======================================================================
576//function : GetNormalToFaceOnEdge
577//purpose :
578//=======================================================================
579 void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
580 const TopoDS_Face& aF,
581 gp_Dir& aDNF)
582{
583 Standard_Real aT, aT1, aT2;
584
585 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
586 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
587
588 BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
589
590 if (aF.Orientation()==TopAbs_REVERSED){
591 aDNF.Reverse();
592 }
593}
594
595//=======================================================================
596//function : GetNormalToFaceOnEdge
597//purpose :
598//=======================================================================
599 void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
600 const TopoDS_Face& aF1,
601 const Standard_Real aT,
602 gp_Dir& aDNF1)
603{
604 Standard_Real U, V, aTolPC;
605 gp_Pnt2d aP2D;
606 gp_Pnt aP;
607 gp_Vec aD1U, aD1V;
608
609 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
610
611 Handle(Geom2d_Curve)aC2D1;
612 BOPTools_Tools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC, Standard_True);
613
614 aC2D1->D0(aT, aP2D);
615 U=aP2D.X();
616 V=aP2D.Y();
617
618 aS1->D1(U, V, aP, aD1U, aD1V);
619 gp_Dir aDD1U(aD1U);
620 gp_Dir aDD1V(aD1V);
621
622 aDNF1=aDD1U^aDD1V;
623}
624
625//=======================================================================
626//function : GetBiNormal
627//purpose :
628//=======================================================================
629 void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aE,
630 const TopoDS_Face& aF,
631 const Standard_Real aT,
632 gp_Dir& aDB)
633{
634 gp_Dir aDNF, aDT;
635 //
636 // Normal to the face aF at parameter aT
637 BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
638 if (aF.Orientation()==TopAbs_REVERSED){
639 aDNF.Reverse();
640 }
641 //
642 // Split tangent on aF at parameter aT
643 BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDT);
644
645 if (aF.Orientation()==TopAbs_REVERSED){
646 aDT.Reverse();
647 }
648 // Binormal
649 aDB=aDNF^aDT;
650}
651
652//=======================================================================
653//function : :GetBiNormal
654//purpose :
655//=======================================================================
656 void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aSp,
657 const TopoDS_Face& aF,
658 gp_Dir& aDB)
659{
660 gp_Dir aDNF, aDD1Sp;
661 //
662 // Normal to the face aF at parameter aT
663 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF, aDNF);
664 //
665 // Split tangent on aF at parameter aT
666 BOPTools_Tools3D::GetTangentToEdge(aSp, aDD1Sp);
667
668 if (aF.Orientation()==TopAbs_REVERSED){
669 aDD1Sp.Reverse();
670 }
671 // Binormal
672 aDB=aDNF^aDD1Sp;
673}
674//=======================================================================
675//function : GetTangentToEdge
676//purpose :
677//=======================================================================
678 Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge,
679 gp_Dir& aDT)
680{
681 Standard_Boolean isdgE;
682
683 Standard_Real aT1, aT2, aT;
684
685 isdgE = BRep_Tool::Degenerated(anEdge);
686 if (isdgE) {
687 return Standard_False;
688 }
689
690 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, aT1, aT2);
691 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
692
693 BOPTools_Tools3D::GetTangentToEdge(anEdge, aT, aDT);
694
695 return Standard_True;
696}
697//=======================================================================
698//function : GetTangentToEdge
699//purpose :
700//=======================================================================
701 Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge,
702 const Standard_Real aT,
703 gp_Dir& aDT)
704{
705 Standard_Boolean isdgE;
706 Standard_Real first, last;
707
708 isdgE = BRep_Tool::Degenerated(anEdge);
709 if (isdgE) {
710 return Standard_False;
711 }
712
713 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
714 gp_Pnt aP;
715 gp_Vec aTau;
716 aC->D1(aT, aP, aTau);
717 gp_Dir aD(aTau);
718 if (anEdge.Orientation() == TopAbs_REVERSED){
719 aD.Reverse();
720 }
721 aDT=aD;
722
723 return Standard_True;
724}
725//=======================================================================
726//function : :IsSplitToReverse
727//purpose :
728//=======================================================================
729 Standard_Boolean BOPTools_Tools3D:: IsSplitToReverse(const TopoDS_Edge& aE,
730 const TopoDS_Edge& aSp)
731{
732 Standard_Real t1, t2, aT;
733
734 Handle(Geom_Curve)aCE=BRep_Tool::Curve(aE, t1, t2);
735 Handle(Geom_Curve)aCSp=BRep_Tool::Curve(aSp,t1, t2);
736
737 aT=BOPTools_Tools2D::IntermediatePoint(t1, t2);
738
739 gp_Vec aD1E, aD1Sp;
740 gp_Pnt aP;
741
742 aCE->D1 (aT, aP, aD1E);
743 aCSp->D1(aT, aP, aD1Sp);
744
745 gp_Dir aDD1E (aD1E);
746 gp_Dir aDD1Sp(aD1Sp);
747
748 if (aE.Orientation()==TopAbs_REVERSED) {
749 aDD1E.Reverse();
750 }
751 if (aSp.Orientation()==TopAbs_REVERSED) {
752 aDD1Sp.Reverse();
753 }
754
755 aT=aDD1E*aDD1Sp;
756
757 return (aT<0.);
758}
759
760//=======================================================================
761//function : GetAdjacentFace
762//purpose :
763//=======================================================================
764 Standard_Boolean BOPTools_Tools3D::GetAdjacentFace(const TopoDS_Face& aFaceObj,
765 const TopoDS_Edge& anEObj,
766 const TopTools_IndexedDataMapOfShapeListOfShape& anEdgeFaceMap,
767 TopoDS_Face& anAdjF)
768{
769 const TopTools_ListOfShape& aListOfAdjFaces=anEdgeFaceMap.FindFromKey(anEObj);
770 TopTools_ListIteratorOfListOfShape anIt(aListOfAdjFaces);
771 TopoDS_Shape anAdjShape;
772 for (; anIt.More(); anIt.Next()) {
773 if (anIt.Value()!=aFaceObj) {
774 anAdjShape=anIt.Value();
775 break;
776 }
777 }
778
779 if (!anAdjShape.IsNull()) {
780 anAdjF=TopoDS::Face(anAdjShape);
781 return Standard_True;
782 }
783 else {
784 return Standard_False;
785 }
786}
787//=======================================================================
788//function : IsKeepTwice
789//purpose :
790//=======================================================================
791 Standard_Boolean BOPTools_Tools3D::IsKeepTwice(const TopoDS_Face& aF1,
792 const TopoDS_Face& aF2,
793 const TopoDS_Face& aF2Adj,
794 const TopoDS_Edge& aSpEF2)
795{
796 if( !CheckKeepArguments(aF1, aF2, aF2Adj) ) {
797 return Standard_False;
798 }
799
800 Standard_Real aT1, aT2, aT, dt=1.e-7, A, B, C, D, d2, d2Adj;
801 gp_Dir aDNF1, aDNF2, DBF2, aDNF2Adj, DBF2Adj;
802 gp_Vec aD1Sp;
803 gp_Pnt aP, aPF2, aPF2Adj;
804
805 Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aSpEF2, aT1, aT2);
806 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
807 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF1, aT, aDNF1);
808
809 //
810 // Split tangent on F2
811 aC3D->D1(aT, aP, aD1Sp);
812 gp_Dir aDD1Sp(aD1Sp);
813
814 if (aSpEF2.Orientation()==TopAbs_REVERSED) {
815 aDD1Sp.Reverse();
816 }
817 // Split Normal on F2
818 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2, aT, aDNF2);
819 if (aF2.Orientation()==TopAbs_REVERSED) {
820 aDNF2.Reverse();
821 }
822 // Binormal on F2
823 DBF2=aDNF2^aDD1Sp;
824
825 // Point near aP
826 aPF2.SetCoord(aP.X()+dt*DBF2.X(),
827 aP.Y()+dt*DBF2.Y(),
828 aP.Z()+dt*DBF2.Z());
829
830
831 //
832 // Split tangent on F2Adj
833 aDD1Sp.Reverse();
834 // Split Normal on F2Adj
835 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2Adj, aT, aDNF2Adj);
836 if (aF2Adj.Orientation()==TopAbs_REVERSED) {
837 aDNF2Adj.Reverse();
838 }
839 // Binormal on F2Adj
840 DBF2Adj=aDNF2Adj^aDD1Sp;
841
842 // Point near aP
843 aPF2Adj.SetCoord(aP.X()+dt*DBF2Adj.X(),
844 aP.Y()+dt*DBF2Adj.Y(),
845 aP.Z()+dt*DBF2Adj.Z());
846 //
847 // Tangent Plane on F1
848 gp_Pln aPlnN1(aP, aDNF1);
849 aPlnN1.Coefficients(A, B, C, D);
850 //
851 d2 = A*aPF2.X() + B*aPF2.Y() + C*aPF2.Z() + D;
852 d2Adj= A*aPF2Adj.X() + B*aPF2Adj.Y()+ C*aPF2Adj.Z() + D;
853 //
854 if (fabs(d2)<1.e-10) {
855 d2=0.;
856 }
857 if (fabs(d2Adj)<1.e-10) {
858 d2Adj=0.;
859 }
860 //
861 aT=d2*d2Adj;
862 //
863 return (aT >= 0.);
864}
865
866//=======================================================================
867//function : SenseFlag
868//purpose :
869//=======================================================================
870 Standard_Integer BOPTools_Tools3D::SenseFlag (const gp_Dir& aDNF1,
871 const gp_Dir& aDNF2)
872{
873 Standard_Boolean bIsDirsCoinside;
874 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
875 if (!bIsDirsCoinside) {
876 return 0;
877 }
878
879 Standard_Real aScPr;
880
881 aScPr=aDNF1*aDNF2;
882 if (aScPr<0.) {
883 return -1;
884 }
885 else if (aScPr>0.) {
886 return 1;
887 }
888 return -1;
889}
890
891//=======================================================================
892//function : GetNormalToSurface
893//purpose :
894//=======================================================================
895 Standard_Boolean BOPTools_Tools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS,
896 const Standard_Real U,
897 const Standard_Real V,
898 gp_Dir& aDNS)
899{
900 Standard_Boolean bFlag;
901
902 gp_Pnt aP;
903 gp_Vec aD1U, aD1V;
904
905 aS->D1(U, V, aP, aD1U, aD1V);
906
907 gp_Dir aDD1U(aD1U);
908 gp_Dir aDD1V(aD1V);
909
910 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
911 if (!bFlag) {
912 return bFlag;
913 }
914
915 aDNS=aDD1U^aDD1V;
916 return bFlag;
917}
918
919//=======================================================================
920//function : GetNormalToSurface
921//purpose : local modification
922//=======================================================================
923
924static void GetApproxNormalToFaceOnEdgeEx(const TopoDS_Edge& aE,
925 const TopoDS_Face& aF,
926 const Standard_Real aT,
927 const Standard_Real aDT,
928 gp_Pnt& aPNear,
929 gp_Dir& aDNF)
930{
931 Standard_Real aFirst, aLast;
932 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
933
934 if (aC2D.IsNull()) {
935 return;
936 }
937
938 //gp_Pnt aPNear;
939 gp_Pnt2d aPx2DNear;
940 BOPTools_Tools3D::PointNearEdge (aE, aF, aT, aDT, aPx2DNear, aPNear);
941
942 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
943
944 BOPTools_Tools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
945
946 if (aF.Orientation()==TopAbs_REVERSED){
947 aDNF.Reverse();
948 }
949}
950
951//=======================================================================
952//function : GetPlanes
953//purpose :
954//=======================================================================
955 void BOPTools_Tools3D::GetPlanes (const TopoDS_Edge& aSpx,
956 const TopoDS_Edge& anEx,
957 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
958 const TopoDS_Edge& anE1,
959 const TopoDS_Face& aF1,
960 TopAbs_State& aStPF1,
4f189102 961 const Handle(IntTools_Context)& aContext)
7fd59977 962{
963 Standard_Boolean bIsAdjExists;
964
965 Standard_Real aT, aT1, aT2;
966 gp_Dir aDNFx1, aDNFx2;
967 gp_Pnt aPx, aPx1, aPx2, aPF1;
968 TopoDS_Face aFx1, aFx2;
969 //
970 // Point
971 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpx, aT1, aT2);
972 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
973
974 aC3D->D0(aT, aPx);
975 //
976 // 1.1. Fx1, Fx2 and theirs normals
977 TopAbs_Orientation anOrEx, anOr;
978 anOrEx=anEx.Orientation();
979
980 TopoDS_Edge aSpxSimm=anEx;
981 if (anOrEx==TopAbs_FORWARD) {
982 aSpxSimm.Orientation(TopAbs_REVERSED);
983 }
984 else if (anOrEx==TopAbs_REVERSED){
985 aSpxSimm.Orientation(TopAbs_FORWARD);
986 }
987 //
988
989 const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
990 TopTools_ListIteratorOfListOfShape anIt(aLF);
991
992 for (; anIt.More(); anIt.Next()) {
993 const TopoDS_Shape& aFE=anIt.Value();
994 aFx1=TopoDS::Face(aFE);
995 anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
996 if (anOr==anOrEx){
997 break;
998 }
999 }
1000
1001 //-- EJG
1002 Standard_Boolean aMoreShift = Standard_False;
1003 Standard_Real aF2Tol = BRep_Tool::Tolerance(aFx1);
1004 Standard_Real aF1Tol = BRep_Tool::Tolerance(aF1);
1005 Standard_Real aETol = BRep_Tool::Tolerance(anEx);
1006 if( aETol > 1.e-5 && (aF2Tol > 1.e-5 && aF1Tol > 1.e-5) )
1007 aMoreShift = Standard_True;
1008 Standard_Real aDT = 9.1e-5;
1009 if( aMoreShift ) {
1010 GetApproxNormalToFaceOnEdgeEx(anEx, aFx1, aT, aDT, aPx1, aDNFx1);
1011 }
1012 else {
1013 //-- EJG
1014 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
1015 }
1016
1017 bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
1018
1019 if (!bIsAdjExists) {
1020 //-- EJG
1021 if( aMoreShift ) {
1022 GetApproxNormalToFaceOnEdgeEx(aSpxSimm, aFx1, aT, aDT, aPx2, aDNFx2);
1023 }
1024 else {
1025 //-- EJG
1026 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2);
1027 }
1028
4f189102 1029 aContext->ProjectPointOnEdge(aPx, anE1, aT1);
7fd59977 1030 PointNearE (anE1, aF1, aT1, aPF1, aMoreShift);
1031 }
1032
1033 else {// if (bIsAdjExists)
1034 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
1035 //
4f189102 1036 aContext->ProjectPointOnEdge(aPx, anE1, aT1);
7fd59977 1037 PointNearE (anE1, aF1, aT1, aPF1, aMoreShift);
1038 }
1039
1040 {
1041 Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
1042
c6541a0c 1043 aTwoPI = M_PI + M_PI;
7fd59977 1044
1045 gp_Vec aVx1(aPx, aPx1);
1046 gp_Dir aDBx1 (aVx1);
1047 gp_Pln aPlnToCompare (aPx, aDNFx1);
1048
1049 gp_Vec aVx2(aPx, aPx2);
1050 gp_Dir aDBx2 (aVx2);
1051
1052 anAlfa12=aDBx1.Angle(aDBx2);
1053 d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
1054 if (d12 < 0.) {
1055 anAlfa12=aTwoPI-anAlfa12;
1056 }
1057
1058 gp_Vec aVF1(aPx, aPF1);
1059 gp_Dir aDBF1 (aVF1);
1060 anAlfa1=aDBx1.Angle(aDBF1);
1061 d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
1062 if (d1 < 0.) {
1063 anAlfa1=aTwoPI-anAlfa1;
1064 }
1065
1066 aStPF1=TopAbs_OUT;
1067 if (anAlfa1 > anAlfa12) {
1068 aStPF1=TopAbs_IN;
1069 }
1070 }
1071}
1072
1073//=======================================================================
1074//function : Orientation
1075//purpose :
1076//=======================================================================
1077 TopAbs_Orientation BOPTools_Tools3D::Orientation(const TopoDS_Edge& anE,
1078 const TopoDS_Face& aF)
1079{
1080 TopAbs_Orientation anOr=TopAbs_INTERNAL;
1081
1082 TopExp_Explorer anExp;
1083 anExp.Init(aF, TopAbs_EDGE);
1084 for (; anExp.More(); anExp.Next()) {
1085 const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current());
1086 if (anEF1.IsEqual(anE)) {
1087 anOr=anEF1.Orientation();
1088 break;
1089 }
1090 }
1091 return anOr;
1092}
1093
1094//=======================================================================
1095//function : SignDistance
1096//purpose :
1097//=======================================================================
1098 Standard_Real BOPTools_Tools3D::SignDistance(const gp_Pnt& aP,
1099 const gp_Pln& aPln)
1100{
1101 Standard_Real A, B, C, D, d;
1102 aPln.Coefficients(A, B, C, D);
1103 //
1104 d = A*aP.X() + B*aP.Y() + C*aP.Z() + D;
1105
1106 return d;
1107}
1108
1109//=======================================================================
1110// function: IsValidArea
1111// purpose:
1112//=======================================================================
1113 Standard_Boolean BOPTools_Tools3D::IsValidArea (const TopoDS_Face& aF,
1114 Standard_Boolean& bNegativeFlag)
1115
1116{
1117 Standard_Boolean bFlag;
1118 Standard_Real aMass, dM=1.e-16;
1119 GProp_GProps G;
1120 BRepGProp::SurfaceProperties(aF,G);
1121 aMass=G.Mass();
1122 //
1123 bFlag=(fabs(aMass)-dM > 0.);
1124 bNegativeFlag=(aMass < dM);
1125
1126 if( bNegativeFlag ) {
1127 Bnd_Box boxF;
1128 BRepBndLib::AddClose(aF, boxF);
1129 Standard_Real aXmin = 0, aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.;
1130 boxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1131 Standard_Boolean bigX = (fabs(aXmax-aXmin) >= 1.e+10);
1132 Standard_Boolean bigY = (fabs(aYmax-aYmin) >= 1.e+10);
1133 Standard_Boolean bigZ = (fabs(aZmax-aZmin) >= 1.e+10);
1134 if( !bigX && (!bigY && !bigZ) ) {
1135 TopExp_Explorer anExp;
1136 Standard_Integer nbW = 0;
1137 for(anExp.Init(aF, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1138 const TopoDS_Wire& aW = TopoDS::Wire(anExp.Current());
1139 nbW++;
1140 }
1141 if( nbW == 1 ) {
1142 TopTools_IndexedDataMapOfShapeListOfShape mapVE;
1143 mapVE.Clear();
1144 TopExp::MapShapesAndAncestors(aF,TopAbs_VERTEX,TopAbs_EDGE,mapVE);
1145 Standard_Integer nbKeys = mapVE.Extent(), iKey = 0;
1146 Standard_Boolean changeFlag = Standard_True;
1147 for( iKey = 1; iKey <= nbKeys; iKey++ ) {
1148 const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey));
1149 if( iV.IsNull() ) continue;
6e6cd5d9 1150 //Standard_Real TolV = BRep_Tool::Tolerance(iV);
7fd59977 1151 const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey);
1152 Standard_Integer nbE = iLE.Extent();
1153 if( nbE != 2 ) {
1154 changeFlag = Standard_False;
1155 break;
1156 }
1157 const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First());
1158 const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last());
1159 if(BRep_Tool::Degenerated(iE1) ||
1160 BRep_Tool::Degenerated(iE2) ) continue;
1161 Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1);
1162 Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2);
1163 Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.;
1164 Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1);
1165 Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2);
1166 if( aC3D1.IsNull() || aC3D2.IsNull() ) {
1167 changeFlag = Standard_False;
1168 break;
1169 }
1170 if( Abs(Abs(pL1-pF1)-Abs(pL2-pF2)) <= 1.e-10 ) {
1171 changeFlag = Standard_False;
1172 break;
1173 }
1174 gp_Pnt aPnt1 = aC3D1->Value(iPE1);
1175 gp_Pnt aPnt2 = aC3D2->Value(iPE2);
1176 Standard_Real dist = aPnt1.Distance(aPnt2);
1177 Standard_Real TolE1 = BRep_Tool::Tolerance(iE1);
1178 Standard_Real TolE2 = BRep_Tool::Tolerance(iE2);
1179 if( dist > (/*TolV+*/TolE1+TolE2) ) {
1180 changeFlag = Standard_False;
1181 break;
1182 }
1183 }
1184 if( changeFlag ) bNegativeFlag = 0;
1185 }
1186 }
1187 }
1188
1189 //
1190 return bFlag;
1191}
1192
1193//=======================================================================
1194// function: PointNearE
1195// purpose:
1196//=======================================================================
1197void PointNearE (const TopoDS_Edge& aE,
1198 const TopoDS_Face& aF,
1199 const Standard_Real aT,
1200 gp_Pnt& aPInFace,
1201 const Standard_Boolean aSt)
1202{
1203 Standard_Real aT1, aT2;
1204 //
1205 // 1. a Point on Edge aPOnEdge
1206 Handle(Geom_Curve)aC=BRep_Tool::Curve(aE, aT1, aT2);
1207 gp_Pnt aPOnEdge;
1208 gp_Pnt2d aPInFace2D;
1209 //
1210 aC->D0 (aT, aPOnEdge);
1211 //
1212 // 2. a Point inside Face near aPOnEdge aPInFace;
1213 TopoDS_Face aFF=aF;
1214 TopoDS_Edge aERight;
1215 aFF.Orientation(TopAbs_FORWARD);
1216 BOPTools_Tools3D::OrientEdgeOnFace (aE, aFF, aERight);
1217 //
1218 //
1219 Standard_Real aTolE, aDt2D;
1220 GeomAbs_SurfaceType aType;
1221 {
1222 aDt2D=BOPTools_Tools3D::MinStepIn2d();
1223 //
1224 Handle(Geom_Surface) aS=BRep_Tool::Surface(aFF);
1225 GeomAdaptor_Surface aGASF(aS);
1226 aType=aGASF.GetType();
1227 if (aType==GeomAbs_Plane) {
1228 aTolE=BRep_Tool::Tolerance(aE);
1229 if (aTolE>aDt2D) {
1230 aDt2D=aTolE;
1231 }
1232 }
1233
1234 }
1235
1236 //-- EJG
1237 if( aSt )
1238 if( aDt2D < 1.e-4)
1239 aDt2D *= 10.;
1240 //-- EJG
1241
1242 //
1243 BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aDt2D, aPInFace2D, aPInFace);
1244 //
1245 if (BRep_Tool::IsClosed(aE, aF)) {
1246 Standard_Real X, Y, UMin, UMax, VMin, VMax;
1247 X=aPInFace2D.X();
1248 Y=aPInFace2D.Y();
1249 BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
1250 if (!(X >= UMin && X <= UMax && Y >= VMin && Y <= VMax)) {
1251 aERight.Reverse();
1252 BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace);
1253 }
1254 }
1255
1256}
1257
1258static Standard_Boolean PseudoSDFaces(const BRepAdaptor_Surface& BS1,
1259 const BRepAdaptor_Surface& BS2)
1260{
1261 Standard_Real TolF1 = BS1.Tolerance();
1262 Standard_Real TolF2 = BS2.Tolerance();
1263
1264 gp_Pln Pln1 = BS1.Plane();
1265 gp_Pln Pln2 = BS2.Plane();
1266
1267 TopExp_Explorer anExpE;
1268 Standard_Real pF = 0., pL = 0.;
1269
1270
1271 const TopoDS_Face& aF1 = BS1.Face();
6e6cd5d9 1272 Standard_Real maxTolE1 = 1.e-7;
7fd59977 1273 Standard_Integer nbE1 = 0, nbOnE1 = 0;
1274 for(anExpE.Init(aF1, TopAbs_EDGE); anExpE.More(); anExpE.Next()) {
1275 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
1276 nbE1++;
1277 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1278 if( aTolE > maxTolE1 ) maxTolE1 = aTolE;
1279 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL);
1280 if( !aC3D.IsNull() ) {
1281 Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL);
1282 gp_Pnt mPnt = aC3D->Value(pM);
1283 Standard_Real distMP = Pln2.Distance(mPnt);
1284
1285 if( distMP <= aTolE )
1286 nbOnE1++;
1287 else {
1288 TopoDS_Vertex Vf, Vl;
1289 TopExp::Vertices(aE,Vf,Vl);
1290 if( !Vf.IsNull() && !Vl.IsNull() ) {
1291 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1292 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1293 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1294 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1295 Standard_Real distF = Pln2.Distance(aPntF);
1296 Standard_Real distL = Pln2.Distance(aPntL);
1297 if( distF <= aTolVf && distL <= aTolVl )
1298 nbOnE1++;
1299 }
1300 else if( !Vf.IsNull() && Vl.IsNull() ) {
1301 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1302 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1303 Standard_Real distF = Pln2.Distance(aPntF);
1304 if( distF <= aTolVf )
1305 nbOnE1++;
1306 }
1307 else if( Vf.IsNull() && !Vl.IsNull() ) {
1308 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1309 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1310 Standard_Real distL = Pln2.Distance(aPntL);
1311 if( distL <= aTolVl )
1312 nbOnE1++;
1313 }
1314 else
1315 continue;
1316 }
1317 }
1318 }
1319
1320 Standard_Boolean procF1 = ((maxTolE1/TolF1) >= 1000. ||
1321 (TolF1/maxTolE1) >= 1000.) ? Standard_True : Standard_False;
1322 procF1 = (procF1 && (nbE1 > 1 && nbOnE1 > 1) );
1323
1324 if( !procF1 )
1325 return Standard_False;
1326
1327 const TopoDS_Face& aF2 = BS1.Face();
6e6cd5d9 1328 Standard_Real maxTolE2 = 1.e-7;
7fd59977 1329 Standard_Integer nbE2 = 0, nbOnE2 = 0;
1330 for(anExpE.Init(aF2, TopAbs_EDGE); anExpE.More(); anExpE.Next()) {
1331 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
1332 nbE2++;
1333 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1334 if( aTolE > maxTolE2 ) maxTolE2 = aTolE;
1335 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL);
1336 if( !aC3D.IsNull() ) {
1337 Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL);
1338 gp_Pnt mPnt = aC3D->Value(pM);
1339 Standard_Real distMP = Pln1.Distance(mPnt);
1340 if( distMP <= aTolE )
1341 nbOnE2++;
1342 else {
1343 TopoDS_Vertex Vf, Vl;
1344 TopExp::Vertices(aE,Vf,Vl);
1345 if( !Vf.IsNull() && !Vl.IsNull() ) {
1346 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1347 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1348 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1349 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1350 Standard_Real distF = Pln1.Distance(aPntF);
1351 Standard_Real distL = Pln1.Distance(aPntL);
1352 if( distF <= aTolVf && distL <= aTolVl )
1353 nbOnE2++;
1354 }
1355 else if( !Vf.IsNull() && Vl.IsNull() ) {
1356 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1357 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1358 Standard_Real distF = Pln1.Distance(aPntF);
1359 if( distF <= aTolVf )
1360 nbOnE2++;
1361 }
1362 else if( Vf.IsNull() && !Vl.IsNull() ) {
1363 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1364 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1365 Standard_Real distL = Pln1.Distance(aPntL);
1366 if( distL <= aTolVl )
1367 nbOnE2++;
1368 }
1369 else
1370 continue;
1371 }
1372 }
1373 }
1374
1375 Standard_Boolean procF2 = ((maxTolE2/TolF2) >= 1000. ||
1376 (TolF2/maxTolE2) >= 1000.) ? Standard_True : Standard_False;
1377 procF2 = (procF2 && (nbE2 > 1 && nbOnE2 > 1) );
1378
1379 return (procF1 && procF2);
1380
1381}
1382
1383Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1,
1384 const TopoDS_Face& F2,
1385 const TopoDS_Face& F3)
1386{
1387 BRepAdaptor_Surface aBS1(F1);
1388 BRepAdaptor_Surface aBS2(F2);
1389 BRepAdaptor_Surface aBS3(F3);
1390
1391 GeomAbs_SurfaceType aT1 = aBS1.GetType();
1392 GeomAbs_SurfaceType aT2 = aBS2.GetType();
1393 GeomAbs_SurfaceType aT3 = aBS3.GetType();
1394
1395 if(aT1 == GeomAbs_Cylinder ||
1396 aT1 == GeomAbs_Cone ||
1397 aT1 == GeomAbs_Sphere ||
1398 aT1 == GeomAbs_Torus ) return Standard_True;
1399
1400 if(aT2 == GeomAbs_Cylinder ||
1401 aT2 == GeomAbs_Cone ||
1402 aT3 == GeomAbs_Sphere ||
1403 aT3 == GeomAbs_Torus ) return Standard_True;
1404
1405 if(aT3 == GeomAbs_Cylinder ||
1406 aT3 == GeomAbs_Cone ||
1407 aT3 == GeomAbs_Sphere ||
1408 aT3 == GeomAbs_Torus ) return Standard_True;
1409
1410 if( aT1 == GeomAbs_Plane && aT2 == GeomAbs_Plane ) {
1411 if( PseudoSDFaces(aBS1, aBS2) )
1412 return Standard_False;
1413 }
1414 else if( aT1 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) {
1415 if( PseudoSDFaces(aBS1, aBS3) )
1416 return Standard_False;
1417 }
1418 else if( aT2 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) {
1419 if( PseudoSDFaces(aBS2, aBS3) )
1420 return Standard_False;
1421 }
1422 else
1423 return Standard_True;
1424 return Standard_True;
1425}