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