1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 #include <BOPTools_AlgoTools3D.ixx>
22 #include <TopExp_Explorer.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Vertex.hxx>
30 #include <BOPCol_IndexedMapOfShape.hxx>
31 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepTools.hxx>
36 #include <BRepAdaptor_Surface.hxx>
38 #include <gp_Vec2d.hxx>
39 #include <gp_Pnt2d.hxx>
40 #include <gp_Lin2d.hxx>
41 #include <gp_Dir2d.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <Geom2d_TrimmedCurve.hxx>
48 #include <Geom2d_Line.hxx>
50 #include <Geom_Curve.hxx>
51 #include <Geom_Surface.hxx>
52 #include <Geom_BSplineSurface.hxx>
53 #include <Geom_BezierSurface.hxx>
55 #include <GeomAdaptor_Surface.hxx>
57 #include <IntTools_Tools.hxx>
59 #include <BOPTools_AlgoTools2D.hxx>
61 #include <GProp_GProps.hxx>
62 #include <BRepGProp.hxx>
63 #include <BRepBndLib.hxx>
64 #include <Bnd_Box.hxx>
65 #include <gp_Cylinder.hxx>
66 #include <BRep_TVertex.hxx>
67 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
68 #include <BRep_PointRepresentation.hxx>
69 #include <BRep_TEdge.hxx>
70 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
71 #include <BRep_CurveRepresentation.hxx>
72 #include <BRep_TFace.hxx>
73 #include <Poly_Triangulation.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BOPInt_Context.hxx>
76 #include <Geom2dAdaptor_Curve.hxx>
77 #include <Geom2dHatch_Hatcher.hxx>
78 #include <HatchGen_Domain.hxx>
80 static void Add(const TopoDS_Shape& aS,
81 BOPCol_IndexedMapOfShape& myShapes,
82 Standard_Boolean& bHasGeometry);
84 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
86 //=======================================================================
87 //function : DoSplitSEAMOnFace
89 //=======================================================================
90 void BOPTools_AlgoTools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
91 const TopoDS_Face& aF)
93 Standard_Boolean bIsUPeriodic, bIsVPeriodic, bIsLeft = Standard_False;
94 Standard_Real aTol, a, b, anUPeriod, anVPeriod, aT, anU, dU/*=1.e-7*/, anU1,
95 anV, dV/*=1.e-7*/, anV1;
99 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
100 Handle(Geom2d_Curve) C2D1;
101 Handle(Geom2d_Line) aLD1;
102 Handle(Geom_Surface) aS;
107 aSp.Orientation(TopAbs_FORWARD);
108 aTol=BRep_Tool::Tolerance(aSp);
110 aS=BRep_Tool::Surface(aF);
111 bIsUPeriodic=aS->IsUPeriodic();
112 bIsVPeriodic=aS->IsVPeriodic();
114 anUPeriod = bIsUPeriodic ? aS->UPeriod() : 0.;
115 anVPeriod = bIsVPeriodic ? aS->VPeriod() : 0.;
117 if (!bIsUPeriodic && !bIsVPeriodic) {
118 Standard_Boolean bIsUClosed, bIsVClosed;
119 Standard_Real aUmin = 0., aUmax = 0., aVmin = 0., aVmax = 0.;
120 Handle(Geom_BSplineSurface) aBS;
121 Handle(Geom_BezierSurface) aBZ;
123 bIsUClosed=Standard_False;
124 bIsVClosed=Standard_False;
125 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
126 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
129 bIsUClosed=aBS->IsUClosed();
130 bIsVClosed=aBS->IsVClosed();
131 aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
133 else if (!aBZ.IsNull()) {
134 bIsUClosed=aBZ->IsUClosed();
135 bIsVClosed=aBZ->IsVClosed();
136 aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
138 if (!bIsUClosed && !bIsVClosed) {
143 anUPeriod=aUmax-aUmin;
146 anVPeriod=aVmax-aVmin;
150 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
152 aT=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
153 C2D1->D1(aT, aP2D, aVec2D);
154 gp_Dir2d aDir2D1(aVec2D), aDOX(-1.,0.), aDOY(0.,1.);
162 GeomAdaptor_Surface aGAS(aS);
163 dU = aGAS.UResolution(aTol);
164 dV = aGAS.VResolution(aTol);
167 if (fabs (anU) < dU) {
168 bIsLeft=Standard_True;
171 else if (fabs (anU-anUPeriod) < dU) {
172 bIsLeft=Standard_False;
177 if (anVPeriod > 0.) {
178 if (fabs (anV) < dV) {
179 bIsLeft=Standard_True;
182 else if (fabs (anV-anVPeriod) < dV) {
183 bIsLeft=Standard_False;
188 if (anU1==anU && anV1==anV) {
192 aScPr = (anU1==anU) ? aDir2D1*aDOX : aDir2D1*aDOY;
194 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
195 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b);
197 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
198 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b);
199 gp_Vec2d aTrV(anU1-anU, anV1-anV);
200 aC2->Translate(aTrV);
204 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
207 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
212 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
215 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
220 //=======================================================================
221 //function : GetNormalToFaceOnEdge
223 //=======================================================================
224 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
225 const TopoDS_Face& aF,
228 Standard_Real aT, aT1, aT2;
230 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
231 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
233 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
235 if (aF.Orientation()==TopAbs_REVERSED){
240 //=======================================================================
241 //function : GetNormalToFaceOnEdge
243 //=======================================================================
244 void BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
245 const TopoDS_Face& aF1,
246 const Standard_Real aT,
249 Standard_Real U, V, aTolPC;
254 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
256 Handle(Geom2d_Curve)aC2D1;
257 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC);
263 aS1->D1(U, V, aP, aD1U, aD1V);
270 //=======================================================================
271 //function : SenseFlag
273 //=======================================================================
274 Standard_Integer BOPTools_AlgoTools3D::SenseFlag (const gp_Dir& aDNF1,
277 Standard_Boolean bIsDirsCoinside;
278 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
279 if (!bIsDirsCoinside) {
295 //=======================================================================
296 //function : GetNormalToSurface
298 //=======================================================================
299 Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS,
300 const Standard_Real U,
301 const Standard_Real V,
304 Standard_Boolean bFlag;
309 aS->D1(U, V, aP, aD1U, aD1V);
314 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
323 //=======================================================================
324 //function : GetApproxNormalToFaceOnEdge
326 //=======================================================================
328 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(const TopoDS_Edge& aE,
329 const TopoDS_Face& aF,
330 const Standard_Real aT,
335 Standard_Real aFirst, aLast;
336 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
342 PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear);
343 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
345 BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
347 if (aF.Orientation()==TopAbs_REVERSED){
353 //=======================================================================
354 //function : GetApproxNormalToFaceOnEdge
356 //=======================================================================
357 void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
358 const TopoDS_Face& aF,
359 const Standard_Real aT,
362 Handle(BOPInt_Context)& theContext)
364 Standard_Real aFirst, aLast;
365 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
372 BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear, theContext);
374 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
376 BOPTools_AlgoTools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
378 if (aF.Orientation()==TopAbs_REVERSED){
383 //=======================================================================
384 //function : PointNearEdge
386 //=======================================================================
387 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
388 const TopoDS_Face& aF,
389 const Standard_Real aT,
390 const Standard_Real aDt2D,
394 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
395 GeomAbs_SurfaceType aTS;
396 Handle(Geom2d_Curve) aC2D;
397 Handle(Geom_Surface) aS;
399 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
401 aPx2DNear.SetCoord (99., 99);
405 aS=BRep_Tool::Surface(aF);
409 aC2D->D1 (aT, aPx2D, aVx2D);
410 gp_Dir2d aDx2D(aVx2D);
413 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
415 if (aE.Orientation()==TopAbs_REVERSED){
419 if (aF.Orientation()==TopAbs_REVERSED) {
423 aETol = BRep_Tool::Tolerance(aE);
424 aFTol = BRep_Tool::Tolerance(aF);
426 GeomAdaptor_Surface aGAS(aS);
428 if (aTS==GeomAbs_BSplineSurface) {
433 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
434 //if( aETol > 1.e-5 && aFTol > 1.e-5 ) {
436 if(aTS!=GeomAbs_Sphere) {
437 gp_Vec2d transVec( aDP );
438 transVal = aDt2D + aETol + aFTol;
439 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
440 Standard_Real aR, dT;
442 gp_Cylinder aCyl=aGAS.Cylinder();
445 if (dT>=-1 && dT<=1) {
451 transVec.Multiply(transVal);
452 aPx2DNear = aPx2D.Translated( transVec );
455 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
459 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
462 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
465 //=======================================================================
466 //function : PointNearEdge
468 //=======================================================================
469 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
470 const TopoDS_Face& aF,
471 const Standard_Real aT,
474 Handle(BOPInt_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 (aE, aF, aT, dT2D, aPx2DNear, aPxNear);
497 if (!theContext->IsPointInOnFace(aF, aPx2DNear)) {
498 Standard_Integer iErr;
499 Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh;
503 BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
513 if (dU < dTresh || dV < dTresh) {
514 iErr = BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2d, theContext);
523 //=======================================================================
524 // function: PointNearEdge
526 //=======================================================================
527 void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE,
528 const TopoDS_Face& aF,
529 gp_Pnt2d& aPInFace2D,
531 Handle(BOPInt_Context)& theContext)
533 Standard_Real aT, aT1, aT2;
536 BRep_Tool::Range(aE, aT1, aT2);
537 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
539 // 2. a Point inside Face near aPOnEdge aPInFace;
542 aFF.Orientation(TopAbs_FORWARD);
543 BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight);
545 BOPTools_AlgoTools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace, theContext);
548 //=======================================================================
549 //function : MinStepIn2d
551 //=======================================================================
552 Standard_Real BOPTools_AlgoTools3D::MinStepIn2d()
554 Standard_Real dt=1.e-5;
558 //=======================================================================
559 //function : IsEmptyShape
561 //=======================================================================
562 Standard_Boolean BOPTools_AlgoTools3D::IsEmptyShape(const TopoDS_Shape& aS)
564 Standard_Boolean bHasGeometry=Standard_False;
566 BOPCol_IndexedMapOfShape myShapes;
568 Add(aS, myShapes, bHasGeometry);
570 return !bHasGeometry;
573 //=======================================================================
576 //=======================================================================
577 void Add(const TopoDS_Shape& aS,
578 BOPCol_IndexedMapOfShape& myShapes,
579 Standard_Boolean& bHasGeometry)
581 Standard_Integer anIndex;
591 TopoDS_Shape aSx = aS;
593 anIndex=myShapes.FindIndex(aSx);
595 bHasGeometry=HasGeometry (aSx);
600 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
601 for(; anIt.More(); anIt.Next()) {
602 const TopoDS_Shape& aSy=anIt.Value();
603 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) {
625 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(aS.TShape());
626 BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
628 while (itrp.More()) {
629 const Handle(BRep_PointRepresentation)& PR = itrp.Value();
631 if (PR->IsPointOnCurve()) {
635 else if (PR->IsPointOnCurveOnSurface()) {
639 else if (PR->IsPointOnSurface()) {
647 else if (aType == TopAbs_EDGE) {
648 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
649 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
651 while (itrc.More()) {
652 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
653 if (CR->IsCurve3D()) {
654 if (!CR->Curve3D().IsNull()) {
658 else if (CR->IsCurveOnSurface()) {
661 else if (CR->IsRegularity()) {
664 else if (!CR->Polygon3D().IsNull()) {
667 else if (CR->IsPolygonOnTriangulation()) {
670 else if (CR->IsPolygonOnSurface()) {
677 else if (aType == TopAbs_FACE) {
678 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
679 if (!TF->Surface().IsNull()) {
682 Handle(Poly_Triangulation) Tr = TF->Triangulation();
688 return !bHasGeometry;
692 //=======================================================================
693 //function : OrientEdgeOnFace
695 //=======================================================================
696 void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
697 const TopoDS_Face& aF,
698 TopoDS_Edge& aERight)
700 if (BRep_Tool::IsClosed(aE, aF)) {
702 aERight.Orientation(aE.Orientation());
704 Standard_Integer iFoundCount = 0;
705 TopoDS_Edge anEdge = aE;
706 TopExp_Explorer anExp(aF, TopAbs_EDGE);
708 for (; anExp.More(); anExp.Next()) {
709 const TopoDS_Shape& aSS=anExp.Current();
711 if (aSS.IsSame(aE)) {
712 anEdge = TopoDS::Edge(aSS);
717 if(iFoundCount == 1) {
723 TopExp_Explorer anExp(aF, TopAbs_EDGE);
724 for (; anExp.More(); anExp.Next()) {
725 const TopoDS_Shape& aSS=anExp.Current();
726 if (aSS.IsSame(aE)) {
728 aERight.Orientation(aSS.Orientation());
733 aERight.Orientation(aE.Orientation());
736 //=======================================================================
737 //function : PointInFace
739 //=======================================================================
740 Standard_Integer BOPTools_AlgoTools3D::PointInFace(const TopoDS_Face& aF,
743 Handle(BOPInt_Context)& theContext)
745 Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
746 Standard_Integer iErr, aIx, aNbDomains;
747 Standard_Real aUMin, aUMax, aVMin, aVMax;
748 Standard_Real aVx = 0., aUx, aV1, aV2, aEpsT;
749 gp_Dir2d aD2D (0., 1.);
752 Handle(Geom2d_Curve) aC2D;
753 Handle(Geom2d_Line) aL2D;
754 Handle(Geom_Surface) aS;
757 Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF);
763 aFF.Orientation (TopAbs_FORWARD);
765 aS=BRep_Tool::Surface(aFF);
766 BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
768 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
769 aP2D.SetCoord(aUx, 0.);
770 aL2D=new Geom2d_Line (aP2D, aD2D);
771 Geom2dAdaptor_Curve aHCur(aL2D);
773 aIx=aHatcher.AddHatching(aHCur) ;
776 bIsDone=aHatcher.TrimDone(aIx);
782 aHatcher.ComputeDomains(aIx);
783 bIsDone=aHatcher.IsDone(aIx);
789 aNbDomains=aHatcher.NbDomains(aIx);
790 if (aNbDomains > 0) {
791 const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1) ;
792 bHasFirstPoint=aDomain.HasFirstPoint();
793 if (!bHasFirstPoint) {
798 aV1=aDomain.FirstPoint().Parameter();
800 bHasSecondPoint=aDomain.HasSecondPoint();
801 if (!bHasSecondPoint) {
806 aV2=aDomain.SecondPoint().Parameter();
808 aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
816 aS->D0(aUx, aVx, aPx);
818 theP2D.SetCoord(aUx, aVx);