1 // Created on: 1998-11-23
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-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 <Geom_BezierCurve.hxx>
19 #include <Geom_BezierSurface.hxx>
20 #include <Geom_BSplineCurve.hxx>
21 #include <Geom_BSplineSurface.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Surface.hxx>
24 #include <GeomAbs_CurveType.hxx>
25 #include <GeomAbs_SurfaceType.hxx>
26 #include <GeomAdaptor_Curve.hxx>
27 #include <GeomAdaptor_Surface.hxx>
28 #include <GeomLib.hxx>
29 #include <GeomLib_IsPlanarSurface.hxx>
31 #include <StdFail_NotDone.hxx>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColgp_HArray1OfPnt.hxx>
35 static Standard_Boolean Controle(const TColgp_Array1OfPnt& P,
37 const Standard_Real Tol)
40 Standard_Boolean B=Standard_True;
42 for (ii=1; ii<=P.Length() && B; ii++)
43 B = (Plan.Distance(P(ii)) < Tol);
48 static Standard_Boolean Controle(const TColgp_Array1OfPnt& Poles,
49 const Standard_Real Tol,
50 const Handle(Geom_Surface)& S,
53 Standard_Boolean IsPlan = Standard_False;
54 Standard_Boolean Essai = Standard_True;
55 Standard_Real gx,gy,gz;
56 Standard_Integer Nb = Poles.Length();
62 // Test allege (pour une rejection rapide)
63 TColgp_Array1OfPnt Aux(1,5);
67 Aux(4) = Poles(Nb/2+Nb/3);
69 GeomLib::Inertia(Aux, Bary, DX, DY, gx, gy, gz);
73 if (Essai) { // Test Grandeur nature...
74 GeomLib::Inertia(Poles, Bary, DX, DY, gx, gy, gz);
75 if (gz<Tol && gy>Tol) {
78 Standard_Real umin, umax, vmin, vmax;
79 S->Bounds(umin, umax, vmin, vmax);
80 S->D1( (umin+umax)/2, (vmin+vmax)/2, P, DU, DV);
81 // On prend DX le plus proche possible de DU
83 Standard_Real Angle1 = du.Angle(DX);
84 Standard_Real Angle2 = du.Angle(DY);
85 if (Angle1 > M_PI/2) Angle1 = M_PI-Angle1;
86 if (Angle2 > M_PI/2) Angle2 = M_PI-Angle2;
87 if (Angle2 < Angle1) {
88 du = DY; DY = DX; DX = du;
90 if (DX.Angle(DU) > M_PI/2) DX.Reverse();
91 if (DY.Angle(DV) > M_PI/2) DY.Reverse();
93 gp_Ax3 axe(Bary, DX^DY, DX);
94 Plan.SetPosition(axe);
95 Plan.SetLocation(Bary);
96 IsPlan = Standard_True;
102 static Standard_Boolean Controle(const Handle(Geom_Curve)& C,
104 const Standard_Real Tol)
106 Standard_Boolean B = Standard_True;
107 Standard_Integer ii, Nb;
108 GeomAbs_CurveType Type;
109 GeomAdaptor_Curve AC(C);
111 Handle(TColgp_HArray1OfPnt) TabP;
126 case GeomAbs_Ellipse:
127 case GeomAbs_Hyperbola:
128 case GeomAbs_Parabola:
133 case GeomAbs_BezierCurve:
136 Handle (Geom_BezierCurve) BZ = AC.Bezier();
137 TabP = new (TColgp_HArray1OfPnt) (1, AC.NbPoles());
138 for (ii=1; ii<=Nb; ii++)
139 TabP->SetValue(ii, BZ->Pole(ii));
142 case GeomAbs_BSplineCurve:
145 Handle (Geom_BSplineCurve) BZ = AC.BSpline();
146 TabP = new (TColgp_HArray1OfPnt) (1, AC.NbPoles());
147 for (ii=1; ii<=Nb; ii++)
148 TabP->SetValue(ii, BZ->Pole(ii));
153 Nb = 8 + 3*AC.NbIntervals(GeomAbs_CN);
158 Standard_Real u, du, f, l, d;
159 f = AC.FirstParameter();
160 l = AC.LastParameter();
162 for (ii=1; ii<=Nb && B ; ii++) {
164 d = Plan.Distance(C->Value(u));
169 B = Controle(TabP->Array1(), Plan, Tol);
177 GeomLib_IsPlanarSurface::GeomLib_IsPlanarSurface(const Handle(Geom_Surface)& S,
178 const Standard_Real Tol)
181 GeomAdaptor_Surface AS(S);
182 GeomAbs_SurfaceType Type;
189 IsPlan = Standard_True;
193 case GeomAbs_Cylinder :
195 case GeomAbs_Sphere :
198 IsPlan = Standard_False;
201 case GeomAbs_BezierSurface :
202 case GeomAbs_BSplineSurface :
204 Standard_Integer ii, jj, kk,
205 NbU = AS.NbUPoles(), NbV = AS.NbVPoles();
206 TColgp_Array1OfPnt Poles(1, NbU*NbV);
207 if (Type == GeomAbs_BezierSurface) {
208 Handle(Geom_BezierSurface) BZ;
210 for(ii=1, kk=1; ii<=NbU; ii++)
211 for(jj=1; jj<=NbV; jj++,kk++)
212 Poles(kk) = BZ->Pole(ii,jj);
215 Handle(Geom_BSplineSurface) BS;
217 for(ii=1, kk=1; ii<=NbU; ii++)
218 for(jj=1; jj<=NbV; jj++,kk++)
219 Poles(kk) = BS->Pole(ii,jj);
222 IsPlan = Controle(Poles, Tol, S, myPlan);
226 case GeomAbs_SurfaceOfRevolution :
228 Standard_Boolean Essai = Standard_True;
231 gp_Dir Dir = AS.AxeOfRevolution().Direction();
232 Standard_Real Umin, Umax, Vmin, Vmax;
233 S->Bounds(Umin, Umax, Vmin, Vmax);
234 S->D1((Umin+Umax)/2, (Vmin+Vmax)/2, P, DU, DV);
235 if (DU.Magnitude() <= gp::Resolution() ||
236 DV.Magnitude() <= gp::Resolution())
238 Standard_Real NewU = (Umin+Umax)/2 + (Umax-Umin)*0.1;
239 Standard_Real NewV = (Vmin+Vmax)/2 + (Vmax-Vmin)*0.1;
240 S->D1( NewU, NewV, P, DU, DV );
243 if (Dn.Magnitude() > 1.e-7) {
244 Standard_Real angle = Dir.Angle(Dn);
245 if (angle > M_PI/2) {
246 angle = M_PI - angle;
249 Essai = (angle < 0.1);
254 axe.SetXDirection(DU);
255 myPlan.SetPosition(axe);
256 myPlan.SetLocation(P);
257 Handle(Geom_Curve) C;
259 IsPlan = Controle(C, myPlan, Tol);
262 IsPlan = Standard_False;
266 case GeomAbs_SurfaceOfExtrusion :
268 Standard_Boolean Essai = Standard_False;
269 Standard_Real Umin, Umax, Vmin, Vmax;
274 S->Bounds(Umin, Umax, Vmin, Vmax);
275 S->D1((Umin+Umax)/2, (Vmin+Vmax)/2, P, Du, Dv);
276 if (Du.Magnitude() <= gp::Resolution() ||
277 Dv.Magnitude() <= gp::Resolution())
279 Standard_Real NewU = (Umin+Umax)/2 + (Umax-Umin)*0.1;
280 Standard_Real NewV = (Vmin+Vmax)/2 + (Vmax-Vmin)*0.1;
281 S->D1( NewU, NewV, P, Du, Dv );
284 norm = Dn.Magnitude();
287 Standard_Real angmax = Tol / (Vmax-Vmin);
289 Essai = (D.IsNormal(AS.Direction(), angmax));
292 gp_Ax3 axe(P, Dn, Du);
293 myPlan.SetPosition(axe);
294 myPlan.SetLocation(P);
295 Handle(Geom_Curve) C;
296 C = S->VIso((Vmin+Vmax)/2);
297 IsPlan = Controle(C, myPlan, Tol);
300 IsPlan = Standard_False;
306 Standard_Integer NbU,NbV, ii, jj, kk;
307 NbU = 8 + 3*AS.NbUIntervals(GeomAbs_CN);
308 NbV = 8 + 3*AS.NbVIntervals(GeomAbs_CN);
309 Standard_Real Umin, Umax, Vmin, Vmax, du, dv, U, V;
310 S->Bounds(Umin, Umax, Vmin, Vmax);
311 du = (Umax-Umin)/(NbU-1);
312 dv = (Vmax-Vmin)/(NbV-1);
313 TColgp_Array1OfPnt Pnts(1, NbU*NbV);
314 for(ii=0, kk=1; ii<NbU; ii++) {
316 for(jj=0; jj<NbV; jj++,kk++) {
318 S->D0(U,V, Pnts(kk));
322 IsPlan = Controle(Pnts, Tol, S, myPlan);
327 Standard_Boolean GeomLib_IsPlanarSurface::IsPlanar() const
332 const gp_Pln& GeomLib_IsPlanarSurface::Plan() const
334 if (!IsPlan) throw StdFail_NotDone(" GeomLib_IsPlanarSurface");