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