1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <BOPTools_AlgoTools3D.ixx>
18 #include <TopExp_Explorer.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Face.hxx>
24 #include <TopoDS_Vertex.hxx>
26 #include <BOPCol_IndexedMapOfShape.hxx>
27 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRepTools.hxx>
32 #include <BRepAdaptor_Surface.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <gp_Lin2d.hxx>
37 #include <gp_Dir2d.hxx>
42 #include <Geom2d_Curve.hxx>
43 #include <Geom2d_TrimmedCurve.hxx>
44 #include <Geom2d_Line.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <Geom_BSplineSurface.hxx>
49 #include <Geom_BezierSurface.hxx>
51 #include <GeomAdaptor_Surface.hxx>
53 #include <IntTools_Tools.hxx>
55 #include <BOPTools_AlgoTools2D.hxx>
57 #include <GProp_GProps.hxx>
58 #include <BRepGProp.hxx>
59 #include <BRepBndLib.hxx>
60 #include <Bnd_Box.hxx>
61 #include <gp_Cylinder.hxx>
62 #include <BRep_TVertex.hxx>
63 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
64 #include <BRep_PointRepresentation.hxx>
65 #include <BRep_TEdge.hxx>
66 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
67 #include <BRep_CurveRepresentation.hxx>
68 #include <BRep_TFace.hxx>
69 #include <Poly_Triangulation.hxx>
70 #include <BRep_Builder.hxx>
71 #include <IntTools_Context.hxx>
72 #include <Geom2dAdaptor_Curve.hxx>
73 #include <Geom2dHatch_Hatcher.hxx>
74 #include <HatchGen_Domain.hxx>
76 static void Add(const TopoDS_Shape& aS,
77 BOPCol_IndexedMapOfShape& myShapes,
78 Standard_Boolean& bHasGeometry);
80 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
82 //=======================================================================
83 //function : DoSplitSEAMOnFace
85 //=======================================================================
86 void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
87 const TopoDS_Face& aF)
89 Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft;
90 Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU, anU1;
91 Standard_Real aScPr, anV, dV, anV1;
94 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
95 Handle(Geom2d_Curve) C2D1;
96 Handle(Geom2d_Line) aLD1;
97 Handle(Geom_Surface) aS;
101 bIsLeft = Standard_False;
103 aSp.Orientation(TopAbs_FORWARD);
104 aTol=BRep_Tool::Tolerance(aSp);
106 aS=BRep_Tool::Surface(aF);
107 bIsUPeriodic=aS->IsUPeriodic();
108 bIsVPeriodic=aS->IsVPeriodic();
110 anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
111 anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
113 if (!bIsUPeriodic && !bIsVPeriodic) {
114 Standard_Boolean bIsUClosed, bIsVClosed;
115 Standard_Real aUmin = 0., aUmax = 0., aVmin = 0., aVmax = 0.;
116 Handle(Geom_BSplineSurface) aBS;
117 Handle(Geom_BezierSurface) aBZ;
119 bIsUClosed=Standard_False;
120 bIsVClosed=Standard_False;
121 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
122 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
125 bIsUClosed=aBS->IsUClosed();
126 bIsVClosed=aBS->IsVClosed();
127 aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
129 else if (!aBZ.IsNull()) {
130 bIsUClosed=aBZ->IsUClosed();
131 bIsVClosed=aBZ->IsVClosed();
132 aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
134 if (!bIsUClosed && !bIsVClosed) {
139 anUPeriod=aUmax-aUmin;
142 anVPeriod=aVmax-aVmin;
146 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
148 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
149 C2D1->D1(aT, aP2D, aVec2D);
150 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
158 GeomAdaptor_Surface aGAS(aS);
159 dU = aGAS.UResolution(aTol);
160 dV = aGAS.VResolution(aTol);
163 if (fabs (anU) < dU) {
164 bIsLeft=Standard_True;
167 else if (fabs (anU-anUPeriod) < dU) {
168 bIsLeft=Standard_False;
173 if (anVPeriod > 0.) {
174 if (fabs (anV) < dV) {
175 bIsLeft=Standard_True;
178 else if (fabs (anV-anVPeriod) < dV) {
179 bIsLeft=Standard_False;
184 if (anU1==anU && anV1==anV) {
188 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
190 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
191 Handle(Geom2d_TrimmedCurve) aC1 =
192 new Geom2d_TrimmedCurve(aTmpC1, a, b);
194 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
195 Handle(Geom2d_TrimmedCurve) aC2 =
196 new Geom2d_TrimmedCurve(aTmpC2, a, b);
197 gp_Vec2d aTrV(anU1-anU, anV1-anV);
198 aC2->Translate(aTrV);
202 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
205 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
210 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
213 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
217 //=======================================================================
218 //function : GetNormalToFaceOnEdge
220 //=======================================================================
221 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
222 const TopoDS_Face& aF,
225 Standard_Real aT, aT1, aT2;
227 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
228 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
230 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
232 if (aF.Orientation()==TopAbs_REVERSED){
236 //=======================================================================
237 //function : GetNormalToFaceOnEdge
239 //=======================================================================
240 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
241 const TopoDS_Face& aF1,
242 const Standard_Real aT,
245 Standard_Real U, V, aTolPC;
250 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
252 Handle(Geom2d_Curve)aC2D1;
253 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
259 aS1->D1(U, V, aP, aD1U, aD1V);
265 //=======================================================================
266 //function : SenseFlag
268 //=======================================================================
269 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
272 Standard_Boolean bIsDirsCoinside;
274 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
275 if (!bIsDirsCoinside) {
290 //=======================================================================
291 //function : GetNormalToSurface
293 //=======================================================================
294 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
295 (const Handle(Geom_Surface)& aS,
296 const Standard_Real U,
297 const Standard_Real V,
300 Standard_Boolean bFlag;
305 aS->D1(U, V, aP, aD1U, aD1V);
310 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
318 //=======================================================================
319 //function : GetApproxNormalToFaceOnEdge
321 //=======================================================================
322 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
323 (const TopoDS_Edge& aE,
324 const TopoDS_Face& aF,
325 const Standard_Real aT,
330 Standard_Real aFirst, aLast;
331 Handle(Geom2d_Curve) aC2D=
332 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
338 PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
339 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
341 BOPTools_AlgoTools3D::GetNormalToSurface
342 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
344 if (aF.Orientation()==TopAbs_REVERSED){
348 //=======================================================================
349 //function : GetApproxNormalToFaceOnEdge
351 //=======================================================================
352 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
353 (const TopoDS_Edge& aE,
354 const TopoDS_Face& aF,
355 const Standard_Real aT,
358 Handle(IntTools_Context)& theContext)
360 Standard_Real aFirst, aLast;
361 Handle(Geom2d_Curve) aC2D=
362 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
369 BOPTools_AlgoTools3D::PointNearEdge
370 (aE, aF, aT, aPx2DNear, aPNear, theContext);
372 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
374 BOPTools_AlgoTools3D::GetNormalToSurface
375 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
377 if (aF.Orientation()==TopAbs_REVERSED){
381 //=======================================================================
382 //function : PointNearEdge
384 //=======================================================================
385 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
386 const TopoDS_Face& aF,
387 const Standard_Real aT,
388 const Standard_Real aDt2D,
392 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
393 GeomAbs_SurfaceType aTS;
394 Handle(Geom2d_Curve) aC2D;
395 Handle(Geom_Surface) aS;
397 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
399 aPx2DNear.SetCoord (99., 99);
403 aS=BRep_Tool::Surface(aF);
407 aC2D->D1 (aT, aPx2D, aVx2D);
408 gp_Dir2d aDx2D(aVx2D);
411 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
413 if (aE.Orientation()==TopAbs_REVERSED){
417 if (aF.Orientation()==TopAbs_REVERSED) {
421 aETol = BRep_Tool::Tolerance(aE);
422 aFTol = BRep_Tool::Tolerance(aF);
424 GeomAdaptor_Surface aGAS(aS);
426 if (aTS==GeomAbs_BSplineSurface) {
431 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
432 //if( aETol > 1.e-5 && aFTol > 1.e-5 ) {
434 if(aTS!=GeomAbs_Sphere) {
435 gp_Vec2d transVec( aDP );
436 transVal = aDt2D + aETol + aFTol;
437 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
438 Standard_Real aR, dT;
440 gp_Cylinder aCyl=aGAS.Cylinder();
443 if (dT>=-1 && dT<=1) {
449 transVec.Multiply(transVal);
450 aPx2DNear = aPx2D.Translated( transVec );
454 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
459 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
462 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
464 //=======================================================================
465 //function : PointNearEdge
467 //=======================================================================
468 void BOPTools_AlgoTools3D::PointNearEdge
469 (const TopoDS_Edge& aE,
470 const TopoDS_Face& aF,
471 const Standard_Real aT,
474 Handle(IntTools_Context)& theContext)
476 Standard_Real aTolE, aTolF, dTx, dT2D;
477 Handle(Geom_Surface) aS;
478 GeomAdaptor_Surface aGAS;
480 dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
482 aS = BRep_Tool::Surface(aF);
484 if (aGAS.GetType()==GeomAbs_Cylinder ||
485 aGAS.GetType()==GeomAbs_Sphere) {
489 aTolE = BRep_Tool::Tolerance(aE);
490 aTolF = BRep_Tool::Tolerance(aF);
491 dTx = 2.*(aTolE + aTolF);
496 BOPTools_AlgoTools3D::PointNearEdge
497 (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
498 if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
499 Standard_Integer iErr;
500 Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
504 BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
514 if (dU < dTresh || dV < dTresh) {
515 iErr = BOPTools_AlgoTools3D::PointInFace
516 (aF, aP, aP2d, theContext);
524 //=======================================================================
525 // function: PointNearEdge
527 //=======================================================================
528 void BOPTools_AlgoTools3D::PointNearEdge
529 (const TopoDS_Edge& aE,
530 const TopoDS_Face& aF,
531 gp_Pnt2d& aPInFace2D,
533 Handle(IntTools_Context)& theContext)
535 Standard_Real aT, aT1, aT2;
538 BRep_Tool::Range(aE, aT1, aT2);
539 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
541 // 2. a Point inside Face near aPOnEdge aPInFace;
544 aFF.Orientation(TopAbs_FORWARD);
545 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
547 BOPTools_AlgoTools3D::PointNearEdge
548 (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
550 //=======================================================================
551 //function : MinStepIn2d
553 //=======================================================================
554 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
556 Standard_Real dt=1.e-5;
559 //=======================================================================
560 //function : IsEmptyShape
562 //=======================================================================
563 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
564 (const TopoDS_Shape& aS)
566 Standard_Boolean bHasGeometry=Standard_False;
568 BOPCol_IndexedMapOfShape myShapes;
570 Add(aS, myShapes, bHasGeometry);
572 return !bHasGeometry;
574 //=======================================================================
577 //=======================================================================
578 void Add(const TopoDS_Shape& aS,
579 BOPCol_IndexedMapOfShape& myShapes,
580 Standard_Boolean& bHasGeometry)
582 Standard_Integer anIndex;
592 TopoDS_Shape aSx = aS;
594 anIndex=myShapes.FindIndex(aSx);
596 bHasGeometry=HasGeometry (aSx);
601 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
602 for(; anIt.More(); anIt.Next()) {
603 const TopoDS_Shape& aSy=anIt.Value();
604 Add(aSy, myShapes, bHasGeometry);
614 //=======================================================================
615 //function : HasGeometry
617 //=======================================================================
618 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
620 Standard_Boolean bHasGeometry=Standard_True;
621 TopAbs_ShapeEnum aType= aS.ShapeType();
623 if (aType == TopAbs_VERTEX) {
627 else if (aType == TopAbs_EDGE) {
628 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
629 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
631 while (itrc.More()) {
632 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
633 if (CR->IsCurve3D()) {
634 if (!CR->Curve3D().IsNull()) {
638 else if (CR->IsCurveOnSurface()) {
641 else if (CR->IsRegularity()) {
644 else if (!CR->Polygon3D().IsNull()) {
647 else if (CR->IsPolygonOnTriangulation()) {
650 else if (CR->IsPolygonOnSurface()) {
657 else if (aType == TopAbs_FACE) {
658 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
659 if (!TF->Surface().IsNull()) {
662 Handle(Poly_Triangulation) Tr = TF->Triangulation();
668 return !bHasGeometry;
670 //=======================================================================
671 //function : OrientEdgeOnFace
673 //=======================================================================
674 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
675 const TopoDS_Face& aF,
676 TopoDS_Edge& aERight)
678 if (BRep_Tool::IsClosed(aE, aF)) {
680 aERight.Orientation(aE.Orientation());
682 Standard_Integer iFoundCount = 0;
683 TopoDS_Edge anEdge = aE;
684 TopExp_Explorer anExp(aF, TopAbs_EDGE);
686 for (; anExp.More(); anExp.Next()) {
687 const TopoDS_Shape& aSS=anExp.Current();
689 if (aSS.IsSame(aE)) {
690 anEdge = TopoDS::Edge(aSS);
695 if(iFoundCount == 1) {
701 TopExp_Explorer anExp(aF, TopAbs_EDGE);
702 for (; anExp.More(); anExp.Next()) {
703 const TopoDS_Shape& aSS=anExp.Current();
704 if (aSS.IsSame(aE)) {
706 aERight.Orientation(aSS.Orientation());
711 aERight.Orientation(aE.Orientation());
713 //=======================================================================
714 //function : PointInFace
716 //=======================================================================
717 Standard_Integer BOPTools_AlgoTools3D::PointInFace
718 (const TopoDS_Face& aF,
721 Handle(IntTools_Context)& theContext)
723 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
724 Standard_Integer iErr, aIx, aNbDomains;
725 Standard_Real aUMin, aUMax, aVMin, aVMax;
726 Standard_Real aVx = 0., aUx, aV1, aV2;
727 gp_Dir2d aD2D (0., 1.);
730 Handle(Geom2d_Curve) aC2D;
731 Handle(Geom2d_Line) aL2D;
732 Handle(Geom_Surface) aS;
735 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
740 aFF.Orientation (TopAbs_FORWARD);
742 aS=BRep_Tool::Surface(aFF);
743 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
745 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
746 aP2D.SetCoord(aUx, 0.);
747 aL2D=new Geom2d_Line (aP2D, aD2D);
748 Geom2dAdaptor_Curve aHCur(aL2D);
750 aIx=aHatcher.AddHatching(aHCur) ;
753 bIsDone=aHatcher.TrimDone(aIx);
759 aHatcher.ComputeDomains(aIx);
760 bIsDone=aHatcher.IsDone(aIx);
766 aNbDomains=aHatcher.NbDomains(aIx);
767 if (aNbDomains > 0) {
768 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1);
769 bHasFirstPoint=aDomain.HasFirstPoint();
770 if (!bHasFirstPoint) {
775 aV1=aDomain.FirstPoint().Parameter();
777 bHasSecondPoint=aDomain.HasSecondPoint();
778 if (!bHasSecondPoint) {
783 aV2=aDomain.SecondPoint().Parameter();
785 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
793 aS->D0(aUx, aVx, aPx);
795 theP2D.SetCoord(aUx, aVx);