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