0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / LocOpe / LocOpe_FindEdges.cxx
CommitLineData
b311480e 1// Created on: 1996-02-15
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <LocOpe_FindEdges.ixx>
18
19#include <BRep_Tool.hxx>
20#include <TopExp_Explorer.hxx>
21
22#include <Geom_Curve.hxx>
23#include <Geom_TrimmedCurve.hxx>
24#include <Geom_Line.hxx>
25#include <Geom_Circle.hxx>
26#include <Geom_Ellipse.hxx>
27#include <Geom_BSplineCurve.hxx>
28#include <Geom_BezierCurve.hxx>
29#include <TColgp_Array1OfPnt.hxx>
30#include <TColStd_Array1OfReal.hxx>
31#include <TColStd_Array1OfInteger.hxx>
32
33
34#include <ElCLib.hxx>
35#include <Precision.hxx>
36
37
38
39//=======================================================================
40//function : Set
41//purpose :
42//=======================================================================
43
44void LocOpe_FindEdges::Set(const TopoDS_Shape& FFrom,
45 const TopoDS_Shape& FTo)
46{
47 myFFrom = FFrom;
48 myFTo = FTo;
49 myLFrom.Clear();
50 myLTo.Clear();
51
52
53 TopExp_Explorer expf,expt;
54 Handle(Geom_Curve) Cf,Ct;
55 TopLoc_Location Loc;
56 Standard_Real ff,lf,ft,lt;
57 Handle(Standard_Type) Tf,Tt;
58
59 for (expf.Init(myFFrom,TopAbs_EDGE); expf.More(); expf.Next()) {
60 const TopoDS_Edge& edgf = TopoDS::Edge(expf.Current());
61 Cf = BRep_Tool::Curve(edgf,Loc,ff,lf);
62 if (!Loc.IsIdentity()) {
63 Handle(Geom_Geometry) GGf = Cf->Transformed(Loc.Transformation());
c5f3a425 64 Cf = Handle(Geom_Curve)::DownCast (GGf);
7fd59977 65 }
66 Tf = Cf->DynamicType();
67 if (Tf == STANDARD_TYPE(Geom_TrimmedCurve)) {
c5f3a425 68 Cf = Handle(Geom_TrimmedCurve)::DownCast (Cf)->BasisCurve();
7fd59977 69 Tf = Cf->DynamicType();
70 }
71 if (Tf != STANDARD_TYPE(Geom_Line) && Tf != STANDARD_TYPE(Geom_Circle) &&
72 Tf != STANDARD_TYPE(Geom_Ellipse) && Tf != STANDARD_TYPE(Geom_BSplineCurve)
73 && Tf != STANDARD_TYPE(Geom_BezierCurve)) {
74 continue;
75 }
76 for (expt.Init(myFTo,TopAbs_EDGE); expt.More(); expt.Next()) {
77 const TopoDS_Edge& edgt = TopoDS::Edge(expt.Current());
78 Ct = BRep_Tool::Curve(edgt,Loc,ft,lt);
79 if (!Loc.IsIdentity()) {
80 Handle(Geom_Geometry) GGt = Ct->Transformed(Loc.Transformation());
c5f3a425 81 Ct = Handle(Geom_Curve)::DownCast (GGt);
7fd59977 82 }
83 Tt = Ct->DynamicType();
84 if (Tt == STANDARD_TYPE(Geom_TrimmedCurve)) {
c5f3a425 85 Ct = Handle(Geom_TrimmedCurve)::DownCast (Ct)->BasisCurve();
7fd59977 86 Tt = Ct->DynamicType();
87 }
88 if (Tt != Tf) {
89 continue;
90 }
91 // On a presomption de confusion
92 Standard_Real Tol = Precision::Confusion();
93 if (Tt == STANDARD_TYPE(Geom_Line)) {
c5f3a425 94 gp_Lin lif = Handle(Geom_Line)::DownCast (Cf)->Lin();
95 gp_Lin lit = Handle(Geom_Line)::DownCast (Ct)->Lin();
7fd59977 96 gp_Pnt p1 = ElCLib::Value(ff,lif);
97 gp_Pnt p2 = ElCLib::Value(lf,lif);
98 Standard_Real prm1 = ElCLib::Parameter(lit,p1);
99 Standard_Real prm2 = ElCLib::Parameter(lit,p2);
100 if (prm1 >= ft-Tol && prm1 <= lt+Tol &&
101 prm2 >= ft-Tol && prm2 <= lt+Tol) {
102 Tol *= Tol;
103 gp_Pnt pt = ElCLib::Value(prm1,lit);
104 if (pt.SquareDistance(p1) <= Tol) {
105 pt = ElCLib::Value(prm2,lit);
106 if (pt.SquareDistance(p2) <= Tol) {
107 myLFrom.Append(edgf);
108 myLTo.Append(edgt);
109 break;
110 }
111 }
112 }
113 }
114 else if (Tt == STANDARD_TYPE(Geom_Circle)) {
c5f3a425 115 gp_Circ cif = Handle(Geom_Circle)::DownCast (Cf)->Circ();
116 gp_Circ cit = Handle(Geom_Circle)::DownCast (Ct)->Circ();
7fd59977 117 if (Abs(cif.Radius()-cit.Radius()) <= Tol &&
118 cif.Location().SquareDistance(cit.Location()) <= Tol*Tol) {
119 // Point debut, calage dans periode, et detection meme sens
120
121 gp_Pnt p1,p2;
122 gp_Vec tgf,tgt;
123 ElCLib::D1(ff,cif,p1,tgf);
124 p2 = ElCLib::Value(lf,cif);
125
126 Standard_Real prm1 = ElCLib::Parameter(cit,p1);
127 Standard_Real Tol2d = Precision::PConfusion();
128 if (Abs(prm1-ft) <= Tol2d) prm1 = ft;
c6541a0c 129 prm1 = ElCLib::InPeriod(prm1,ft,ft+2.*M_PI);
7fd59977 130 ElCLib::D1(prm1,cit,p1,tgt);
131
132 Standard_Real prm2 = ElCLib::Parameter(cit,p2);
133 if (tgt.Dot(tgf) > 0.) { // meme sens
134 while (prm2 <= prm1) {
c6541a0c 135 prm2 += 2.*M_PI;
7fd59977 136 }
137 }
138 else {
139 if (Abs(prm1-ft) <= Precision::Angular()) {
c6541a0c 140 prm1 += 2.*M_PI;
7fd59977 141 }
142 while (prm2 >= prm1) {
c6541a0c 143 prm2 -= 2.*M_PI;
7fd59977 144 }
145 }
146
147 if (prm1 >= ft-Tol && prm1 <= lt+Tol &&
148 prm2 >= ft-Tol && prm2 <= lt+Tol) {
149 myLFrom.Append(edgf);
150 myLTo.Append(edgt);
151 break;
152 }
153 else {
154 // Cas non traite : on est a cheval
0797d9d3 155#ifdef OCCT_DEBUG
7fd59977 156 cout <<" cas a cheval."<< endl;
157#endif
158
159// myLFrom.Append(edgf);
160// myLTo.Append(edgt);
161// break;
162 }
163 }
164 }
165 else if (Tt == STANDARD_TYPE(Geom_Ellipse)) {
c5f3a425 166 gp_Elips cif = Handle(Geom_Ellipse)::DownCast (Cf)->Elips();
167 gp_Elips cit = Handle(Geom_Ellipse)::DownCast (Ct)->Elips();
7fd59977 168
169
170 if (Abs(cif.MajorRadius()-cit.MajorRadius()) <= Tol &&
171 Abs(cif.MinorRadius()-cit.MinorRadius()) <= Tol &&
172 cif.Location().SquareDistance(cit.Location()) <= Tol*Tol) {
173 // Point debut, calage dans periode, et detection meme sens
174
175 gp_Pnt p1,p2;
176 gp_Vec tgf,tgt;
177 ElCLib::D1(ff,cif,p1,tgf);
178 p2 = ElCLib::Value(lf,cif);
179
180 Standard_Real prm1 = ElCLib::Parameter(cit,p1);
c6541a0c 181 prm1 = ElCLib::InPeriod(prm1,ft,ft+2.*M_PI);
7fd59977 182 ElCLib::D1(prm1,cit,p1,tgt);
183
184 Standard_Real prm2 = ElCLib::Parameter(cit,p2);
185 if (tgt.Dot(tgf) > 0.) { // meme sens
186 while (prm2 <= prm1) {
c6541a0c 187 prm2 += 2.*M_PI;
7fd59977 188 }
189 }
190 else {
191 if (Abs(prm1-ft) <= Precision::Angular()) {
c6541a0c 192 prm1 += 2.*M_PI;
7fd59977 193 }
194 while (prm2 >= prm1) {
c6541a0c 195 prm2 -= 2.*M_PI;
7fd59977 196 }
197 }
198
199 if (prm1 >= ft-Tol && prm1 <= lt+Tol &&
200 prm2 >= ft-Tol && prm2 <= lt+Tol) {
201 myLFrom.Append(edgf);
202 myLTo.Append(edgt);
203 break;
204 }
205 else {
206 // Cas non traite : on est a cheval
0797d9d3 207#ifdef OCCT_DEBUG
7fd59977 208 cout <<" cas a cheval."<< endl;
209#endif
210// myLFrom.Append(edgf);
211// myLTo.Append(edgt);
212 }
213 }
214 }
215 else if (Tt == STANDARD_TYPE(Geom_BSplineCurve)) {
c5f3a425 216 Handle(Geom_BSplineCurve) Bf = Handle(Geom_BSplineCurve)::DownCast (Cf);
217 Handle(Geom_BSplineCurve) Bt = Handle(Geom_BSplineCurve)::DownCast (Ct);
7fd59977 218
219 Standard_Boolean IsSame = Standard_True;
220
221 Standard_Integer nbpoles = Bf->NbPoles();
222 if (nbpoles != Bt->NbPoles()) {
223 IsSame = Standard_False;
224 }
225
226 if (IsSame) {
227 Standard_Integer nbknots = Bf->NbKnots();
228 if (nbknots != Bt->NbKnots()) {
229 IsSame = Standard_False;
230 }
231
232 if (IsSame) {
233 TColgp_Array1OfPnt Pf(1, nbpoles), Pt(1, nbpoles);
234 Bf->Poles(Pf);
235 Bt->Poles(Pt);
236
237 Standard_Real tol3d = BRep_Tool::Tolerance(edgt);
238 for (Standard_Integer p = 1; p <= nbpoles; p++) {
239 if ( (Pf(p)).Distance(Pt(p)) > tol3d) {
240 IsSame = Standard_False;
241 break;
242 }
243 }
244
245 if (IsSame) {
246 TColStd_Array1OfReal Kf(1, nbknots), Kt(1, nbknots);
247 Bf->Knots(Kf);
248 Bt->Knots(Kt);
249
250 TColStd_Array1OfInteger Mf(1, nbknots), Mt(1, nbknots);
251 Bf->Multiplicities(Mf);
252 Bt->Multiplicities(Mt);
253
254 for (Standard_Integer k = 1; k <= nbknots; k++) {
255 if ((Kf(k)-Kt(k)) > Tol) {
256 IsSame = Standard_False;
257 break;
258 }
259 if (Abs(Mf(k)-Mt(k)) > Tol) {
260 IsSame = Standard_False;
261 break;
262 }
263 }
264
265 if (!Bf->IsRational()) {
266 if (Bt->IsRational()) {
267 IsSame = Standard_False;
268 }
269 }
270 else {
271 if (!Bt->IsRational()) {
272 IsSame = Standard_False;
273 }
274 }
275
276 if (IsSame && Bf->IsRational()) {
277 TColStd_Array1OfReal Wf(1, nbpoles), Wt(1, nbpoles);
278 Bf->Weights(Wf);
279 Bt->Weights(Wt);
280
281 for (Standard_Integer w = 1; w <= nbpoles; w++) {
282 if (Abs(Wf(w)-Wt(w)) > Tol) {
283 IsSame = Standard_False;
284 break;
285 }
286 }
287 }
288
289 if (IsSame) {
0797d9d3 290#ifdef OCCT_DEBUG
7fd59977 291 cout <<"memes bsplines."<< endl;
292#endif
293 myLFrom.Append(edgf);
294 myLTo.Append(edgt);
295 break;
296 }
297 }
298 }
299 }
300 }
301 else if (Tt == STANDARD_TYPE(Geom_BezierCurve)) {
c5f3a425 302 Handle(Geom_BezierCurve) Bf = Handle(Geom_BezierCurve)::DownCast (Cf);
303 Handle(Geom_BezierCurve) Bt = Handle(Geom_BezierCurve)::DownCast (Ct);
7fd59977 304
305 Standard_Boolean IsSame = Standard_True;
306
307 Standard_Integer nbpoles = Bf->NbPoles();
308 if (nbpoles != Bt->NbPoles()) {
309 IsSame = Standard_False;
310 }
311
312 if (IsSame) {
313 TColgp_Array1OfPnt Pf(1, nbpoles), Pt(1, nbpoles);
314 Bf->Poles(Pf);
315 Bt->Poles(Pt);
316
317 for (Standard_Integer p = 1; p <= nbpoles; p++) {
318 if ( (Pf(p)).Distance(Pt(p)) > Tol) {
319 IsSame = Standard_False;
320 break;
321 }
322 }
323
324 if (IsSame) {
325 if (!Bf->IsRational()) {
326 if (Bt->IsRational()) {
327 IsSame = Standard_False;
328 }
329 }
330 else {
331 if (!Bt->IsRational()) {
332 IsSame = Standard_False;
333 }
334 }
335
336 if (IsSame && Bf->IsRational()) {
337 TColStd_Array1OfReal Wf(1, nbpoles), Wt(1, nbpoles);
338 Bf->Weights(Wf);
339 Bt->Weights(Wt);
340
341 for (Standard_Integer w = 1; w <= nbpoles; w++) {
342 if (Abs(Wf(w)-Wt(w)) > Tol) {
343 IsSame = Standard_False;
344 break;
345 }
346 }
347 }
348
349 if (IsSame) {
0797d9d3 350#ifdef OCCT_DEBUG
7fd59977 351 cout <<"memes beziers."<< endl;
352#endif
353 myLFrom.Append(edgf);
354 myLTo.Append(edgt);
355 break;
356 }
357 }
358 }
359 }
360 }
361 }
362}