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_AlgoTools2D.hxx>
48 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& ,
51 const Handle(IntTools_Context)& );
53 Standard_Boolean IsToReverse(const TopoDS_Edge& ,
55 const Handle(IntTools_Context)& );
57 Standard_Boolean IsClosed(const TopoDS_Edge& ,
60 //=======================================================================
61 //function : AttachExistingPCurve
63 //=======================================================================
64 Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
65 (const TopoDS_Edge& aE2, // old
66 const TopoDS_Edge& aE1, // new
67 const TopoDS_Face& aF,
68 const Handle(IntTools_Context)& aCtx)
70 Standard_Boolean bIsToReverse, bIsClosed, bComp;
71 Standard_Integer iRet;
72 Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
73 Standard_Real aTolSP, aTMax;
74 Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
75 Handle(Geom2d_Curve) aC2DT;
80 aC2Dold=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
81 if (aC2Dold.IsNull()){
86 aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy());
88 bIsToReverse=IsToReverse(aE2, aE1, aCtx);
90 Standard_Real aT21r, aT22r;
94 aT21r=aC2DoldC->ReversedParameter(aT21);
95 aT22r=aC2DoldC->ReversedParameter(aT22);
100 aC2DT=new Geom2d_TrimmedCurve(aC2DoldC, aT21, aT22);
102 aTolPPC=Precision::PConfusion();
104 Handle(Geom_Curve) aCE1 = BRep_Tool::Curve(aE1, aT11, aT12);
106 GeomLib::SameRange(aTolPPC, aC2DT, aT21, aT22, aT11, aT12, aC2DT);
113 // check the curves on same parameter to prevent
114 // big tolerance increasing
115 Handle(Geom_Surface) aSF = BRep_Tool::Surface(aF);
117 bComp = IntTools_Tools::ComputeTolerance
118 (aCE1, aC2DT, aSF, aT11, aT12, aTolSP, aTMax, aTolPPC);
124 aTol = BRep_Tool::Tolerance(aE1);
126 if ((aTolSP > 10.*aTol) && aTolSP > 0.1) {
131 // create a temporary edge to make same parameter pcurve
133 aBB.MakeEdge(aE1T, aCE1, aTol);
134 aBB.Range(aE1T, aT11, aT12);
135 aBB.SameRange(aE1T, Standard_False);
136 aBB.SameParameter(aE1T, Standard_False);
138 aBB.UpdateEdge(aE1T, aC2DT, aF, aTol);
140 BRepLib::SameParameter(aE1T);
141 BRepLib::SameRange(aE1T);
143 catch (Standard_Failure)
149 bIsClosed = IsClosed(aE2, aF);
151 iRet = UpdateClosedPCurve(aE2, aE1T, aF, aCtx);
157 // transfer pcurve(s) from the temporary edge to the new edge
158 aBB.Transfert(aE1T, aE1);
159 // update tolerance of vertices
160 Standard_Real aNewTol = BRep_Tool::Tolerance(aE1T);
161 TopoDS_Iterator it(aE1);
162 for (; it.More(); it.Next())
163 aBB.UpdateVertex(TopoDS::Vertex(it.Value()), aNewTol);
166 //=======================================================================
167 //function : UpdateClosedPCurve
169 //=======================================================================
170 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold,
171 const TopoDS_Edge& aEnew,
172 const TopoDS_Face& aF,
173 const Handle(IntTools_Context)& aCtx)
175 Standard_Boolean bUClosed, bRevOrder;
176 Standard_Integer aNbPoints, iRet;
177 Standard_Real aTS1, aTS2, aTS, aScPr, aUS1, aVS1, aUS2, aVS2, aT, aU, aV;
178 Standard_Real aT1, aT2, aTol;
179 gp_Pnt2d aP2DS1, aP2DS2, aP2D;
180 gp_Vec2d aV2DT, aV2D, aV2DS1, aV2DS2;
182 Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2, aC2Dnew, aC2DoldCT;
183 Handle(Geom2d_Curve) aC2Dold;
184 Handle(Geom2d_TrimmedCurve) aC2DTnew;
185 Handle(Geom_Surface) aS;
190 aTol=BRep_Tool::Tolerance(aEnew);
192 // aC2DoldCT is alone p-curve of aEnew that we've built
193 // The task is to build closed p-curves for aEnew
194 aC2DoldCT=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
196 // aC2Dold is p-curve of aEold
197 aC2Dold=BRep_Tool::CurveOnSurface(aEold, aF, aT1, aT2);
199 // As aEold is closed on aF, it is possible to retrieve
201 // aC2DS1 -first p-curve
202 // aC2DS2 -second p-curve
204 aES.Orientation(TopAbs_FORWARD);
205 aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
207 aES.Orientation(TopAbs_REVERSED);
208 aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
210 aTS=BOPTools_AlgoTools2D::IntermediatePoint(aTS1, aTS2);
212 aC2DS1->D1(aTS, aP2DS1, aV2DS1);
213 aC2DS2->D1(aTS, aP2DS2, aV2DS2);
215 // aV2DS12 - translation vector
216 gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
217 gp_Dir2d aD2DS12(aV2DS12);
218 const gp_Dir2d& aD2DX=gp::DX2d();
220 // Directoion of closeness: U-Closed or V-Closed
222 bUClosed=Standard_True;
223 if (fabs(aScPr) < aTol) {
227 aP2DS1.Coord(aUS1, aVS1);
228 aP2DS2.Coord(aUS2, aVS2);
230 // aP - some 3D-point on seam edge of the surface aS
231 aS=BRep_Tool::Surface(aF);
232 aS->D0(aUS1, aVS1, aP);
234 GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
237 aNbPoints=aProjPC.NbPoints();
243 // aT - parameter for aP on the curves of aEnew
244 aT=aProjPC.LowerDistanceParameter();
247 aC2D->D1(aT, aP2D, aV2D);
250 aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
251 aC2DTnew=new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
254 if (!bUClosed) { // V Closed
255 if (fabs(aV-aVS2)<aTol) {
260 if (fabs(aU-aUS2)<aTol) {
265 // Translate aC2DTnew
266 aC2DTnew->Translate(aV2DT);
268 // 4 Order the 2D curves
269 bRevOrder=Standard_False;
272 bRevOrder=!bRevOrder;
276 aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
279 aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
283 //=======================================================================
284 //function : IsToReverse
286 //=======================================================================
287 Standard_Boolean IsToReverse(const TopoDS_Edge& aEold,
288 const TopoDS_Edge& aEnew,
289 const Handle(IntTools_Context)& aCtx)
291 Standard_Boolean bRet, bIsDegenerated;
292 Standard_Real aTnew, aTold, aScPr, aTa, aTb, aT1, aT2;
293 gp_Vec aVold, aVnew, aVE, aVS;
295 Handle(Geom_Curve) aCold, aCnew;
299 bIsDegenerated=(BRep_Tool::Degenerated(aEold) ||
300 BRep_Tool::Degenerated(aEnew));
301 if (bIsDegenerated) {
305 aCold=BRep_Tool::Curve(aEold, aT1, aT2);
306 aCnew=BRep_Tool::Curve(aEnew, aTa, aTb);
312 aTnew=BOPTools_AlgoTools2D::IntermediatePoint(aTa, aTb);
313 aCnew->D1(aTnew, aP, aVnew);
316 if (!aCtx->ProjectPointOnEdge(aP, aEold, aTold))
317 return Standard_False;
318 aCold->D1(aTold, aP, aVold);
326 //=======================================================================
327 //function : IsClosed
329 //=======================================================================
330 Standard_Boolean IsClosed(const TopoDS_Edge& aE,
331 const TopoDS_Face& aF)
333 Standard_Boolean bRet;
335 bRet=BRep_Tool::IsClosed(aE, aF);
337 Standard_Integer iCnt;
340 TopExp_Explorer aExp(aF, TopAbs_EDGE);
341 for (; (aExp.More() || iCnt==2); aExp.Next()) {
342 const TopoDS_Shape& aEx=aExp.Current();