0026788: Compiler warnings when OCCT_DEBUG is enabled
[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 #include <IntTools_Tools.hxx>
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
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, bComp;
70   Standard_Integer iRet;
71   Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
72   Standard_Real aTolSP, aTMax;
73   Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
74   Handle(Geom2d_Curve) aC2DT;
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) {
89     Standard_Real aT21r, aT22r;
90     //
91     aC2DoldC->Reverse();
92     //
93     aT21r=aC2DoldC->ReversedParameter(aT21);
94     aT22r=aC2DoldC->ReversedParameter(aT22);
95     aT21=aT22r;
96     aT22=aT21r;
97   }
98   //
99   aC2DT=new Geom2d_TrimmedCurve(aC2DoldC, aT21, aT22);
100   //
101   aTolPPC=Precision::PConfusion();
102   //
103   Handle(Geom_Curve) aCE1 = BRep_Tool::Curve(aE1, aT11, aT12);
104   //
105   GeomLib::SameRange(aTolPPC, aC2DT, aT21, aT22, aT11, aT12, aC2DT);
106   //
107   if (aC2DT.IsNull()){
108     iRet=2;
109     return iRet;
110   }
111   //
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   //
133   aBB.UpdateEdge(aE1, aC2DT, aF, aTol);
134   BRepLib::SameParameter(aE1);
135   BRepLib::SameRange(aE1);
136   //
137   bIsClosed = IsClosed(aE2, aF);
138   if (bIsClosed) {
139     iRet = UpdateClosedPCurve(aE2, aE1, aF, aCtx);
140     if(iRet) {
141       iRet = 5;
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 {
272   Standard_Boolean bRet, bIsDegenerated;
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   //
297   if (!aCtx->ProjectPointOnEdge(aP, aEold, aTold))
298     return Standard_False;
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 }