1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2015 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_AlgoTools2D.hxx>
16 #include <Precision.hxx>
18 #include <gp_Vec2d.hxx>
19 #include <gp_Dir2d.hxx>
21 #include <TopLoc_Location.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2d_TrimmedCurve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <GeomLib.hxx>
28 #include <GeomAPI_ProjectPointOnCurve.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Face.hxx>
34 #include <BRep_Builder.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRepLib.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <IntTools_Context.hxx>
41 #include <IntTools_Tools.hxx>
43 #include <BOPTools_AlgoTools.hxx>
48 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& ,
51 const Handle(IntTools_Context)& );
53 Standard_Boolean IsClosed(const TopoDS_Edge& ,
56 //=======================================================================
57 //function : AttachExistingPCurve
59 //=======================================================================
60 Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
61 (const TopoDS_Edge& theE2, // old
62 const TopoDS_Edge& theE1, // new
63 const TopoDS_Face& theF,
64 const Handle(IntTools_Context)& aCtx)
66 Standard_Boolean bIsToReverse, bIsClosed, bComp;
67 Standard_Integer iRet;
68 Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
69 Standard_Real aTolSP, aTMax;
70 Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
71 Handle(Geom2d_Curve) aC2DT;
76 TopoDS_Face aF = theF;
77 aF.Orientation (TopAbs_FORWARD);
78 TopoDS_Edge aE1 = theE1;
79 aE1.Orientation (TopAbs_FORWARD);
80 TopoDS_Edge aE2 = theE2;
81 aE2.Orientation (TopAbs_FORWARD);
83 aC2Dold=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
84 if (aC2Dold.IsNull()){
89 aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy());
91 bIsToReverse = BOPTools_AlgoTools::IsSplitToReverse(aE1, aE2, aCtx);
93 Standard_Real aT21r, aT22r;
97 aT21r=aC2DoldC->ReversedParameter(aT21);
98 aT22r=aC2DoldC->ReversedParameter(aT22);
103 aC2DT=new Geom2d_TrimmedCurve(aC2DoldC, aT21, aT22);
105 aTolPPC=Precision::PConfusion();
107 Handle(Geom_Curve) aCE1 = BRep_Tool::Curve(aE1, aT11, aT12);
109 GeomLib::SameRange(aTolPPC, aC2DT, aT21, aT22, aT11, aT12, aC2DT);
116 // check the curves on same parameter to prevent
117 // big tolerance increasing
118 Handle(Geom_Surface) aSF = BRep_Tool::Surface(aF);
120 bComp = IntTools_Tools::ComputeTolerance
121 (aCE1, aC2DT, aSF, aT11, aT12, aTolSP, aTMax, aTolPPC);
127 aTol = BRep_Tool::Tolerance(aE1);
129 if ((aTolSP > 10.*aTol) && aTolSP > 0.1) {
134 // create a temporary edge to make same parameter pcurve
136 aBB.MakeEdge(aE1T, aCE1, aTol);
137 aBB.Range(aE1T, aT11, aT12);
138 aBB.SameRange(aE1T, Standard_False);
139 aBB.SameParameter(aE1T, Standard_False);
141 aBB.UpdateEdge(aE1T, aC2DT, aF, aTol);
143 BRepLib::SameParameter(aE1T);
144 BRepLib::SameRange(aE1T);
146 catch (Standard_Failure const&)
152 bIsClosed = IsClosed(aE2, aF);
154 iRet = UpdateClosedPCurve(aE2, aE1T, aF, aCtx);
160 // transfer pcurve(s) from the temporary edge to the new edge
161 aBB.Transfert(aE1T, aE1);
162 // update tolerance of vertices
163 Standard_Real aNewTol = BRep_Tool::Tolerance(aE1T);
164 TopoDS_Iterator it(aE1);
165 for (; it.More(); it.Next())
166 aBB.UpdateVertex(TopoDS::Vertex(it.Value()), aNewTol);
169 //=======================================================================
170 //function : UpdateClosedPCurve
172 //=======================================================================
173 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold,
174 const TopoDS_Edge& aEnew,
175 const TopoDS_Face& aF,
176 const Handle(IntTools_Context)& aCtx)
178 Standard_Boolean bUClosed, bRevOrder;
179 Standard_Integer aNbPoints, iRet;
180 Standard_Real aTS1, aTS2, aTS, aScPr, aUS1, aVS1, aUS2, aVS2, aT, aU, aV;
181 Standard_Real aT1, aT2, aTol;
182 gp_Pnt2d aP2DS1, aP2DS2, aP2D;
183 gp_Vec2d aV2DT, aV2D, aV2DS1, aV2DS2;
185 Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2, aC2Dnew, aC2DoldCT;
186 Handle(Geom2d_Curve) aC2Dold;
187 Handle(Geom2d_TrimmedCurve) aC2DTnew;
188 Handle(Geom_Surface) aS;
193 aTol=BRep_Tool::Tolerance(aEnew);
195 // aC2DoldCT is alone p-curve of aEnew that we've built
196 // The task is to build closed p-curves for aEnew
197 aC2DoldCT=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
199 // aC2Dold is p-curve of aEold
200 aC2Dold=BRep_Tool::CurveOnSurface(aEold, aF, aT1, aT2);
202 // As aEold is closed on aF, it is possible to retrieve
204 // aC2DS1 -first p-curve
205 // aC2DS2 -second p-curve
207 aES.Orientation(TopAbs_FORWARD);
208 aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
210 aES.Orientation(TopAbs_REVERSED);
211 aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
213 aTS=BOPTools_AlgoTools2D::IntermediatePoint(aTS1, aTS2);
215 aC2DS1->D1(aTS, aP2DS1, aV2DS1);
216 aC2DS2->D1(aTS, aP2DS2, aV2DS2);
218 // aV2DS12 - translation vector
219 gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
220 gp_Dir2d aD2DS12(aV2DS12);
221 const gp_Dir2d& aD2DX=gp::DX2d();
223 // Directoion of closeness: U-Closed or V-Closed
225 bUClosed=Standard_True;
226 if (fabs(aScPr) < aTol) {
230 aP2DS1.Coord(aUS1, aVS1);
231 aP2DS2.Coord(aUS2, aVS2);
233 // aP - some 3D-point on seam edge of the surface aS
234 aS=BRep_Tool::Surface(aF);
235 aS->D0(aUS1, aVS1, aP);
237 GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
240 aNbPoints=aProjPC.NbPoints();
246 // aT - parameter for aP on the curves of aEnew
247 aT=aProjPC.LowerDistanceParameter();
250 aC2D->D1(aT, aP2D, aV2D);
253 aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
254 aC2DTnew=new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
257 if (!bUClosed) { // V Closed
258 if (fabs(aV-aVS2)<aTol) {
263 if (fabs(aU-aUS2)<aTol) {
268 // Translate aC2DTnew
269 aC2DTnew->Translate(aV2DT);
271 // 4 Order the 2D curves
272 bRevOrder=Standard_False;
275 bRevOrder=!bRevOrder;
279 aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
282 aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
286 //=======================================================================
287 //function : IsClosed
289 //=======================================================================
290 Standard_Boolean IsClosed(const TopoDS_Edge& aE,
291 const TopoDS_Face& aF)
293 Standard_Boolean bRet;
295 bRet=BRep_Tool::IsClosed(aE, aF);
297 Standard_Integer iCnt;
300 TopExp_Explorer aExp(aF, TopAbs_EDGE);
301 for (; (aExp.More() || iCnt==2); aExp.Next()) {
302 const TopoDS_Shape& aEx=aExp.Current();