1 // Created on: 1998-11-23
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
23 #include <GeomLib_IsPlanarSurface.ixx>
25 #include <GeomLib.hxx>
26 #include <GeomAbs_CurveType.hxx>
27 #include <GeomAbs_SurfaceType.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_BezierCurve.hxx>
31 #include <Geom_BSplineCurve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_BezierSurface.hxx>
34 #include <Geom_BSplineSurface.hxx>
36 #include <GeomAdaptor_Surface.hxx>
37 #include <GeomAdaptor_Curve.hxx>
39 #include <TColgp_HArray1OfPnt.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
43 static Standard_Boolean Controle(const TColgp_Array1OfPnt& P,
45 const Standard_Real Tol)
48 Standard_Boolean B=Standard_True;
50 for (ii=1; ii<=P.Length() && B; ii++)
51 B = (Plan.Distance(P(ii)) < Tol);
56 static Standard_Boolean Controle(const TColgp_Array1OfPnt& Poles,
57 const Standard_Real Tol,
58 const Handle(Geom_Surface)& S,
61 Standard_Boolean IsPlan = Standard_False;
62 Standard_Boolean Essai = Standard_True;
63 Standard_Real gx,gy,gz;
64 Standard_Integer Nb = Poles.Length();
70 // Test allege (pour une rejection rapide)
71 TColgp_Array1OfPnt Aux(1,5);
75 Aux(4) = Poles(Nb/2+Nb/3);
77 GeomLib::Inertia(Aux, Bary, DX, DY, gx, gy, gz);
81 if (Essai) { // Test Grandeur nature...
82 GeomLib::Inertia(Poles, Bary, DX, DY, gx, gy, gz);
83 if (gz<Tol && gy>Tol) {
86 Standard_Real umin, umax, vmin, vmax;
87 S->Bounds(umin, umax, vmin, vmax);
88 S->D1( (umin+umax)/2, (vmin+vmax)/2, P, DU, DV);
89 // On prend DX le plus proche possible de DU
91 Standard_Real Angle1 = du.Angle(DX);
92 Standard_Real Angle2 = du.Angle(DY);
93 if (Angle1 > M_PI/2) Angle1 = M_PI-Angle1;
94 if (Angle2 > M_PI/2) Angle2 = M_PI-Angle2;
95 if (Angle2 < Angle1) {
96 du = DY; DY = DX; DX = du;
98 if (DX.Angle(DU) > M_PI/2) DX.Reverse();
99 if (DY.Angle(DV) > M_PI/2) DY.Reverse();
101 gp_Ax3 axe(Bary, DX^DY, DX);
102 Plan.SetPosition(axe);
103 Plan.SetLocation(Bary);
104 IsPlan = Standard_True;
110 static Standard_Boolean Controle(const Handle(Geom_Curve)& C,
112 const Standard_Real Tol)
114 Standard_Boolean B = Standard_True;
115 Standard_Integer ii, Nb;
116 GeomAbs_CurveType Type;
117 GeomAdaptor_Curve AC(C);
119 Handle(TColgp_HArray1OfPnt) TabP;
134 case GeomAbs_Ellipse:
135 case GeomAbs_Hyperbola:
136 case GeomAbs_Parabola:
141 case GeomAbs_BezierCurve:
144 Handle (Geom_BezierCurve) BZ = AC.Bezier();
145 TabP = new (TColgp_HArray1OfPnt) (1, AC.NbPoles());
146 for (ii=1; ii<=Nb; ii++)
147 TabP->SetValue(ii, BZ->Pole(ii));
150 case GeomAbs_BSplineCurve:
153 Handle (Geom_BSplineCurve) BZ = AC.BSpline();
154 TabP = new (TColgp_HArray1OfPnt) (1, AC.NbPoles());
155 for (ii=1; ii<=Nb; ii++)
156 TabP->SetValue(ii, BZ->Pole(ii));
161 Nb = 8 + 3*AC.NbIntervals(GeomAbs_CN);
166 Standard_Real u, du, f, l, d;
167 f = AC.FirstParameter();
168 l = AC.LastParameter();
170 for (ii=1; ii<=Nb && B ; ii++) {
172 d = Plan.Distance(C->Value(u));
177 B = Controle(TabP->Array1(), Plan, Tol);
185 GeomLib_IsPlanarSurface::GeomLib_IsPlanarSurface(const Handle(Geom_Surface)& S,
186 const Standard_Real Tol)
189 GeomAdaptor_Surface AS(S);
190 GeomAbs_SurfaceType Type;
197 IsPlan = Standard_True;
201 case GeomAbs_Cylinder :
203 case GeomAbs_Sphere :
206 IsPlan = Standard_False;
209 case GeomAbs_BezierSurface :
210 case GeomAbs_BSplineSurface :
212 Standard_Integer ii, jj, kk,
213 NbU = AS.NbUPoles(), NbV = AS.NbVPoles();
214 TColgp_Array1OfPnt Poles(1, NbU*NbV);
215 if (Type == GeomAbs_BezierSurface) {
216 Handle(Geom_BezierSurface) BZ;
218 for(ii=1, kk=1; ii<=NbU; ii++)
219 for(jj=1; jj<=NbV; jj++,kk++)
220 Poles(kk) = BZ->Pole(ii,jj);
223 Handle(Geom_BSplineSurface) BS;
225 for(ii=1, kk=1; ii<=NbU; ii++)
226 for(jj=1; jj<=NbV; jj++,kk++)
227 Poles(kk) = BS->Pole(ii,jj);
230 IsPlan = Controle(Poles, Tol, S, myPlan);
234 case GeomAbs_SurfaceOfRevolution :
236 Standard_Boolean Essai = Standard_True;
239 gp_Dir Dir = AS.AxeOfRevolution().Direction();
240 Standard_Real Umin, Umax, Vmin, Vmax;
241 S->Bounds(Umin, Umax, Vmin, Vmax);
242 S->D1((Umin+Umax)/2, (Vmin+Vmax)/2, P, DU, DV);
244 if (Dn.Magnitude() > 1.e-7) {
245 Standard_Real angle = Dir.Angle(Dn);
246 if (angle > M_PI/2) {
247 angle = M_PI - angle;
250 Essai = (angle < 0.1);
255 axe.SetXDirection(DU);
256 myPlan.SetPosition(axe);
257 myPlan.SetLocation(P);
258 Handle(Geom_Curve) C;
260 IsPlan = Controle(C, myPlan, Tol);
263 IsPlan = Standard_False;
267 case GeomAbs_SurfaceOfExtrusion :
269 Standard_Boolean Essai = Standard_False;
270 Standard_Real Umin, Umax, Vmin, Vmax;
275 S->Bounds(Umin, Umax, Vmin, Vmax);
276 S->D1((Umin+Umax)/2, (Vmin+Vmax)/2, P, Du, Dv);
278 norm = Dn.Magnitude();
281 Standard_Real angmax = Tol / (Vmax-Vmin);
283 Essai = (D.IsNormal(AS.Direction(), angmax));
286 gp_Ax3 axe(P, Dn, Du);
287 myPlan.SetPosition(axe);
288 myPlan.SetLocation(P);
289 Handle(Geom_Curve) C;
290 C = S->VIso((Vmin+Vmax)/2);
291 IsPlan = Controle(C, myPlan, Tol);
294 IsPlan = Standard_False;
300 Standard_Integer NbU,NbV, ii, jj, kk;
301 NbU = 8 + 3*AS.NbUIntervals(GeomAbs_CN);
302 NbV = 8 + 3*AS.NbVIntervals(GeomAbs_CN);
303 Standard_Real Umin, Umax, Vmin, Vmax, du, dv, U, V;
304 S->Bounds(Umin, Umax, Vmin, Vmax);
305 du = (Umax-Umin)/(NbU-1);
306 dv = (Vmax-Vmin)/(NbV-1);
307 TColgp_Array1OfPnt Pnts(1, NbU*NbV);
308 for(ii=0, kk=1; ii<NbU; ii++) {
310 for(jj=0; jj<NbV; jj++,kk++) {
312 S->D0(U,V, Pnts(kk));
316 IsPlan = Controle(Pnts, Tol, S, myPlan);
321 Standard_Boolean GeomLib_IsPlanarSurface::IsPlanar() const
326 const gp_Pln& GeomLib_IsPlanarSurface::Plan() const
328 if (!IsPlan) StdFail_NotDone::Raise(" GeomLib_IsPlanarSurface");