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