86390a2355470474fa8ad77ec683dccc14659cf7
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D_1.cxx
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
45 static
46   Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& ,
47                                       const TopoDS_Edge& ,
48                                       const TopoDS_Face& , 
49                                       const Handle(IntTools_Context)& );
50 static
51   Standard_Boolean IsToReverse(const TopoDS_Edge& ,
52                                const TopoDS_Edge& ,
53                                const Handle(IntTools_Context)& );
54 static
55   Standard_Boolean IsClosed(const TopoDS_Edge& ,
56                             const TopoDS_Face& );
57
58
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 {
69   Standard_Boolean bIsToReverse, bIsClosed;
70   Standard_Integer iRet;
71   Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
72   Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
73   Handle(Geom2d_TrimmedCurve) aC2DT;
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) {
88     Standard_Real aT21r, aT22r;
89     //
90     aC2DoldC->Reverse();
91     //
92     aT21r=aC2DoldC->ReversedParameter(aT21);
93     aT22r=aC2DoldC->ReversedParameter(aT22);
94     aT21=aT22r;
95     aT22=aT21r;
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 //=======================================================================
132 Standard_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 //=======================================================================
249 Standard_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 //=======================================================================
291 Standard_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