0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D_1.cxx
CommitLineData
905522ee 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2015 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
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.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#include <BOPTools_AlgoTools2D.hxx>
16#include <Precision.hxx>
17
18#include <gp_Vec2d.hxx>
19#include <gp_Dir2d.hxx>
20
21#include <TopLoc_Location.hxx>
22
23#include <Geom2d_Curve.hxx>
24#include <Geom2d_TrimmedCurve.hxx>
25#include <Geom_Surface.hxx>
26#include <GeomLib.hxx>
27
28#include <GeomAPI_ProjectPointOnCurve.hxx>
29
30#include <TopoDS_Edge.hxx>
31#include <TopoDS_Face.hxx>
32
33#include <BRep_Builder.hxx>
34#include <BRep_Tool.hxx>
35#include <BRepLib.hxx>
36
37#include <TopExp_Explorer.hxx>
38
39#include <IntTools_Context.hxx>
40
41#include <BOPTools_AlgoTools2D.hxx>
42
43
44
45static
46 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& ,
47 const TopoDS_Edge& ,
48 const TopoDS_Face& ,
49 const Handle(IntTools_Context)& );
50static
51 Standard_Boolean IsToReverse(const TopoDS_Edge& ,
52 const TopoDS_Edge& ,
53 const Handle(IntTools_Context)& );
54static
55 Standard_Boolean IsClosed(const TopoDS_Edge& ,
56 const TopoDS_Face& );
57
58
59//=======================================================================
60//function : AttachExistingPCurve
61//purpose :
62//=======================================================================
63Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
64 (const TopoDS_Edge& aE2, // old
65 const TopoDS_Edge& aE1, // new
66 const TopoDS_Face& aF,
67 const Handle(IntTools_Context)& aCtx)
68{
69 Standard_Boolean bIsToReverse, bIsClosed;
70 Standard_Integer iRet;
71 Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
72 Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
543a9964 73 Handle(Geom2d_Curve) aC2DT;
905522ee 74 BRep_Builder aBB;
75 //
76 iRet=0;
77 //
78 aC2Dold=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
79 if (aC2Dold.IsNull()){
80 iRet=1;
81 return iRet;
82 }
83 //
84 aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy());
85 //
86 bIsToReverse=IsToReverse(aE2, aE1, aCtx);
87 if (bIsToReverse) {
b6ec1ef9 88 Standard_Real aT21r, aT22r;
905522ee 89 //
b6ec1ef9 90 aC2DoldC->Reverse();
905522ee 91 //
b6ec1ef9 92 aT21r=aC2DoldC->ReversedParameter(aT21);
93 aT22r=aC2DoldC->ReversedParameter(aT22);
94 aT21=aT22r;
95 aT22=aT21r;
905522ee 96 }
97 //
98 aC2DT=new Geom2d_TrimmedCurve(aC2DoldC, aT21, aT22);
99 //
100 aTol=BRep_Tool::Tolerance(aE1);
101 BRep_Tool::Range (aE1, aT11, aT12);
102 aBB.SameRange(aE1, Standard_False);
103 aBB.SameParameter(aE1, Standard_False);
104
105 aTolPPC=Precision::PConfusion();
106 //
107 GeomLib::SameRange(aTolPPC, aC2DT, aT21, aT22, aT11, aT12, aC2DT);
108 //
109 if (aC2DT.IsNull()){
110 iRet=2;
111 return iRet;
112 }
113 //
114 aBB.UpdateEdge(aE1, aC2DT, aF, aTol);
115 BRepLib::SameParameter(aE1);
116 BRepLib::SameRange(aE1);
117 //
118 bIsClosed=IsClosed(aE2, aF);
119 if (bIsClosed) {
120 iRet=UpdateClosedPCurve(aE2, aE1, aF, aCtx);
121 if(iRet) {
122 iRet=3;
123 }
124 }
125 //
126 return iRet;
127}
128//=======================================================================
129//function : UpdateClosedPCurve
130//purpose :
131//=======================================================================
132Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold,
133 const TopoDS_Edge& aEnew,
134 const TopoDS_Face& aF,
135 const Handle(IntTools_Context)& aCtx)
136{
137 Standard_Boolean bUClosed, bRevOrder;
138 Standard_Integer aNbPoints, iRet;
139 Standard_Real aTS1, aTS2, aTS, aScPr, aUS1, aVS1, aUS2, aVS2, aT, aU, aV;
140 Standard_Real aT1, aT2, aTol;
141 gp_Pnt2d aP2DS1, aP2DS2, aP2D;
142 gp_Vec2d aV2DT, aV2D, aV2DS1, aV2DS2;
143 gp_Pnt aP;
144 Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2, aC2Dnew, aC2DoldCT;
145 Handle(Geom2d_Curve) aC2Dold;
146 Handle(Geom2d_TrimmedCurve) aC2DTnew;
147 Handle(Geom_Surface) aS;
148 TopoDS_Edge aES;
149 BRep_Builder aBB;
150 //
151 iRet=0;
152 aTol=BRep_Tool::Tolerance(aEnew);
153 //
154 // aC2DoldCT is alone p-curve of aEnew that we've built
155 // The task is to build closed p-curves for aEnew
156 aC2DoldCT=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
157 //
158 // aC2Dold is p-curve of aEold
159 aC2Dold=BRep_Tool::CurveOnSurface(aEold, aF, aT1, aT2);
160 //
161 // As aEold is closed on aF, it is possible to retrieve
162 // the two p-curves:
163 // aC2DS1 -first p-curve
164 // aC2DS2 -second p-curve
165 aES=aEold;
166 aES.Orientation(TopAbs_FORWARD);
167 aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
168 //
169 aES.Orientation(TopAbs_REVERSED);
170 aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
171 //
172 aTS=BOPTools_AlgoTools2D::IntermediatePoint(aTS1, aTS2);
173 //
174 aC2DS1->D1(aTS, aP2DS1, aV2DS1);
175 aC2DS2->D1(aTS, aP2DS2, aV2DS2);
176 //
177 // aV2DS12 - translation vector
178 gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
179 gp_Dir2d aD2DS12(aV2DS12);
180 const gp_Dir2d& aD2DX=gp::DX2d();
181 //
182 // Directoion of closeness: U-Closed or V-Closed
183 aScPr=aD2DS12*aD2DX;
184 bUClosed=Standard_True;
185 if (fabs(aScPr) < aTol) {
186 bUClosed=!bUClosed;
187 }
188 //
189 aP2DS1.Coord(aUS1, aVS1);
190 aP2DS2.Coord(aUS2, aVS2);
191 //
192 // aP - some 3D-point on seam edge of the surface aS
193 aS=BRep_Tool::Surface(aF);
194 aS->D0(aUS1, aVS1, aP);
195 //
196 GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
197 //
198 aProjPC.Perform(aP);
199 aNbPoints=aProjPC.NbPoints();
200 if (!aNbPoints) {
201 iRet=1;
202 return iRet;
203 }
204 //
205 // aT - parameter for aP on the curves of aEnew
206 aT=aProjPC.LowerDistanceParameter();
207 //
208 aC2D=aC2DoldCT;
209 aC2D->D1(aT, aP2D, aV2D);
210 aP2D.Coord(aU, aV);
211 //
212 aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
213 aC2DTnew=new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
214 //
215 aV2DT=aV2DS12;
216 if (!bUClosed) { // V Closed
217 if (fabs(aV-aVS2)<aTol) {
218 aV2DT.Reverse();
219 }
220 }
221 else { // U Closed
222 if (fabs(aU-aUS2)<aTol) {
223 aV2DT.Reverse();
224 }
225 }
226 //
227 // Translate aC2DTnew
228 aC2DTnew->Translate(aV2DT);
229 //
230 // 4 Order the 2D curves
231 bRevOrder=Standard_False;
232 aScPr=aV2D*aV2DS1;
233 if(aScPr<0.) {
234 bRevOrder=!bRevOrder;
235 }
236 //
237 if (!bRevOrder) {
238 aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
239 }
240 else {
241 aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
242 }
243 return iRet;
244}
245//=======================================================================
246//function : IsToReverse
247//purpose :
248//=======================================================================
249Standard_Boolean IsToReverse(const TopoDS_Edge& aEold,
250 const TopoDS_Edge& aEnew,
251 const Handle(IntTools_Context)& aCtx)
252{
253 Standard_Boolean bRet, bFlag, bIsDegenerated;
254 Standard_Real aTnew, aTold, aScPr, aTa, aTb, aT1, aT2;
255 gp_Vec aVold, aVnew, aVE, aVS;
256 gp_Pnt aP;
257 Handle(Geom_Curve) aCold, aCnew;
258 //
259 bRet=Standard_False;
260 //
261 bIsDegenerated=(BRep_Tool::Degenerated(aEold) ||
262 BRep_Tool::Degenerated(aEnew));
263 if (bIsDegenerated) {
264 return bRet;
265 }
266 //
267 aCold=BRep_Tool::Curve(aEold, aT1, aT2);
268 aCnew=BRep_Tool::Curve(aEnew, aTa, aTb);
269 //
270 if (aCold==aCnew) {
271 return bRet;
272 }
273 //
274 aTnew=BOPTools_AlgoTools2D::IntermediatePoint(aTa, aTb);
275 aCnew->D1(aTnew, aP, aVnew);
276 aVnew.Normalize();
277 //
278 bFlag=aCtx->ProjectPointOnEdge(aP, aEold, aTold);
279 aCold->D1(aTold, aP, aVold);
280 aVold.Normalize();
281 //
282 aScPr=aVnew*aVold;
283 bRet=(aScPr<0.);
284 //
285 return bRet;
286}
287//=======================================================================
288//function : IsClosed
289//purpose :
290//=======================================================================
291Standard_Boolean IsClosed(const TopoDS_Edge& aE,
292 const TopoDS_Face& aF)
293{
294 Standard_Boolean bRet;
295 //
296 bRet=BRep_Tool::IsClosed(aE, aF);
297 if (bRet) {
298 Standard_Integer iCnt;
299 //
300 iCnt=0;
301 TopExp_Explorer aExp(aF, TopAbs_EDGE);
302 for (; (aExp.More() || iCnt==2); aExp.Next()) {
303 const TopoDS_Shape& aEx=aExp.Current();
304 if(aEx.IsSame(aE)) {
305 ++iCnt;
306 }
307 }
308 bRet=(iCnt==2);
309 }
310 return bRet;
311}
312