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>
17 #include <Bnd_Box.hxx>
18 #include <Poly_Triangulation.hxx>
20 #include <gp_Vec2d.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Lin2d.hxx>
23 #include <gp_Dir2d.hxx>
27 #include <gp_Cylinder.hxx>
29 #include <Geom2d_Curve.hxx>
30 #include <Geom2d_TrimmedCurve.hxx>
31 #include <Geom2d_Line.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_BSplineSurface.hxx>
36 #include <Geom_BezierSurface.hxx>
37 #include <Geom_RectangularTrimmedSurface.hxx>
39 #include <GeomAdaptor_Surface.hxx>
40 #include <Geom2dAdaptor_Curve.hxx>
41 #include <Geom2dHatch_Hatcher.hxx>
42 #include <HatchGen_Domain.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Vertex.hxx>
50 #include <BRep_Builder.hxx>
51 #include <BRep_Tool.hxx>
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>
60 #include <BRepTools.hxx>
61 #include <BRepBndLib.hxx>
62 #include <BRepAdaptor_Surface.hxx>
65 #include <TopExp_Explorer.hxx>
67 #include <GProp_GProps.hxx>
68 #include <BRepGProp.hxx>
70 #include <BOPCol_IndexedMapOfShape.hxx>
71 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
73 #include <IntTools_Tools.hxx>
74 #include <IntTools_Context.hxx>
76 #include <BOPTools_AlgoTools2D.hxx>
78 static void Add(const TopoDS_Shape& aS,
79 BOPCol_IndexedMapOfShape& myShapes,
80 Standard_Boolean& bHasGeometry);
82 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
84 //=======================================================================
85 //function : DoSplitSEAMOnFace
87 //=======================================================================
88 void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
89 const TopoDS_Face& aF)
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;
94 Standard_Real aUmin, aUmax, aVmin, aVmax;
97 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
98 Handle(Geom2d_Curve) C2D1;
99 Handle(Geom2d_Line) aLD1;
100 Handle(Geom_Surface) aS;
104 bIsLeft = Standard_False;
106 aSp.Orientation(TopAbs_FORWARD);
107 aTol=BRep_Tool::Tolerance(aSp);
109 aS=BRep_Tool::Surface(aF);
111 aS->Bounds(aUmin, aUmax, aVmin, aVmax);
113 bIsUPeriodic=aS->IsUPeriodic();
114 bIsVPeriodic=aS->IsVPeriodic();
116 anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
117 anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
119 if (!bIsUPeriodic && !bIsVPeriodic) {
120 Standard_Boolean bIsUClosed, bIsVClosed;
121 Handle(Geom_BSplineSurface) aBS;
122 Handle(Geom_BezierSurface) aBZ;
123 Handle(Geom_RectangularTrimmedSurface) aRTS;
125 bIsUClosed=Standard_False;
126 bIsVClosed=Standard_False;
127 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
128 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
129 aRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
132 bIsUClosed=aBS->IsUClosed();
133 bIsVClosed=aBS->IsVClosed();
135 else if (!aBZ.IsNull()) {
136 bIsUClosed=aBZ->IsUClosed();
137 bIsVClosed=aBZ->IsVClosed();
139 else if (!aRTS.IsNull()) {
140 Handle(Geom_Surface) aSB;
142 aSB=aRTS->BasisSurface();
143 bIsUPeriodic=aSB->IsUPeriodic();
144 bIsVPeriodic=aSB->IsVPeriodic();
146 if (!(bIsUPeriodic || bIsVPeriodic)) {
149 anUPeriod = bIsUPeriodic ? aSB->UPeriod() : 0.;
150 anVPeriod = bIsVPeriodic ? aSB->VPeriod() : 0.;
154 if (!bIsUClosed && !bIsVClosed) {
159 anUPeriod=aUmax-aUmin;
162 anVPeriod=aVmax-aVmin;
167 //---------------------------------------------------
168 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
170 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
171 C2D1->D1(aT, aP2D, aVec2D);
172 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
180 GeomAdaptor_Surface aGAS(aS);
181 dU = aGAS.UResolution(aTol);
182 dV = aGAS.VResolution(aTol);
185 if (fabs (anU-aUmin) < dU) {
186 bIsLeft=Standard_True;
189 else if (fabs (anU-aUmax) < dU) {
190 bIsLeft=Standard_False;
195 if (anVPeriod > 0.) {
196 if (fabs (anV-aVmin) < dV) {
197 bIsLeft=Standard_True;
200 else if (fabs (anV-aVmax) < dV) {
201 bIsLeft=Standard_False;
206 if (anU1==anU && anV1==anV) {
210 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
212 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
213 Handle(Geom2d_TrimmedCurve) aC1 =
214 new Geom2d_TrimmedCurve(aTmpC1, a, b);
216 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
217 Handle(Geom2d_TrimmedCurve) aC2 =
218 new Geom2d_TrimmedCurve(aTmpC2, a, b);
219 gp_Vec2d aTrV(anU1-anU, anV1-anV);
220 aC2->Translate(aTrV);
224 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
227 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
232 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
235 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
239 //=======================================================================
240 //function : GetNormalToFaceOnEdge
242 //=======================================================================
243 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
244 const TopoDS_Face& aF,
247 Standard_Real aT, aT1, aT2;
249 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
250 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
252 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
254 if (aF.Orientation()==TopAbs_REVERSED){
258 //=======================================================================
259 //function : GetNormalToFaceOnEdge
261 //=======================================================================
262 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
263 const TopoDS_Face& aF1,
264 const Standard_Real aT,
267 Standard_Real U, V, aTolPC;
272 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
274 Handle(Geom2d_Curve)aC2D1;
275 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
281 aS1->D1(U, V, aP, aD1U, aD1V);
287 //=======================================================================
288 //function : SenseFlag
290 //=======================================================================
291 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
294 Standard_Boolean bIsDirsCoinside;
296 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
297 if (!bIsDirsCoinside) {
312 //=======================================================================
313 //function : GetNormalToSurface
315 //=======================================================================
316 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface
317 (const Handle(Geom_Surface)& aS,
318 const Standard_Real U,
319 const Standard_Real V,
322 Standard_Boolean bFlag;
327 aS->D1(U, V, aP, aD1U, aD1V);
332 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
340 //=======================================================================
341 //function : GetApproxNormalToFaceOnEdge
343 //=======================================================================
344 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
345 (const TopoDS_Edge& aE,
346 const TopoDS_Face& aF,
347 const Standard_Real aT,
352 Standard_Real aFirst, aLast;
353 Handle(Geom2d_Curve) aC2D=
354 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
360 PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
361 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
363 BOPTools_AlgoTools3D::GetNormalToSurface
364 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
366 if (aF.Orientation()==TopAbs_REVERSED){
370 //=======================================================================
371 //function : GetApproxNormalToFaceOnEdge
373 //=======================================================================
374 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
375 (const TopoDS_Edge& aE,
376 const TopoDS_Face& aF,
377 const Standard_Real aT,
380 Handle(IntTools_Context)& theContext)
382 Standard_Real aFirst, aLast;
383 Handle(Geom2d_Curve) aC2D=
384 BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
391 BOPTools_AlgoTools3D::PointNearEdge
392 (aE, aF, aT, aPx2DNear, aPNear, theContext);
394 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
396 BOPTools_AlgoTools3D::GetNormalToSurface
397 (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
399 if (aF.Orientation()==TopAbs_REVERSED){
403 //=======================================================================
404 //function : PointNearEdge
406 //=======================================================================
407 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
408 const TopoDS_Face& aF,
409 const Standard_Real aT,
410 const Standard_Real aDt2D,
414 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
415 GeomAbs_SurfaceType aTS;
416 Handle(Geom2d_Curve) aC2D;
417 Handle(Geom_Surface) aS;
419 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
421 aPx2DNear.SetCoord (99., 99);
425 aS=BRep_Tool::Surface(aF);
429 aC2D->D1 (aT, aPx2D, aVx2D);
430 gp_Dir2d aDx2D(aVx2D);
433 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
435 if (aE.Orientation()==TopAbs_REVERSED){
439 if (aF.Orientation()==TopAbs_REVERSED) {
443 aETol = BRep_Tool::Tolerance(aE);
444 aFTol = BRep_Tool::Tolerance(aF);
446 GeomAdaptor_Surface aGAS(aS);
448 if (aTS==GeomAbs_BSplineSurface) {
453 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
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;
461 gp_Cylinder aCyl=aGAS.Cylinder();
464 if (dT>=-1 && dT<=1) {
470 transVec.Multiply(transVal);
471 aPx2DNear = aPx2D.Translated( transVec );
475 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
480 (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
483 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
485 //=======================================================================
486 //function : PointNearEdge
488 //=======================================================================
489 void BOPTools_AlgoTools3D::PointNearEdge
490 (const TopoDS_Edge& aE,
491 const TopoDS_Face& aF,
492 const Standard_Real aT,
495 Handle(IntTools_Context)& theContext)
497 Standard_Real aTolE, aTolF, dTx, dT2D;
498 Handle(Geom_Surface) aS;
499 GeomAdaptor_Surface aGAS;
501 dT2D=10.*BOPTools_AlgoTools3D::MinStepIn2d();//~1.e-5;
503 aS = BRep_Tool::Surface(aF);
505 if (aGAS.GetType()==GeomAbs_Cylinder ||
506 aGAS.GetType()==GeomAbs_Sphere) {
510 aTolE = BRep_Tool::Tolerance(aE);
511 aTolF = BRep_Tool::Tolerance(aF);
512 dTx = 2.*(aTolE + aTolF);
517 BOPTools_AlgoTools3D::PointNearEdge
518 (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
519 if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
520 Standard_Integer iErr;
521 Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
525 BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
535 if (dU < dTresh || dV < dTresh) {
536 iErr = BOPTools_AlgoTools3D::PointInFace
537 (aF, aP, aP2d, theContext);
545 //=======================================================================
546 // function: PointNearEdge
548 //=======================================================================
549 void BOPTools_AlgoTools3D::PointNearEdge
550 (const TopoDS_Edge& aE,
551 const TopoDS_Face& aF,
552 gp_Pnt2d& aPInFace2D,
554 Handle(IntTools_Context)& theContext)
556 Standard_Real aT, aT1, aT2;
559 BRep_Tool::Range(aE, aT1, aT2);
560 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
562 // 2. a Point inside Face near aPOnEdge aPInFace;
565 aFF.Orientation(TopAbs_FORWARD);
566 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
568 BOPTools_AlgoTools3D::PointNearEdge
569 (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
571 //=======================================================================
572 //function : MinStepIn2d
574 //=======================================================================
575 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
577 Standard_Real dt=1.e-5;
580 //=======================================================================
581 //function : IsEmptyShape
583 //=======================================================================
584 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape
585 (const TopoDS_Shape& aS)
587 Standard_Boolean bHasGeometry=Standard_False;
589 BOPCol_IndexedMapOfShape myShapes;
591 Add(aS, myShapes, bHasGeometry);
593 return !bHasGeometry;
595 //=======================================================================
598 //=======================================================================
599 void Add(const TopoDS_Shape& aS,
600 BOPCol_IndexedMapOfShape& myShapes,
601 Standard_Boolean& bHasGeometry)
603 Standard_Integer anIndex;
613 TopoDS_Shape aSx = aS;
615 anIndex=myShapes.FindIndex(aSx);
617 bHasGeometry=HasGeometry (aSx);
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);
635 //=======================================================================
636 //function : HasGeometry
638 //=======================================================================
639 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
641 Standard_Boolean bHasGeometry=Standard_True;
642 TopAbs_ShapeEnum aType= aS.ShapeType();
644 if (aType == TopAbs_VERTEX) {
648 else if (aType == TopAbs_EDGE) {
649 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
650 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
652 while (itrc.More()) {
653 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
654 if (CR->IsCurve3D()) {
655 if (!CR->Curve3D().IsNull()) {
659 else if (CR->IsCurveOnSurface()) {
662 else if (CR->IsRegularity()) {
665 else if (!CR->Polygon3D().IsNull()) {
668 else if (CR->IsPolygonOnTriangulation()) {
671 else if (CR->IsPolygonOnSurface()) {
678 else if (aType == TopAbs_FACE) {
679 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
680 if (!TF->Surface().IsNull()) {
683 Handle(Poly_Triangulation) Tr = TF->Triangulation();
689 return !bHasGeometry;
691 //=======================================================================
692 //function : OrientEdgeOnFace
694 //=======================================================================
695 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
696 const TopoDS_Face& aF,
697 TopoDS_Edge& aERight)
699 if (BRep_Tool::IsClosed(aE, aF)) {
701 aERight.Orientation(aE.Orientation());
703 Standard_Integer iFoundCount = 0;
704 TopoDS_Edge anEdge = aE;
705 TopExp_Explorer anExp(aF, TopAbs_EDGE);
707 for (; anExp.More(); anExp.Next()) {
708 const TopoDS_Shape& aSS=anExp.Current();
710 if (aSS.IsSame(aE)) {
711 anEdge = TopoDS::Edge(aSS);
716 if(iFoundCount == 1) {
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)) {
727 aERight.Orientation(aSS.Orientation());
732 aERight.Orientation(aE.Orientation());
734 //=======================================================================
735 //function : PointInFace
737 //=======================================================================
738 Standard_Integer BOPTools_AlgoTools3D::PointInFace
739 (const TopoDS_Face& aF,
742 Handle(IntTools_Context)& theContext)
744 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
745 Standard_Integer iErr, aIx, aNbDomains;
746 Standard_Real aUMin, aUMax, aVMin, aVMax;
747 Standard_Real aVx = 0., aUx, aV1, aV2;
748 gp_Dir2d aD2D (0., 1.);
751 Handle(Geom2d_Curve) aC2D;
752 Handle(Geom2d_Line) aL2D;
753 Handle(Geom_Surface) aS;
756 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
761 aFF.Orientation (TopAbs_FORWARD);
763 aS=BRep_Tool::Surface(aFF);
764 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
766 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
767 aP2D.SetCoord(aUx, 0.);
768 aL2D=new Geom2d_Line (aP2D, aD2D);
769 Geom2dAdaptor_Curve aHCur(aL2D);
771 aIx=aHatcher.AddHatching(aHCur) ;
774 bIsDone=aHatcher.TrimDone(aIx);
780 aHatcher.ComputeDomains(aIx);
781 bIsDone=aHatcher.IsDone(aIx);
787 aNbDomains=aHatcher.NbDomains(aIx);
788 if (aNbDomains > 0) {
789 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1);
790 bHasFirstPoint=aDomain.HasFirstPoint();
791 if (!bHasFirstPoint) {
796 aV1=aDomain.FirstPoint().Parameter();
798 bHasSecondPoint=aDomain.HasSecondPoint();
799 if (!bHasSecondPoint) {
804 aV2=aDomain.SecondPoint().Parameter();
806 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
814 aS->D0(aUx, aVx, aPx);
816 theP2D.SetCoord(aUx, aVx);