1 // Created on: 1996-02-15
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Tool.hxx>
20 #include <Geom_BezierCurve.hxx>
21 #include <Geom_BSplineCurve.hxx>
22 #include <Geom_Circle.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Ellipse.hxx>
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>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_Array1OfReal.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Shape.hxx>
39 //=======================================================================
42 //=======================================================================
43 void LocOpe_FindEdges::Set(const TopoDS_Shape& FFrom,
44 const TopoDS_Shape& FTo)
52 TopExp_Explorer expf,expt;
53 Handle(Geom_Curve) Cf,Ct;
55 Standard_Real ff,lf,ft,lt;
56 Handle(Standard_Type) Tf,Tt;
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());
63 Cf = Handle(Geom_Curve)::DownCast (GGf);
65 Tf = Cf->DynamicType();
66 if (Tf == STANDARD_TYPE(Geom_TrimmedCurve)) {
67 Cf = Handle(Geom_TrimmedCurve)::DownCast (Cf)->BasisCurve();
68 Tf = Cf->DynamicType();
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)) {
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());
80 Ct = Handle(Geom_Curve)::DownCast (GGt);
82 Tt = Ct->DynamicType();
83 if (Tt == STANDARD_TYPE(Geom_TrimmedCurve)) {
84 Ct = Handle(Geom_TrimmedCurve)::DownCast (Ct)->BasisCurve();
85 Tt = Ct->DynamicType();
90 // On a presomption de confusion
91 Standard_Real Tol = Precision::Confusion();
92 if (Tt == STANDARD_TYPE(Geom_Line)) {
93 gp_Lin lif = Handle(Geom_Line)::DownCast (Cf)->Lin();
94 gp_Lin lit = Handle(Geom_Line)::DownCast (Ct)->Lin();
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) {
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);
113 else if (Tt == STANDARD_TYPE(Geom_Circle)) {
114 gp_Circ cif = Handle(Geom_Circle)::DownCast (Cf)->Circ();
115 gp_Circ cit = Handle(Geom_Circle)::DownCast (Ct)->Circ();
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
122 ElCLib::D1(ff,cif,p1,tgf);
123 p2 = ElCLib::Value(lf,cif);
125 Standard_Real prm1 = ElCLib::Parameter(cit,p1);
126 Standard_Real Tol2d = Precision::PConfusion();
127 if (Abs(prm1-ft) <= Tol2d) prm1 = ft;
128 prm1 = ElCLib::InPeriod(prm1,ft,ft+2.*M_PI);
129 ElCLib::D1(prm1,cit,p1,tgt);
131 Standard_Real prm2 = ElCLib::Parameter(cit,p2);
132 if (tgt.Dot(tgf) > 0.) { // meme sens
133 while (prm2 <= prm1) {
138 if (Abs(prm1-ft) <= Precision::Angular()) {
141 while (prm2 >= prm1) {
146 if (prm1 >= ft-Tol && prm1 <= lt+Tol &&
147 prm2 >= ft-Tol && prm2 <= lt+Tol) {
148 myLFrom.Append(edgf);
153 // Cas non traite : on est a cheval
155 cout <<" cas a cheval."<< endl;
158 // myLFrom.Append(edgf);
159 // myLTo.Append(edgt);
164 else if (Tt == STANDARD_TYPE(Geom_Ellipse)) {
165 gp_Elips cif = Handle(Geom_Ellipse)::DownCast (Cf)->Elips();
166 gp_Elips cit = Handle(Geom_Ellipse)::DownCast (Ct)->Elips();
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
176 ElCLib::D1(ff,cif,p1,tgf);
177 p2 = ElCLib::Value(lf,cif);
179 Standard_Real prm1 = ElCLib::Parameter(cit,p1);
180 prm1 = ElCLib::InPeriod(prm1,ft,ft+2.*M_PI);
181 ElCLib::D1(prm1,cit,p1,tgt);
183 Standard_Real prm2 = ElCLib::Parameter(cit,p2);
184 if (tgt.Dot(tgf) > 0.) { // meme sens
185 while (prm2 <= prm1) {
190 if (Abs(prm1-ft) <= Precision::Angular()) {
193 while (prm2 >= prm1) {
198 if (prm1 >= ft-Tol && prm1 <= lt+Tol &&
199 prm2 >= ft-Tol && prm2 <= lt+Tol) {
200 myLFrom.Append(edgf);
205 // Cas non traite : on est a cheval
207 cout <<" cas a cheval."<< endl;
209 // myLFrom.Append(edgf);
210 // myLTo.Append(edgt);
214 else if (Tt == STANDARD_TYPE(Geom_BSplineCurve)) {
215 Handle(Geom_BSplineCurve) Bf = Handle(Geom_BSplineCurve)::DownCast (Cf);
216 Handle(Geom_BSplineCurve) Bt = Handle(Geom_BSplineCurve)::DownCast (Ct);
218 Standard_Boolean IsSame = Standard_True;
220 Standard_Integer nbpoles = Bf->NbPoles();
221 if (nbpoles != Bt->NbPoles()) {
222 IsSame = Standard_False;
226 Standard_Integer nbknots = Bf->NbKnots();
227 if (nbknots != Bt->NbKnots()) {
228 IsSame = Standard_False;
232 TColgp_Array1OfPnt Pf(1, nbpoles), Pt(1, nbpoles);
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;
245 TColStd_Array1OfReal Kf(1, nbknots), Kt(1, nbknots);
249 TColStd_Array1OfInteger Mf(1, nbknots), Mt(1, nbknots);
250 Bf->Multiplicities(Mf);
251 Bt->Multiplicities(Mt);
253 for (Standard_Integer k = 1; k <= nbknots; k++) {
254 if ((Kf(k)-Kt(k)) > Tol) {
255 IsSame = Standard_False;
258 if (Abs(Mf(k)-Mt(k)) > Tol) {
259 IsSame = Standard_False;
264 if (!Bf->IsRational()) {
265 if (Bt->IsRational()) {
266 IsSame = Standard_False;
270 if (!Bt->IsRational()) {
271 IsSame = Standard_False;
275 if (IsSame && Bf->IsRational()) {
276 TColStd_Array1OfReal Wf(1, nbpoles), Wt(1, nbpoles);
280 for (Standard_Integer w = 1; w <= nbpoles; w++) {
281 if (Abs(Wf(w)-Wt(w)) > Tol) {
282 IsSame = Standard_False;
290 cout <<"memes bsplines."<< endl;
292 myLFrom.Append(edgf);
300 else if (Tt == STANDARD_TYPE(Geom_BezierCurve)) {
301 Handle(Geom_BezierCurve) Bf = Handle(Geom_BezierCurve)::DownCast (Cf);
302 Handle(Geom_BezierCurve) Bt = Handle(Geom_BezierCurve)::DownCast (Ct);
304 Standard_Boolean IsSame = Standard_True;
306 Standard_Integer nbpoles = Bf->NbPoles();
307 if (nbpoles != Bt->NbPoles()) {
308 IsSame = Standard_False;
312 TColgp_Array1OfPnt Pf(1, nbpoles), Pt(1, nbpoles);
316 for (Standard_Integer p = 1; p <= nbpoles; p++) {
317 if ( (Pf(p)).Distance(Pt(p)) > Tol) {
318 IsSame = Standard_False;
324 if (!Bf->IsRational()) {
325 if (Bt->IsRational()) {
326 IsSame = Standard_False;
330 if (!Bt->IsRational()) {
331 IsSame = Standard_False;
335 if (IsSame && Bf->IsRational()) {
336 TColStd_Array1OfReal Wf(1, nbpoles), Wt(1, nbpoles);
340 for (Standard_Integer w = 1; w <= nbpoles; w++) {
341 if (Abs(Wf(w)-Wt(w)) > Tol) {
342 IsSame = Standard_False;
350 cout <<"memes beziers."<< endl;
352 myLFrom.Append(edgf);