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