0025416: Wrong section curve
[occt.git] / src / BOPTools / BOPTools_AlgoTools3D.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
4e57c75e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
4e57c75e 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.
4e57c75e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
4e57c75e 14
15#include <BOPTools_AlgoTools3D.ixx>
16
6303cb12 17#include <Bnd_Box.hxx>
18#include <Poly_Triangulation.hxx>
4e57c75e 19
20#include <gp_Vec2d.hxx>
21#include <gp_Pnt2d.hxx>
22#include <gp_Lin2d.hxx>
23#include <gp_Dir2d.hxx>
24#include <gp_Vec.hxx>
25#include <gp_Dir.hxx>
26#include <gp_Pln.hxx>
6303cb12 27#include <gp_Cylinder.hxx>
4e57c75e 28
29#include <Geom2d_Curve.hxx>
30#include <Geom2d_TrimmedCurve.hxx>
31#include <Geom2d_Line.hxx>
32
33#include <Geom_Curve.hxx>
34#include <Geom_Surface.hxx>
35#include <Geom_BSplineSurface.hxx>
36#include <Geom_BezierSurface.hxx>
6303cb12 37#include <Geom_RectangularTrimmedSurface.hxx>
4e57c75e 38
39#include <GeomAdaptor_Surface.hxx>
6303cb12 40#include <Geom2dAdaptor_Curve.hxx>
41#include <Geom2dHatch_Hatcher.hxx>
42#include <HatchGen_Domain.hxx>
4e57c75e 43
6303cb12 44#include <TopoDS.hxx>
45#include <TopoDS_Shape.hxx>
46#include <TopoDS_Edge.hxx>
47#include <TopoDS_Face.hxx>
48#include <TopoDS_Vertex.hxx>
4e57c75e 49
6303cb12 50#include <BRep_Builder.hxx>
51#include <BRep_Tool.hxx>
4e57c75e 52#include <BRep_TVertex.hxx>
53#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
54#include <BRep_PointRepresentation.hxx>
55#include <BRep_TEdge.hxx>
56#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
57#include <BRep_CurveRepresentation.hxx>
58#include <BRep_TFace.hxx>
6303cb12 59
60#include <BRepTools.hxx>
61#include <BRepBndLib.hxx>
62#include <BRepAdaptor_Surface.hxx>
63
64#include <TopExp.hxx>
65#include <TopExp_Explorer.hxx>
66
67#include <GProp_GProps.hxx>
68#include <BRepGProp.hxx>
69
70#include <BOPCol_IndexedMapOfShape.hxx>
71#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
72
73#include <IntTools_Tools.hxx>
1e143abb 74#include <IntTools_Context.hxx>
6303cb12 75
76#include <BOPTools_AlgoTools2D.hxx>
4e57c75e 77
78static void Add(const TopoDS_Shape& aS,
79 BOPCol_IndexedMapOfShape& myShapes,
80 Standard_Boolean& bHasGeometry);
81static
82 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
83
84//=======================================================================
85//function : DoSplitSEAMOnFace
86//purpose :
87//=======================================================================
362dec17 88void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
89 const TopoDS_Face& aF)
4e57c75e 90{
362dec17 91 Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
92 Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU, anU1;
93 Standard_Real aScPr, anV, dV, anV1;
6303cb12 94 Standard_Real aUmin, aUmax, aVmin, aVmax;
4e57c75e 95 gp_Pnt2d aP2D;
96 gp_Vec2d aVec2D;
97 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
98 Handle(Geom2d_Curve) C2D1;
99 Handle(Geom2d_Line) aLD1;
100 Handle(Geom_Surface) aS;
101 BRep_Builder BB;
102 TopoDS_Edge aSp;
103 //
362dec17 104 bIsLeft = Standard_False;
4e57c75e 105 aSp=aSplit;
106 aSp.Orientation(TopAbs_FORWARD);
4e57c75e 107 aTol=BRep_Tool::Tolerance(aSp);
fe343049 108 //
4e57c75e 109 aS=BRep_Tool::Surface(aF);
6303cb12 110 //
111 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
112 //
4e57c75e 113 bIsUPeriodic=aS->IsUPeriodic();
fe343049 114 bIsVPeriodic=aS->IsVPeriodic();
115 //
116 anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
117 anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
118 //
119 if (!bIsUPeriodic && !bIsVPeriodic) {
120 Standard_Boolean bIsUClosed, bIsVClosed;
4e57c75e 121 Handle(Geom_BSplineSurface) aBS;
122 Handle(Geom_BezierSurface) aBZ;
6303cb12 123 Handle(Geom_RectangularTrimmedSurface) aRTS;
4e57c75e 124 //
125 bIsUClosed=Standard_False;
fe343049 126 bIsVClosed=Standard_False;
4e57c75e 127 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
128 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
6303cb12 129 aRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
4e57c75e 130 //
131 if (!aBS.IsNull()) {
132 bIsUClosed=aBS->IsUClosed();
fe343049 133 bIsVClosed=aBS->IsVClosed();
4e57c75e 134 }
135 else if (!aBZ.IsNull()) {
136 bIsUClosed=aBZ->IsUClosed();
fe343049 137 bIsVClosed=aBZ->IsVClosed();
4e57c75e 138 }
6303cb12 139 else if (!aRTS.IsNull()) {
140 Handle(Geom_Surface) aSB;
141 //
142 aSB=aRTS->BasisSurface();
143 bIsUPeriodic=aSB->IsUPeriodic();
144 bIsVPeriodic=aSB->IsVPeriodic();
145 //
146 if (!(bIsUPeriodic || bIsVPeriodic)) {
147 return;
148 }
149 anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
150 anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
4e57c75e 151 }
152 //
6303cb12 153 if (aRTS.IsNull()) {
154 if (!bIsUClosed && !bIsVClosed) {
155 return;
156 }
157 //
158 if (bIsUClosed) {
159 anUPeriod=aUmax-aUmin;
160 }
161 if (bIsVClosed) {
162 anVPeriod=aVmax-aVmin;
163 }
fe343049 164 }
4e57c75e 165 }
166 //
6303cb12 167 //---------------------------------------------------
4e57c75e 168 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
169 //
170 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
171 C2D1->D1(aT, aP2D, aVec2D);
fe343049 172 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
4e57c75e 173 //
fe343049 174 anU=aP2D.X();
175 anV=aP2D.Y();
4e57c75e 176 //
fe343049 177 anU1=anU;
178 anV1=anV;
4e57c75e 179 //
0929d0ef 180 GeomAdaptor_Surface aGAS(aS);
181 dU = aGAS.UResolution(aTol);
182 dV = aGAS.VResolution(aTol);
183 //
fe343049 184 if (anUPeriod > 0.){
6303cb12 185 if (fabs (anU-aUmin) < dU) {
fe343049 186 bIsLeft=Standard_True;
187 anU1=anU+anUPeriod;
188 }
6303cb12 189 else if (fabs (anU-aUmax) < dU) {
fe343049 190 bIsLeft=Standard_False;
191 anU1=anU-anUPeriod;
192 }
4e57c75e 193 }
fe343049 194 //
195 if (anVPeriod > 0.) {
6303cb12 196 if (fabs (anV-aVmin) < dV) {
fe343049 197 bIsLeft=Standard_True;
198 anV1=anV+anVPeriod;
199 }
6303cb12 200 else if (fabs (anV-aVmax) < dV) {
fe343049 201 bIsLeft=Standard_False;
202 anV1=anV-anVPeriod;
203 }
4e57c75e 204 }
fe343049 205 //
206 if (anU1==anU && anV1==anV) {
4e57c75e 207 return;
208 }
209 //
fe343049 210 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
211 //
4e57c75e 212 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
362dec17 213 Handle(Geom2d_TrimmedCurve) aC1 =
214 new Geom2d_TrimmedCurve(aTmpC1, a, b);
fe343049 215 //
4e57c75e 216 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
362dec17 217 Handle(Geom2d_TrimmedCurve) aC2 =
218 new Geom2d_TrimmedCurve(aTmpC2, a, b);
fe343049 219 gp_Vec2d aTrV(anU1-anU, anV1-anV);
4e57c75e 220 aC2->Translate(aTrV);
221 //
222 if (!bIsLeft) {
223 if (aScPr<0.) {
224 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
225 }
226 else {
227 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
228 }
229 }
230 else {
231 if (aScPr<0.) {
232 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
233 }
234 else {
235 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
236 }
237 }
4e57c75e 238}
4e57c75e 239//=======================================================================
240//function : GetNormalToFaceOnEdge
241//purpose :
242//=======================================================================
362dec17 243void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
244 const TopoDS_Face& aF,
245 gp_Dir& aDNF)
4e57c75e 246{
247 Standard_Real aT, aT1, aT2;
248
249 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
250 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
251
252 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
253
254 if (aF.Orientation()==TopAbs_REVERSED){
255 aDNF.Reverse();
256 }
257}
4e57c75e 258//=======================================================================
259//function : GetNormalToFaceOnEdge
260//purpose :
261//=======================================================================
362dec17 262void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
263 const TopoDS_Face& aF1,
264 const Standard_Real aT,
265 gp_Dir& aDNF1)
4e57c75e 266{
267 Standard_Real U, V, aTolPC;
268 gp_Pnt2d aP2D;
269 gp_Pnt aP;
270 gp_Vec aD1U, aD1V;
271
272 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
273
274 Handle(Geom2d_Curve)aC2D1;
275 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
276
277 aC2D1->D0(aT, aP2D);
278 U=aP2D.X();
279 V=aP2D.Y();
280
281 aS1->D1(U, V, aP, aD1U, aD1V);
282 gp_Dir aDD1U(aD1U);
283 gp_Dir aDD1V(aD1V);
284
285 aDNF1=aDD1U^aDD1V;
286}
4e57c75e 287//=======================================================================
288//function : SenseFlag
289//purpose :
290//=======================================================================
362dec17 291Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
292 const gp_Dir& aDNF2)
4e57c75e 293{
294 Standard_Boolean bIsDirsCoinside;
362dec17 295 //
4e57c75e 296 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
297 if (!bIsDirsCoinside) {
298 return 0;
299 }
300
301 Standard_Real aScPr;
302
303 aScPr=aDNF1*aDNF2;
304 if (aScPr<0.) {
305 return -1;
306 }
307 else if (aScPr>0.) {
308 return 1;
309 }
310 return -1;
311}
4e57c75e 312//=======================================================================
313//function : GetNormalToSurface
314//purpose :
315//=======================================================================
362dec17 316Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
317 (const Handle(Geom_Surface)& aS,
318 const Standard_Real U,
319 const Standard_Real V,
320 gp_Dir& aDNS)
4e57c75e 321{
322 Standard_Boolean bFlag;
323
324 gp_Pnt aP;
325 gp_Vec aD1U, aD1V;
326
327 aS->D1(U, V, aP, aD1U, aD1V);
328
329 gp_Dir aDD1U(aD1U);
330 gp_Dir aDD1V(aD1V);
331
332 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
333 if (!bFlag) {
334 return bFlag;
335 }
336
337 aDNS=aDD1U^aDD1V;
338 return bFlag;
339}
4e57c75e 340//=======================================================================
341//function : GetApproxNormalToFaceOnEdge
342//purpose :
343//=======================================================================
362dec17 344void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
345 (const TopoDS_Edge& aE,
346 const TopoDS_Face& aF,
347 const Standard_Real aT,
348 gp_Pnt& aPNear,
349 gp_Dir& aDNF,
350 Standard_Real aDt2D)
4e57c75e 351{
352 Standard_Real aFirst, aLast;
362dec17 353 Handle(Geom2d_Curve) aC2D=
354 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
4e57c75e 355
356 if (aC2D.IsNull()) {
357 return;
358 }
359 gp_Pnt2d aPx2DNear;
360 PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
361 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
362
362dec17 363 BOPTools_AlgoTools3D::GetNormalToSurface
364 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
4e57c75e 365
366 if (aF.Orientation()==TopAbs_REVERSED){
367 aDNF.Reverse();
368 }
369}
4e57c75e 370//=======================================================================
371//function : GetApproxNormalToFaceOnEdge
372//purpose :
373//=======================================================================
362dec17 374void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
375 (const TopoDS_Edge& aE,
376 const TopoDS_Face& aF,
377 const Standard_Real aT,
378 gp_Pnt& aPNear,
379 gp_Dir& aDNF,
1e143abb 380 Handle(IntTools_Context)& theContext)
4e57c75e 381{
382 Standard_Real aFirst, aLast;
362dec17 383 Handle(Geom2d_Curve) aC2D=
384 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
4e57c75e 385
386 if (aC2D.IsNull()) {
387 return;
388 }
389 //gp_Pnt aPNear;
390 gp_Pnt2d aPx2DNear;
362dec17 391 BOPTools_AlgoTools3D::PointNearEdge
392 (aE, aF, aT, aPx2DNear, aPNear, theContext);
4e57c75e 393
394 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
395
362dec17 396 BOPTools_AlgoTools3D::GetNormalToSurface
397 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
4e57c75e 398
399 if (aF.Orientation()==TopAbs_REVERSED){
400 aDNF.Reverse();
401 }
402}
4e57c75e 403//=======================================================================
404//function : PointNearEdge
405//purpose :
406//=======================================================================
362dec17 407void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
408 const TopoDS_Face& aF,
409 const Standard_Real aT,
410 const Standard_Real aDt2D,
411 gp_Pnt2d& aPx2DNear,
412 gp_Pnt& aPxNear)
4e57c75e 413{
414 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
415 GeomAbs_SurfaceType aTS;
416 Handle(Geom2d_Curve) aC2D;
417 Handle(Geom_Surface) aS;
418 //
419 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
420 if (aC2D.IsNull()) {
421 aPx2DNear.SetCoord (99., 99);
422 return;
423 }
424 //
425 aS=BRep_Tool::Surface(aF);
426 //
427 gp_Pnt2d aPx2D;
428 gp_Vec2d aVx2D;
429 aC2D->D1 (aT, aPx2D, aVx2D);
430 gp_Dir2d aDx2D(aVx2D);
431
432 gp_Dir2d aDP;
433 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
434
435 if (aE.Orientation()==TopAbs_REVERSED){
436 aDP.Reverse();
437 }
438
439 if (aF.Orientation()==TopAbs_REVERSED) {
440 aDP.Reverse();
441 }
442 //
443 aETol = BRep_Tool::Tolerance(aE);
444 aFTol = BRep_Tool::Tolerance(aF);
f4ea2ca6 445 // NPAL19220
4e57c75e 446 GeomAdaptor_Surface aGAS(aS);
447 aTS=aGAS.GetType();
448 if (aTS==GeomAbs_BSplineSurface) {
449 if (aETol > 1.e-5) {
450 aFTol=aETol;
451 }
452 }
453 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
6303cb12 454 //
4e57c75e 455 if(aTS!=GeomAbs_Sphere) {
456 gp_Vec2d transVec( aDP );
457 transVal = aDt2D + aETol + aFTol;
458 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
459 Standard_Real aR, dT;
460 //
461 gp_Cylinder aCyl=aGAS.Cylinder();
462 aR=aCyl.Radius();
463 dT=1.-transVal/aR;
464 if (dT>=-1 && dT<=1) {
465 dT=acos(dT);
466 transVal=dT;
467 }
468 }
469 //
470 transVec.Multiply(transVal);
471 aPx2DNear = aPx2D.Translated( transVec );
472 }
473 else {
362dec17 474 aPx2DNear.SetCoord
475 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
4e57c75e 476 }
477 }
478 else {
362dec17 479 aPx2DNear.SetCoord
480 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
4e57c75e 481 }
482 //
483 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
484}
4e57c75e 485//=======================================================================
486//function : PointNearEdge
487//purpose :
488//=======================================================================
362dec17 489void BOPTools_AlgoTools3D::PointNearEdge
490 (const TopoDS_Edge& aE,
491 const TopoDS_Face& aF,
492 const Standard_Real aT,
493 gp_Pnt2d& aPx2DNear,
494 gp_Pnt& aPxNear,
1e143abb 495 Handle(IntTools_Context)& theContext)
4e57c75e 496{
f4ea2ca6 497 Standard_Real aTolE, aTolF, dTx, dT2D;
498 Handle(Geom_Surface) aS;
499 GeomAdaptor_Surface aGAS;
4e57c75e 500 //
f4ea2ca6 501 dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
502 //
503 aS = BRep_Tool::Surface(aF);
504 aGAS.Load(aS);
4e57c75e 505 if (aGAS.GetType()==GeomAbs_Cylinder ||
506 aGAS.GetType()==GeomAbs_Sphere) {
f4ea2ca6 507 dT2D=10.*dT2D;
508 }
509 //
4e57c75e 510 aTolE = BRep_Tool::Tolerance(aE);
511 aTolF = BRep_Tool::Tolerance(aF);
f4ea2ca6 512 dTx = 2.*(aTolE + aTolF);
513 if (dTx > dT2D) {
514 dT2D=dTx;
515 }
516 //
362dec17 517 BOPTools_AlgoTools3D::PointNearEdge
518 (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
4e57c75e 519 if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
f4ea2ca6 520 Standard_Integer iErr;
521 Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
4e57c75e 522 gp_Pnt aP;
523 gp_Pnt2d aP2d;
4e57c75e 524 //
f4ea2ca6 525 BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
526 //
527 dU=aU2-aU1;
528 dV=aV2-aV1;
529 //
530 dTresh=1.e-4;
531 if (dT2D > dTresh) {
532 dTresh=dT2D;
533 }
534 //
535 if (dU < dTresh || dV < dTresh) {
362dec17 536 iErr = BOPTools_AlgoTools3D::PointInFace
537 (aF, aP, aP2d, theContext);
4e57c75e 538 if (!iErr) {
539 aPxNear = aP;
540 aPx2DNear = aP2d;
541 }
542 }
543 }
544}
4e57c75e 545//=======================================================================
546// function: PointNearEdge
547// purpose:
548//=======================================================================
362dec17 549void BOPTools_AlgoTools3D::PointNearEdge
550 (const TopoDS_Edge& aE,
551 const TopoDS_Face& aF,
552 gp_Pnt2d& aPInFace2D,
553 gp_Pnt& aPInFace,
1e143abb 554 Handle(IntTools_Context)& theContext)
4e57c75e 555{
556 Standard_Real aT, aT1, aT2;
557 //
558 // 1.
559 BRep_Tool::Range(aE, aT1, aT2);
560 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
561 //
562 // 2. a Point inside Face near aPOnEdge aPInFace;
563 TopoDS_Face aFF=aF;
564 TopoDS_Edge aERight;
565 aFF.Orientation(TopAbs_FORWARD);
566 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
567
362dec17 568 BOPTools_AlgoTools3D::PointNearEdge
569 (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
4e57c75e 570}
4e57c75e 571//=======================================================================
572//function : MinStepIn2d
573//purpose :
574//=======================================================================
362dec17 575Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
4e57c75e 576{
577 Standard_Real dt=1.e-5;
578 return dt;
579}
4e57c75e 580//=======================================================================
581//function : IsEmptyShape
582//purpose :
583//=======================================================================
362dec17 584Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
585 (const TopoDS_Shape& aS)
4e57c75e 586{
587 Standard_Boolean bHasGeometry=Standard_False;
588 //
589 BOPCol_IndexedMapOfShape myShapes;
590 //
591 Add(aS, myShapes, bHasGeometry);
592
593 return !bHasGeometry;
594}
4e57c75e 595//=======================================================================
596//function : Add
597//purpose :
598//=======================================================================
599void Add(const TopoDS_Shape& aS,
600 BOPCol_IndexedMapOfShape& myShapes,
601 Standard_Boolean& bHasGeometry)
602{
603 Standard_Integer anIndex;
604 //
605 if (bHasGeometry) {
606 return;
607 }
608 //
609 if (aS.IsNull()) {
610 return;
611 }
612 //
613 TopoDS_Shape aSx = aS;
614 //
615 anIndex=myShapes.FindIndex(aSx);
616 if (!anIndex) {
617 bHasGeometry=HasGeometry (aSx);
618 if (bHasGeometry) {
619 return;
620 }
621 //
622 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
623 for(; anIt.More(); anIt.Next()) {
624 const TopoDS_Shape& aSy=anIt.Value();
625 Add(aSy, myShapes, bHasGeometry);
626 //
627 if (bHasGeometry) {
628 return;
629 }
630 //
631 myShapes.Add(aSx);
632 }
633 }
634}
4e57c75e 635//=======================================================================
636//function : HasGeometry
637//purpose :
638//=======================================================================
362dec17 639Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
4e57c75e 640{
641 Standard_Boolean bHasGeometry=Standard_True;
642 TopAbs_ShapeEnum aType= aS.ShapeType();
643
644 if (aType == TopAbs_VERTEX) {
362dec17 645 return bHasGeometry;
4e57c75e 646 }
4e57c75e 647 //
648 else if (aType == TopAbs_EDGE) {
649 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
650 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
651
652 while (itrc.More()) {
653 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
654 if (CR->IsCurve3D()) {
655 if (!CR->Curve3D().IsNull()) {
656 return bHasGeometry;
657 }
658 }
659 else if (CR->IsCurveOnSurface()) {
660 return bHasGeometry;
661 }
662 else if (CR->IsRegularity()) {
663 return bHasGeometry;
664 }
665 else if (!CR->Polygon3D().IsNull()) {
666 return bHasGeometry;
667 }
668 else if (CR->IsPolygonOnTriangulation()) {
669 return bHasGeometry;
670 }
671 else if (CR->IsPolygonOnSurface()) {
672 return bHasGeometry;
673 }
674 itrc.Next();
675 }
676 }
677 //
678 else if (aType == TopAbs_FACE) {
679 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
680 if (!TF->Surface().IsNull()) {
681 return bHasGeometry;
682 }
683 Handle(Poly_Triangulation) Tr = TF->Triangulation();
684 if (!Tr.IsNull()) {
685 return bHasGeometry;
686 }
687 }
688
689 return !bHasGeometry;
690}
4e57c75e 691//=======================================================================
692//function : OrientEdgeOnFace
693//purpose :
694//=======================================================================
362dec17 695void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
696 const TopoDS_Face& aF,
697 TopoDS_Edge& aERight)
4e57c75e 698{
699 if (BRep_Tool::IsClosed(aE, aF)) {
700 aERight=aE;
701 aERight.Orientation(aE.Orientation());
702
703 Standard_Integer iFoundCount = 0;
704 TopoDS_Edge anEdge = aE;
705 TopExp_Explorer anExp(aF, TopAbs_EDGE);
706
707 for (; anExp.More(); anExp.Next()) {
708 const TopoDS_Shape& aSS=anExp.Current();
709
710 if (aSS.IsSame(aE)) {
711 anEdge = TopoDS::Edge(aSS);
712 iFoundCount++;
713 }
714 }
715
716 if(iFoundCount == 1) {
717 aERight = anEdge;
718 }
719 return;
720 }
721
722 TopExp_Explorer anExp(aF, TopAbs_EDGE);
723 for (; anExp.More(); anExp.Next()) {
724 const TopoDS_Shape& aSS=anExp.Current();
725 if (aSS.IsSame(aE)) {
726 aERight=aE;
727 aERight.Orientation(aSS.Orientation());
728 return;
729 }
730 }
731 aERight=aE;
732 aERight.Orientation(aE.Orientation());
733}
4e57c75e 734//=======================================================================
735//function : PointInFace
736//purpose :
737//=======================================================================
362dec17 738Standard_Integer BOPTools_AlgoTools3D::PointInFace
739 (const TopoDS_Face& aF,
740 gp_Pnt& theP,
741 gp_Pnt2d& theP2D,
1e143abb 742 Handle(IntTools_Context)& theContext)
4e57c75e 743{
744 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
873c119f 745 Standard_Integer iErr, aIx = 0, aNbDomains = 0;
4e57c75e 746 Standard_Real aUMin, aUMax, aVMin, aVMax;
96a95605 747 Standard_Real aVx = 0., aUx, aV1, aV2;
4e57c75e 748 gp_Dir2d aD2D (0., 1.);
749 gp_Pnt2d aP2D;
750 gp_Pnt aPx;
751 Handle(Geom2d_Curve) aC2D;
752 Handle(Geom2d_Line) aL2D;
753 Handle(Geom_Surface) aS;
754 TopoDS_Face aFF;
755 //
756 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
757 //
758 iErr=0;
4e57c75e 759 //
760 aFF=aF;
761 aFF.Orientation (TopAbs_FORWARD);
762 //
763 aS=BRep_Tool::Surface(aFF);
764 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
765 //
766 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
873c119f 767 Standard_Integer i;
768 for(i = 1; i <= 2; ++i)
769 {
770 aP2D.SetCoord(aUx, 0.);
771 aL2D=new Geom2d_Line (aP2D, aD2D);
772 Geom2dAdaptor_Curve aHCur(aL2D);
773 //
774 aIx=aHatcher.AddHatching(aHCur) ;
775 //
776 aHatcher.Trim(aIx);
777 bIsDone=aHatcher.TrimDone(aIx);
778 if (!bIsDone) {
779 iErr=1;
780 return iErr;
781 }
782 //
783 if(aHatcher.NbPoints(aIx) > 1)
784 {
785 aHatcher.ComputeDomains(aIx);
786 bIsDone=aHatcher.IsDone(aIx);
787 if (!bIsDone) {
788 iErr=2;
789 return iErr;
790 }
791 break;
792 }
793 else
794 {
795 aUx = aUMax - (aUx - aUMin);
796 }
4e57c75e 797 }
798 //
d4b867e6 799 if(!aHatcher.IsDone(aIx))
800 {
801 iErr=2;
802 return iErr;
803 }
804
4e57c75e 805 aNbDomains=aHatcher.NbDomains(aIx);
3ed30348 806 if (aNbDomains > 0) {
362dec17 807 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1);
4e57c75e 808 bHasFirstPoint=aDomain.HasFirstPoint();
809 if (!bHasFirstPoint) {
810 iErr=3;
811 return iErr;
812 }
813 //
814 aV1=aDomain.FirstPoint().Parameter();
815 //
816 bHasSecondPoint=aDomain.HasSecondPoint();
817 if (!bHasSecondPoint) {
818 iErr=4;
819 return iErr;
820 }
821 //
822 aV2=aDomain.SecondPoint().Parameter();
823 //
824 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
825 //
3ed30348 826 }
827 else {
828 iErr=2;
829 return iErr;
4e57c75e 830 }
831 //
832 aS->D0(aUx, aVx, aPx);
833 //
834 theP2D.SetCoord(aUx, aVx);
835 theP=aPx;
836 //
837 return iErr;
838}