0030760: Modeling Algorithms - Intersection fails in Occt 7.3.0
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D_1.cxx
CommitLineData
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
4e66868a 30#include <TopoDS.hxx>
905522ee 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>
521e1c61 41#include <IntTools_Tools.hxx>
905522ee 42
80d55adf 43#include <BOPTools_AlgoTools.hxx>
905522ee 44
45
46
47static
48 Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& ,
49 const TopoDS_Edge& ,
50 const TopoDS_Face& ,
51 const Handle(IntTools_Context)& );
905522ee 52static
53 Standard_Boolean IsClosed(const TopoDS_Edge& ,
54 const TopoDS_Face& );
55
905522ee 56//=======================================================================
57//function : AttachExistingPCurve
58//purpose :
59//=======================================================================
60Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
78005ffe 61 (const TopoDS_Edge& theE2, // old
62 const TopoDS_Edge& theE1, // new
63 const TopoDS_Face& theF,
905522ee 64 const Handle(IntTools_Context)& aCtx)
65{
521e1c61 66 Standard_Boolean bIsToReverse, bIsClosed, bComp;
905522ee 67 Standard_Integer iRet;
68 Standard_Real aTol, aT11, aT12, aT21, aT22, aTolPPC;
521e1c61 69 Standard_Real aTolSP, aTMax;
905522ee 70 Handle(Geom2d_Curve) aC2Dold, aC2DoldC;
543a9964 71 Handle(Geom2d_Curve) aC2DT;
905522ee 72 BRep_Builder aBB;
73 //
74 iRet=0;
75 //
78005ffe 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 //
905522ee 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 //
80d55adf 91 bIsToReverse = BOPTools_AlgoTools::IsSplitToReverse(aE1, aE2, aCtx);
905522ee 92 if (bIsToReverse) {
b6ec1ef9 93 Standard_Real aT21r, aT22r;
905522ee 94 //
b6ec1ef9 95 aC2DoldC->Reverse();
905522ee 96 //
b6ec1ef9 97 aT21r=aC2DoldC->ReversedParameter(aT21);
98 aT22r=aC2DoldC->ReversedParameter(aT22);
99 aT21=aT22r;
100 aT22=aT21r;
905522ee 101 }
102 //
103 aC2DT=new Geom2d_TrimmedCurve(aC2DoldC, aT21, aT22);
104 //
905522ee 105 aTolPPC=Precision::PConfusion();
106 //
521e1c61 107 Handle(Geom_Curve) aCE1 = BRep_Tool::Curve(aE1, aT11, aT12);
108 //
905522ee 109 GeomLib::SameRange(aTolPPC, aC2DT, aT21, aT22, aT11, aT12, aC2DT);
110 //
111 if (aC2DT.IsNull()){
112 iRet=2;
113 return iRet;
114 }
115 //
521e1c61 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
6ca1c746 121 (aCE1, aC2DT, aSF, aT11, aT12, aTolSP, aTMax, aTolPPC);
521e1c61 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 //
4e66868a 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 }
a738b534 146 catch (Standard_Failure const&)
4e66868a 147 {
148 iRet = 6;
149 return iRet;
150 }
905522ee 151 //
521e1c61 152 bIsClosed = IsClosed(aE2, aF);
905522ee 153 if (bIsClosed) {
4e66868a 154 iRet = UpdateClosedPCurve(aE2, aE1T, aF, aCtx);
905522ee 155 if(iRet) {
521e1c61 156 iRet = 5;
4e66868a 157 return iRet;
905522ee 158 }
159 }
4e66868a 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);
905522ee 167 return iRet;
168}
169//=======================================================================
170//function : UpdateClosedPCurve
171//purpose :
172//=======================================================================
173Standard_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//=======================================================================
905522ee 287//function : IsClosed
288//purpose :
289//=======================================================================
290Standard_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}