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