e4ac811a60435a08536e8e6f376876ccb6532525
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_Surface.hxx
1 // Created on: 1998-06-03
2 // Created by: data exchange team
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef _ShapeAnalysis_Surface_HeaderFile
18 #define _ShapeAnalysis_Surface_HeaderFile
19
20 #include <Standard.hxx>
21 #include <Standard_Type.hxx>
22
23 #include <Extrema_ExtPS.hxx>
24 #include <GeomAdaptor_Surface.hxx>
25 #include <Standard_Boolean.hxx>
26 #include <Standard_Integer.hxx>
27 #include <Standard_Real.hxx>
28 #include <gp_Pnt.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <Bnd_Box.hxx>
31 #include <MMgt_TShared.hxx>
32 #include <TColgp_Array1OfPnt.hxx>
33 #include <TColgp_Array1OfPnt2d.hxx>
34 class Geom_Surface;
35 class GeomAdaptor_HSurface;
36 class Geom_Curve;
37 class gp_Pnt2d;
38 class gp_Pnt;
39 class Bnd_Box;
40
41
42 class ShapeAnalysis_Surface;
43 DEFINE_STANDARD_HANDLE(ShapeAnalysis_Surface, MMgt_TShared)
44
45 //! Complements standard tool Geom_Surface by providing additional
46 //! functionality for detection surface singularities, checking
47 //! spatial surface closure and computing projections of 3D points
48 //! onto a surface.
49 //!
50 //! * The singularities
51 //! Each singularity stores the precision with which corresponding
52 //! surface iso-line is considered as degenerated.
53 //! The number of singularities is determined by specifying precision
54 //! and always not greater than 4.
55 //!
56 //! * The spatial closure
57 //! The check for spatial closure is performed with given precision
58 //! (default value is Precision::Confusion).
59 //! If Geom_Surface says that the surface is closed, this class
60 //! also says this. Otherwise additional analysis is performed.
61 //!
62 //! * The parameters of 3D point on the surface
63 //! The projection of the point is performed with given precision.
64 //! This class tries to find a solution taking into account possible
65 //! singularities.
66 //! Additional method for searching the solution from already built
67 //! one is also provided.
68 //!
69 //! This tool is optimised: computes most information only once
70 class ShapeAnalysis_Surface : public MMgt_TShared
71 {
72
73 public:
74
75   
76   //! Creates an analyzer object on the basis of existing surface
77   Standard_EXPORT ShapeAnalysis_Surface(const Handle(Geom_Surface)& S);
78   
79   //! Loads existing surface
80   Standard_EXPORT void Init (const Handle(Geom_Surface)& S);
81   
82   //! Reads all the data from another Surface, without recomputing
83   Standard_EXPORT void Init (const Handle(ShapeAnalysis_Surface)& other);
84   
85   Standard_EXPORT void SetDomain (const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2);
86   
87   //! Returns a surface being analyzed
88     const Handle(Geom_Surface)& Surface() const;
89   
90   //! Returns the Adaptor.
91   //! Creates it if not yet done.
92   Standard_EXPORT const Handle(GeomAdaptor_HSurface)& Adaptor3d();
93   
94   //! Returns the Adaptor (may be Null if method Adaptor() was not called)
95     const Handle(GeomAdaptor_HSurface)& TrueAdaptor3d() const;
96   
97   //! Returns 3D distance found by one of the following methods.
98   //! IsDegenerated, DegeneratedValues, ProjectDegenerated
99   //! (distance between 3D point and found or last (if not found)
100   //! singularity),
101   //! IsUClosed, IsVClosed (minimum value of precision to consider
102   //! the surface to be closed),
103   //! ValueOfUV (distance between 3D point and found solution).
104     Standard_Real Gap() const;
105   
106   //! Returns a 3D point specified by parameters in surface
107   //! parametrical space
108     gp_Pnt Value (const Standard_Real u, const Standard_Real v);
109   
110   //! Returns a 3d point specified by a point in surface
111   //! parametrical space
112     gp_Pnt Value (const gp_Pnt2d& p2d);
113   
114   //! Returns True if the surface has singularities for the given
115   //! precision (i.e. if there are surface singularities with sizes
116   //! not greater than precision).
117   Standard_EXPORT Standard_Boolean HasSingularities (const Standard_Real preci);
118   
119   //! Returns the number of singularities for the given precision
120   //! (i.e. number of surface singularities with sizes not greater
121   //! than precision).
122   Standard_EXPORT Standard_Integer NbSingularities (const Standard_Real preci);
123   
124   //! Returns the characteristics of the singularity specified by
125   //! its rank number <num>.
126   //! That means, that it is not neccessary for <num> to be in the
127   //! range [1, NbSingularities] but must be not greater than
128   //! possible (see ComputeSingularities).
129   //! The returned characteristics are:
130   //! preci: the smallest precision with which the iso-line is
131   //! considered as degenerated,
132   //! P3d: 3D point of singularity (middle point of the surface
133   //! iso-line),
134   //! firstP2d and lastP2d: first and last 2D points of the
135   //! iso-line in parametrical surface,
136   //! firstpar and lastpar: first and last parameters of the
137   //! iso-line in parametrical surface,
138   //! uisodeg: if the degenerated iso-line is U-iso (True) or
139   //! V-iso (False).
140   //! Returns False if <num> is out of range, else returns True.
141   Standard_EXPORT Standard_Boolean Singularity (const Standard_Integer num, Standard_Real& preci, gp_Pnt& P3d, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, Standard_Boolean& uisodeg);
142   
143   //! Returns True if there is at least one surface boundary which
144   //! is considered as degenerated with <preci> and distance
145   //! between P3d and corresponding singular point is less than
146   //! <preci>
147   Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt& P3d, const Standard_Real preci);
148   
149   //! Returns True if there is at least one surface iso-line which
150   //! is considered as degenerated with <preci> and distance
151   //! between P3d and corresponding singular point is less than
152   //! <preci> (like IsDegenerated).
153   //! Returns characteristics of the first found boundary matching
154   //! those criteria.
155   Standard_EXPORT Standard_Boolean DegeneratedValues (const gp_Pnt& P3d, const Standard_Real preci, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, const Standard_Boolean forward = Standard_True);
156   
157   //! Projects a point <P3d> on a singularity by computing
158   //! one of the coordinates of preliminary computed <result>.
159   //!
160   //! Finds the iso-line which is considered as degenerated with
161   //! <preci> and
162   //! a. distance between P3d and corresponding singular point is
163   //! less than <preci> (like IsDegenerated) or
164   //! b. difference between already computed <result>'s coordinate
165   //! and iso-coordinate of the boundary is less than 2D
166   //! resolution (computed from <preci> by Geom_Adaptor).
167   //! Then sets not yet computed <result>'s coordinate taking it
168   //! from <neighbour> and returns True.
169   Standard_EXPORT Standard_Boolean ProjectDegenerated (const gp_Pnt& P3d, const Standard_Real preci, const gp_Pnt2d& neighbour, gp_Pnt2d& result);
170   
171   //! Checks points at the beginning (direct is True) or end
172   //! (direct is False) of array <points> to lie in singularity of
173   //! surface, and if yes, adjusts the indeterminate 2d coordinate
174   //! of these points by nearest point which is not in singularity.
175   //! Returns True if some points were adjusted.
176   Standard_EXPORT Standard_Boolean ProjectDegenerated (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, TColgp_Array1OfPnt2d& pnt2d, const Standard_Real preci, const Standard_Boolean direct);
177   
178   //! Returns True if straight pcurve going from point p2d1 to p2d2
179   //! is degenerate, i.e. lies in the singularity of the surface.
180   //! NOTE: it uses another method of detecting singularity than
181   //! used by ComputeSingularities() et al.!
182   //! For that, maximums of distances between points p2d1, p2d2
183   //! and 0.5*(p2d1+p2d2) and between corresponding 3d points are
184   //! computed.
185   //! The pcurve (p2d1, p2d2) is considered as degenerate if:
186   //! - max distance in 3d is less than <tol>
187   //! - max distance in 2d is at least <ratio> times greather than
188   //! the Resolution computed from max distance in 3d
189   //! (max3d < tol && max2d > ratio * Resolution(max3d))
190   //! NOTE: <ratio> should be >1 (e.g. 10)
191   Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt2d& p2d1, const gp_Pnt2d& p2d2, const Standard_Real tol, const Standard_Real ratio);
192   
193   //! Returns the bounds of the surface
194   //! (from Bounds from Surface, but buffered)
195     void Bounds (Standard_Real& ufirst, Standard_Real& ulast, Standard_Real& vfirst, Standard_Real& vlast) const;
196   
197   //! Computes bound isos (protected against exceptions)
198   Standard_EXPORT void ComputeBoundIsos();
199   
200   //! Returns a U-Iso. Null if not possible or failed
201   //! Remark : bound isos are buffered
202   Standard_EXPORT Handle(Geom_Curve) UIso (const Standard_Real U);
203   
204   //! Returns a V-Iso. Null if not possible or failed
205   //! Remark : bound isos are buffered
206   Standard_EXPORT Handle(Geom_Curve) VIso (const Standard_Real V);
207   
208   //! Tells if the Surface is spatially closed in U with given
209   //! precision. If <preci> < 0 then Precision::Confusion is used.
210   //! If Geom_Surface says that the surface is U-closed, this method
211   //! also says this. Otherwise additional analysis is performed,
212   //! comparing given precision with the following distances:
213   //! - periodic B-Splines are closed,
214   //! - polinomial B-Spline with boundary multiplicities degree+1
215   //! and Bezier - maximum distance between poles,
216   //! - rational B-Spline or one with boundary multiplicities not
217   //! degree+1 - maximum distance computed at knots and their
218   //! middles,
219   //! - surface of extrusion - distance between ends of basis
220   //! curve,
221   //! - other (RectangularTrimmed and Offset) - maximum distance
222   //! computed at 100 equi-distanted points.
223   Standard_EXPORT Standard_Boolean IsUClosed (const Standard_Real preci = -1);
224   
225   //! Tells if the Surface is spatially closed in V with given
226   //! precision. If <preci> < 0 then Precision::Confusion is used.
227   //! If Geom_Surface says that the surface is V-closed, this method
228   //! also says this. Otherwise additional analysis is performed,
229   //! comparing given precision with the following distances:
230   //! - periodic B-Splines are closed,
231   //! - polinomial B-Spline with boundary multiplicities degree+1
232   //! and Bezier - maximum distance between poles,
233   //! - rational B-Spline or one with boundary multiplicities not
234   //! degree+1 - maximum distance computed at knots and their
235   //! middles,
236   //! - surface of revolution - distance between ends of basis
237   //! curve,
238   //! - other (RectangularTrimmed and Offset) - maximum distance
239   //! computed at 100 equi-distanted points.
240   Standard_EXPORT Standard_Boolean IsVClosed (const Standard_Real preci = -1);
241   
242   //! Computes the parameters in the surface parametrical space of
243   //! 3D point.
244   //! The result is parameters of the point projected onto the
245   //! surface.
246   //! This method enhances functionality provided by the standard
247   //! tool GeomAPI_ProjectPointOnSurface by treatment of cases when
248   //! the projected point is near to the surface boundaries and
249   //! when this standard tool fails.
250   Standard_EXPORT gp_Pnt2d ValueOfUV (const gp_Pnt& P3D, const Standard_Real preci);
251   
252   //! Projects a point P3D on the surface.
253   //! Does the same thing as ValueOfUV but tries to optimize
254   //! computations by taking into account previous point <p2dPrev>:
255   //! makes a step by UV and tries Newton algorithm.
256   //! If <maxpreci> >0. and distance between solution and
257   //! P3D is greater than <maxpreci>, that solution is considered
258   //! as bad, and ValueOfUV() is used.
259   //! If not succeded, calls ValueOfUV()
260   Standard_EXPORT gp_Pnt2d NextValueOfUV (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, const Standard_Real maxpreci = -1.0);
261   
262   //! Tries a refinement of an already computed couple (U,V) by
263   //! using projecting 3D point on iso-lines:
264   //! 1. boundaries of the surface,
265   //! 2. iso-lines passing through (U,V)
266   //! 3. iteratively received iso-lines passing through new U and
267   //! new V (number of iterations is limited by 5 in each
268   //! direction)
269   //! Returns the best resulting distance between P3D and Value(U,V)
270   //! in the case of success. Else, returns a very great value
271   Standard_EXPORT Standard_Real UVFromIso (const gp_Pnt& P3D, const Standard_Real preci, Standard_Real& U, Standard_Real& V);
272   
273   //! Returns minimum value to consider the surface as U-closed
274     Standard_Real UCloseVal() const;
275   
276   //! Returns minimum value to consider the surface as V-closed
277     Standard_Real VCloseVal() const;
278   
279   Standard_EXPORT const Bnd_Box& GetBoxUF();
280   
281   Standard_EXPORT const Bnd_Box& GetBoxUL();
282   
283   Standard_EXPORT const Bnd_Box& GetBoxVF();
284   
285   Standard_EXPORT const Bnd_Box& GetBoxVL();
286
287
288
289
290   DEFINE_STANDARD_RTTIEXT(ShapeAnalysis_Surface,MMgt_TShared)
291
292 protected:
293
294
295   Handle(Geom_Surface) mySurf;
296   Handle(GeomAdaptor_HSurface) myAdSur;
297   Extrema_ExtPS myExtPS;
298   Standard_Boolean myExtOK;
299   Standard_Integer myNbDeg;
300   Standard_Real myPreci[4];
301   gp_Pnt myP3d[4];
302   gp_Pnt2d myFirstP2d[4];
303   gp_Pnt2d myLastP2d[4];
304   Standard_Real myFirstPar[4];
305   Standard_Real myLastPar[4];
306   Standard_Boolean myUIsoDeg[4];
307   Standard_Boolean myIsos;
308   Standard_Real myUF;
309   Standard_Real myUL;
310   Standard_Real myVF;
311   Standard_Real myVL;
312   Handle(Geom_Curve) myIsoUF;
313   Handle(Geom_Curve) myIsoUL;
314   Handle(Geom_Curve) myIsoVF;
315   Handle(Geom_Curve) myIsoVL;
316   Standard_Boolean myIsoBoxes;
317   Bnd_Box myBndUF;
318   Bnd_Box myBndUL;
319   Bnd_Box myBndVF;
320   Bnd_Box myBndVL;
321   Standard_Real myGap;
322   Standard_Real myUDelt;
323   Standard_Real myVDelt;
324   Standard_Real myUCloseVal;
325   Standard_Real myVCloseVal;
326
327
328 private:
329
330   
331   //! Computes singularities on the surface.
332   //! Computes the sizes of boundaries or singular ares of the
333   //! surface. Then each boundary or area is considered as
334   //! degenerated with precision not less than its size.
335   //!
336   //! The singularities and corresponding precisions are the
337   //! following:
338   //! - ConicalSurface -  one degenerated point (apex of the cone),
339   //! precision is 0.,
340   //! - ToroidalSurface - two degenerated points, precision is
341   //! Max (0, majorR-minorR),
342   //! - SphericalSurface - two degenerated points (poles),
343   //! precision is 0.
344   //! - Bounded, Surface Of Revolution, Offset - four degenerated
345   //! points, precisions are maximum distance between corners
346   //! and middle point on the boundary
347   Standard_EXPORT void ComputeSingularities();
348   
349   Standard_EXPORT void ComputeBoxes();
350
351   //! @return 0, 1 or 2.
352   Standard_EXPORT Standard_Integer SurfaceNewton (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, gp_Pnt2d& sol);
353
354   Standard_EXPORT void SortSingularities();
355
356
357
358 };
359
360
361 #include <ShapeAnalysis_Surface.lxx>
362
363
364
365
366
367 #endif // _ShapeAnalysis_Surface_HeaderFile