0032139: Visualization - support single-precision floating point data within Poly_Tri...
[occt.git] / src / Poly / Poly_Triangulation.hxx
1 // Created on: 1995-03-06
2 // Created by: Laurent PAINNOT
3 // Copyright (c) 1995-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 _Poly_Triangulation_HeaderFile
18 #define _Poly_Triangulation_HeaderFile
19
20 #include <Bnd_Box.hxx>
21 #include <gp_Vec3f.hxx>
22 #include <Poly_HArray1OfTriangle.hxx>
23 #include <Poly_ArrayOfNodes.hxx>
24 #include <Poly_ArrayOfUVNodes.hxx>
25 #include <TColgp_HArray1OfPnt.hxx>
26 #include <TColgp_HArray1OfPnt2d.hxx>
27 #include <TShort_HArray1OfShortReal.hxx>
28
29 class Poly_Triangulation;
30 DEFINE_STANDARD_HANDLE(Poly_Triangulation, Standard_Transient)
31
32 //! Provides a triangulation for a surface, a set of surfaces, or
33 //! more generally a shape.
34 //! A triangulation consists of an approximate representation
35 //! of the actual shape, using a collection of points and
36 //! triangles. The points are located on the surface. The
37 //! edges of the triangles connect adjacent points with a
38 //! straight line that approximates the true curve on the surface.
39 //! A triangulation comprises:
40 //! -   A table of 3D nodes (3D points on the surface).
41 //! -   A table of triangles. Each triangle (Poly_Triangle
42 //! object) comprises a triplet of indices in the table of 3D
43 //! nodes specific to the triangulation.
44 //! -   A table of 2D nodes (2D points), parallel to the table of
45 //! 3D nodes. This table is optional. If it exists, the
46 //! coordinates of a 2D point are the (u, v) parameters
47 //! of the corresponding 3D point on the surface
48 //! approximated by the triangulation.
49 //! -   A deflection (optional), which maximizes the distance
50 //! from a point on the surface to the corresponding point
51 //! on its approximate triangulation.
52 //! In many cases, algorithms do not need to work with the
53 //! exact representation of a surface. A triangular
54 //! representation induces simpler and more robust adjusting,
55 //! faster performances, and the results are as good.
56 //! This is a Transient class.
57 class Poly_Triangulation : public Standard_Transient
58 {
59   DEFINE_STANDARD_RTTIEXT(Poly_Triangulation, Standard_Transient)
60 public:
61
62   //! Constructs an empty triangulation.
63   Standard_EXPORT Poly_Triangulation();
64
65   //! Constructs a triangulation from a set of triangles.
66   //! The triangulation is initialized without a triangle or a node,
67   //! but capable of containing specified number of nodes and triangles.
68   //! @param theNbNodes     [in] number of nodes to allocate
69   //! @param theNbTriangles [in] number of triangles to allocate
70   //! @param theHasUVNodes  [in] indicates whether 2D nodes will be associated with 3D ones,
71   //!                            (i.e. to enable a 2D representation)
72   //! @param theHasNormals  [in] indicates whether normals will be given and associated with nodes
73   Standard_EXPORT Poly_Triangulation (const Standard_Integer theNbNodes,
74                                       const Standard_Integer theNbTriangles,
75                                       const Standard_Boolean theHasUVNodes,
76                                       const Standard_Boolean theHasNormals = false);
77
78   //! Constructs a triangulation from a set of triangles. The
79   //! triangulation is initialized with 3D points from Nodes and triangles
80   //! from Triangles.
81   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const Poly_Array1OfTriangle& Triangles);
82
83   //! Constructs a triangulation from a set of triangles. The
84   //! triangulation is initialized with 3D points from Nodes, 2D points from
85   //! UVNodes and triangles from Triangles, where
86   //! coordinates of a 2D point from UVNodes are the
87   //! (u, v) parameters of the corresponding 3D point
88   //! from Nodes on the surface approximated by the
89   //! constructed triangulation.
90   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const TColgp_Array1OfPnt2d& UVNodes, const Poly_Array1OfTriangle& Triangles);
91
92   //! Destructor
93   Standard_EXPORT virtual ~Poly_Triangulation();
94
95   //! Creates full copy of current triangulation
96   Standard_EXPORT virtual Handle(Poly_Triangulation) Copy() const;
97
98   //! Copy constructor for triangulation.
99   Standard_EXPORT Poly_Triangulation (const Handle(Poly_Triangulation)& theTriangulation);
100
101   //! Returns the deflection of this triangulation.
102   Standard_Real Deflection() const { return myDeflection; }
103
104   //! Sets the deflection of this triangulation to theDeflection.
105   //! See more on deflection in Polygon2D
106   void Deflection (const Standard_Real theDeflection) { myDeflection = theDeflection; }
107
108   //! Returns TRUE if triangulation has some geometry.
109   virtual Standard_Boolean HasGeometry() const { return !myNodes.IsEmpty() && !myTriangles.IsEmpty(); }
110
111   //! Returns the number of nodes for this triangulation.
112   Standard_Integer NbNodes() const { return myNodes.Length(); }
113
114   //! Returns the number of triangles for this triangulation.
115   Standard_Integer NbTriangles() const { return myTriangles.Length(); }
116
117   //! Returns Standard_True if 2D nodes are associated with 3D nodes for this triangulation.
118   Standard_Boolean HasUVNodes() const { return !myUVNodes.IsEmpty(); }
119
120   //! Returns Standard_True if nodal normals are defined.
121   Standard_Boolean HasNormals() const { return !myNormals.IsEmpty(); }
122
123   //! Returns a node at the given index.
124   gp_Pnt Node (Standard_Integer theIndex) const { return myNodes.Value (theIndex - 1); }
125
126   //! Sets a node coordinates.
127   void SetNode (Standard_Integer theIndex,
128                 const gp_Pnt& thePnt)
129   {
130     myNodes.SetValue (theIndex - 1, thePnt);
131   }
132
133   //! Returns UV-node at the given index.
134   gp_Pnt2d UVNode (Standard_Integer theIndex) const { return myUVNodes.Value (theIndex - 1); }
135
136   //! Sets an UV-node coordinates.
137   void SetUVNode (Standard_Integer theIndex,
138                   const gp_Pnt2d&  thePnt)
139   {
140     myUVNodes.SetValue (theIndex - 1, thePnt);
141   }
142
143   //! Returns triangle at the given index.
144   const Poly_Triangle& Triangle (Standard_Integer theIndex) const { return myTriangles.Value (theIndex); }
145
146   //! Sets a triangle.
147   void SetTriangle (Standard_Integer theIndex,
148                     const Poly_Triangle& theTriangle)
149   {
150     myTriangles.SetValue (theIndex, theTriangle);
151   }
152
153   //! Returns normal at the given index.
154   gp_Dir Normal (Standard_Integer theIndex) const
155   {
156     const gp_Vec3f& aNorm = myNormals.Value (theIndex - 1);
157     return gp_Dir (aNorm.x(), aNorm.y(), aNorm.z());
158   }
159
160   //! Returns normal at the given index.
161   void Normal (Standard_Integer theIndex,
162                gp_Vec3f& theVec3) const
163   {
164     theVec3 = myNormals.Value (theIndex - 1);
165   }
166
167   //! Changes normal at the given index.
168   void SetNormal (const Standard_Integer theIndex,
169                   const gp_Vec3f& theNormal)
170   {
171     myNormals.SetValue (theIndex - 1, theNormal);
172   }
173
174   //! Changes normal at the given index.
175   void SetNormal (const Standard_Integer theIndex,
176                   const gp_Dir& theNormal)
177   {
178     SetNormal (theIndex, gp_Vec3f (float(theNormal.X()),
179                                    float(theNormal.Y()),
180                                    float(theNormal.Z())));
181   }
182
183   //! Returns cached min - max range of triangulation data,
184   //! which is VOID by default (e.g, no cached information).
185   Standard_EXPORT const Bnd_Box& CachedMinMax() const;
186
187   //! Sets a cached min - max range of this triangulation.
188   //! The bounding box should exactly match actual range of triangulation data
189   //! without a gap or transformation, or otherwise undefined behavior will be observed.
190   //! Passing a VOID range invalidates the cache.
191   Standard_EXPORT void SetCachedMinMax (const Bnd_Box& theBox);
192
193   //! Returns TRUE if there is some cached min - max range of this triangulation.
194   Standard_EXPORT Standard_Boolean HasCachedMinMax() const { return myCachedMinMax != NULL; }
195
196   //! Updates cached min - max range of this triangulation with bounding box of nodal data.
197   void UpdateCachedMinMax()
198   {
199     Bnd_Box aBox;
200     MinMax (aBox, gp_Trsf(), true);
201     SetCachedMinMax (aBox);
202   }
203
204   //! Extends the passed box with bounding box of this triangulation.
205   //! Uses cached min - max range when available and:
206   //! - input transformation theTrsf has no rotation part;
207   //! - theIsAccurate is set to FALSE;
208   //! - no triangulation data available (e.g. it is deferred and not loaded).
209   //! @param theBox [in] [out] bounding box to extend by this triangulation
210   //! @param theTrsf [in] optional transformation
211   //! @param theIsAccurate [in] when FALSE, allows using a cached min - max range of this triangulation
212   //!                           even for non-identity transformation.
213   //! @return FALSE if there is no any data to extend the passed box (no both triangulation and cached min - max range).
214   Standard_EXPORT Standard_Boolean MinMax (Bnd_Box& theBox, const gp_Trsf& theTrsf, const bool theIsAccurate = false) const;
215
216   //! Dumps the content of me into the stream
217   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
218
219 public:
220
221   //! Returns TRUE if node positions are defined with double precision; TRUE by default.
222   bool IsDoublePrecision() const { return myNodes.IsDoublePrecision(); }
223
224   //! Set if node positions should be defined with double or single precision for 3D and UV nodes.
225   //! Raises exception if data was already allocated.
226   Standard_EXPORT void SetDoublePrecision (bool theIsDouble);
227
228   //! Method resizing internal arrays of nodes (synchronously for all attributes).
229   //! @param theNbNodes   [in] new number of nodes
230   //! @param theToCopyOld [in] copy old nodes into the new array
231   Standard_EXPORT void ResizeNodes (Standard_Integer theNbNodes,
232                                     Standard_Boolean theToCopyOld);
233
234   //! Method resizing an internal array of triangles.
235   //! @param theNbTriangles [in] new number of triangles
236   //! @param theToCopyOld   [in] copy old triangles into the new array
237   Standard_EXPORT void ResizeTriangles (Standard_Integer theNbTriangles,
238                                         Standard_Boolean theToCopyOld);
239
240   //! If an array for UV coordinates is not allocated yet, do it now.
241   Standard_EXPORT void AddUVNodes();
242
243   //! Deallocates the UV nodes array.
244   Standard_EXPORT void RemoveUVNodes();
245
246   //! If an array for normals is not allocated yet, do it now.
247   Standard_EXPORT void AddNormals();
248
249   //! Deallocates the Normals array.
250   Standard_EXPORT void RemoveNormals();
251
252   //! Compute smooth normals by averaging triangle normals.
253   Standard_EXPORT void ComputeNormals();
254
255 public:
256
257   //! Returns the table of 3D points for read-only access or NULL if nodes array is undefined.
258   //! Poly_Triangulation::Node() should be used instead when possible.
259   //! Returned object should not be used after Poly_Triangulation destruction.
260   Standard_EXPORT Handle(TColgp_HArray1OfPnt) MapNodeArray() const;
261
262   //! Returns the triangle array for read-only access or NULL if triangle array is undefined.
263   //! Poly_Triangulation::Triangle() should be used instead when possible.
264   //! Returned object should not be used after Poly_Triangulation destruction.
265   Standard_EXPORT Handle(Poly_HArray1OfTriangle) MapTriangleArray() const;
266
267   //! Returns the table of 2D nodes for read-only access or NULL if UV nodes array is undefined.
268   //! Poly_Triangulation::UVNode() should be used instead when possible.
269   //! Returned object should not be used after Poly_Triangulation destruction.
270   Standard_EXPORT Handle(TColgp_HArray1OfPnt2d) MapUVNodeArray() const;
271
272   //! Returns the table of per-vertex normals for read-only access or NULL if normals array is undefined.
273   //! Poly_Triangulation::Normal() should be used instead when possible.
274   //! Returned object should not be used after Poly_Triangulation destruction.
275   Standard_EXPORT Handle(TShort_HArray1OfShortReal) MapNormalArray() const;
276
277 public:
278
279   //! Returns an internal array of triangles.
280   //! Triangle()/SetTriangle() should be used instead in portable code.
281   Poly_Array1OfTriangle& InternalTriangles() { return myTriangles; }
282
283   //! Returns an internal array of nodes.
284   //! Node()/SetNode() should be used instead in portable code.
285   Poly_ArrayOfNodes& InternalNodes() { return myNodes; }
286
287   //! Returns an internal array of UV nodes.
288   //! UBNode()/SetUVNode() should be used instead in portable code.
289   Poly_ArrayOfUVNodes& InternalUVNodes() { return myUVNodes; }
290
291   //! Return an internal array of normals.
292   //! Normal()/SetNormal() should be used instead in portable code.
293   NCollection_Array1<gp_Vec3f>& InternalNormals() { return myNormals; }
294
295   Standard_DEPRECATED("Deprecated method, SetNormal() should be used instead")
296   Standard_EXPORT void SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals);
297
298   Standard_DEPRECATED("Deprecated method, Triangle() should be used instead")
299   const Poly_Array1OfTriangle& Triangles() const { return myTriangles; }
300
301   Standard_DEPRECATED("Deprecated method, SetTriangle() should be used instead")
302   Poly_Array1OfTriangle& ChangeTriangles() { return myTriangles; }
303
304   Standard_DEPRECATED("Deprecated method, SetTriangle() should be used instead")
305   Poly_Triangle& ChangeTriangle (const Standard_Integer theIndex) { return myTriangles.ChangeValue (theIndex); }
306
307 protected:
308
309   //! Clears cached min - max range saved previously.
310   Standard_EXPORT void unsetCachedMinMax();
311
312   //! Calculates bounding box of nodal data.
313   //! @param theTrsf [in] optional transformation.
314   Standard_EXPORT virtual Bnd_Box computeBoundingBox (const gp_Trsf& theTrsf) const;
315
316 protected:
317
318   Bnd_Box*                     myCachedMinMax;
319   Standard_Real                myDeflection;
320   Poly_ArrayOfNodes            myNodes;
321   Poly_Array1OfTriangle        myTriangles;
322   Poly_ArrayOfUVNodes          myUVNodes;
323   NCollection_Array1<gp_Vec3f> myNormals;
324
325 };
326
327 #endif // _Poly_Triangulation_HeaderFile