summaryrefslogtreecommitdiff
path: root/inc/Poly_CoherentTriangulation.hxx
blob: 765e3e5fd2d322c51f4d51b85c1e5e098c6ed4e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
// File:      Poly_CoherentTriangulation.hxx
// Created:   24.11.07 14:24
// Author:    Alexander GRIGORIEV
// Copyright: Open Cascade 2007


#ifndef Poly_CoherentTriangulation_HeaderFile
#define Poly_CoherentTriangulation_HeaderFile

#include <Handle_Poly_Triangulation.hxx>
#include <Poly_CoherentNode.hxx>
#include <Poly_CoherentTriangle.hxx>
#include <Poly_CoherentLink.hxx>
#include <NCollection_Vector.hxx>

class Handle_Poly_CoherentTriangulation;
class Poly_CoherentTriangulation;
template <class A> class NCollection_List;

typedef NCollection_Vector<Poly_CoherentTriangle>::Iterator
                                Poly_BaseIteratorOfCoherentTriangle;
typedef NCollection_Vector<Poly_CoherentNode>::Iterator
                                Poly_BaseIteratorOfCoherentNode;
typedef NCollection_Vector<Poly_CoherentLink>::Iterator
                                Poly_BaseIteratorOfCoherentLink;

/**
 * Triangulation structure that allows to:
 * <ul>
 * <li>Store the connectivity of each triangle with up to 3 neighbouring ones
 *     and with the corresponding 3rd nodes on them,</li>
 * <li>Store the connectivity of each node with all triangles that share this
 *     node</li>
 * <li>Add nodes and triangles to the structure,</li>
 * <li>Find all triangles sharing a single or a couple of nodes</li>
 * <li>Remove triangles from structure</li>
 * <li>Optionally create Links between pairs of nodes according to the current
 *     triangulation. 
 * <li>Convert from/to Poly_Triangulation structure.</li>
 * </ul>
 * This class is useful for algorithms that need to analyse and/or edit a
 * triangulated mesh -- for example for mesh refining. The connectivity model
 * follows the idea that all Triangles in a mesh should have coherent orientation
 * like on a surface of a solid body. Connections between more than 2 triangles
 * are not suppoorted.
 * @section Poly_CoherentTriangulation Architecture
 * The data types used in this structure are:
 * <ul>
 * <li><b>Poly_CoherentNode</b>: Inherits go_XYZ therefore provides the full
 *     public API of gp_XYZ. Contains references to all incident triangles. You
 *     can add new nodes but you cannot remove existing ones. However each node
 *     that has no referenced triangle is considered as "free" (use the method
 *     IsFreeNode() to check this). Free nodes are not available to further
 *     processing, particularly they are not exported in Poly_Triangulation.
 * </li>
 * <li><b>Poly_CoherentTriangle</b>: Main data type. Refers three Nodes, three
 *     connected Triangles, three opposite (connected) Nodes and three Links.
 *     If there is boundary then 1, 2 or 3 references to Triangles/connected
 *     Nodes/Links are assigned to NULL (for pointers) or -1 (for integer
 *     node index).
 *     <br>
 *     You can find a triangle by one node using its triangle iterator or by
 *     two nodes - creating a temporary Poly_CoherentLink and calling the method
 *     FindTriangle().
 *     <br>
 *     Triangles can be removed but they are never deleted from
 *     the containing array. Removed triangles have all nodes equal to -1. You
 *     can use the method IsEmpty() to check that.
 * </li>
 * <li><b>Poly_CoherentLink</b>: Auxiliary data type. Normally the array of
 *     Links is empty, because for many algorithms it is sufficient to define
 *     only Triangles. You can explicitly create the Links at least once,
 *     calling the method ComputeLinks(). Each Link is oriented couple of
 *     Poly_CoherentNode (directed to the ascending Node index). It refers
 *     two connected triangulated Nodes - on the left and on the right,
 *     therefore a Poly_CoherentLink instance refers the full set of nodes
 *     that constitute a couple of connected Triangles. A boundary Link has
 *     either the first (left) or the second (right) connected node index
 *     equal to -1.
 *     <br>
 *     When the array of Links is created, all subsequent calls to AddTriangle
 *     and RemoveTriangle try to preserve the connectivity Triangle-Link in
 *     addition to the connectivity Triangle-Triangle. Particularly, new Links
 *     are created by method AddTriangle() and existing ones are removed by
 *     method RemoveTriangle(), in each case whenever necessary.
 *     <br>
 *     Similarly to Poly_CoherentTriangle, a Link can be removed but not
 *     destroyed separately from others. Removed Link can be recogniosed using
 *     the method IsEmpty(). To destroy all Links, call the method ClearLinks(),
 *     this method also nullifies Link references in all Triangles. 
 * </li>
 * All objects (except for free Nodes and empty Triangles and Links) can be
 * visited by the corresponding Iterator. Direct access is provided only for
 * Nodes (needed to resolve Node indexed commonly used as reference). Triangles
 * and Links can be retrieved by their index only internally, the public API
 * provides only references or pointers to C++ objects. If you need a direct
 * access to Triangles and Links, you can subclass Poly_CoherentTriangulation
 * and use the protected API for your needs.
 * <br>
 * Memory management: All data objects are stored in NCollection_Vector
 * containers that prove to be efficient for the performance. In addition
 * references to triangles are stored in ring lists, with an instance of such
 * list per Poly_CoherentNode. These lists are allocated in a memory allocator
 * that is provided in the constructor of Poly_CoherentTriangulation. By default
 * the standard OCCT allocator (aka NCollection_BaseAllocator) is used. But if
 * you need to increase the performance you can use NCollection_IncAllocator
 * instead.
 * </ul>
 */

class Poly_CoherentTriangulation : public Standard_Transient
{
 public:
  /**
   * Subclass Iterator - allows to iterate all triangles skipping those that
   * have been removed.
   */
  class IteratorOfTriangle : public Poly_BaseIteratorOfCoherentTriangle
  {
  public:
    //! Constructor
    Standard_EXPORT IteratorOfTriangle
                          (const Handle_Poly_CoherentTriangulation& theTri);
    //! Make step
    Standard_EXPORT virtual void Next ();
  };

  /**
   * Subclass Iterator - allows to iterate all nodes skipping the free ones.
   */
  class IteratorOfNode : public Poly_BaseIteratorOfCoherentNode
  {
  public:
    //! Constructor
    Standard_EXPORT IteratorOfNode
                        (const Handle_Poly_CoherentTriangulation& theTri);
    //! Make step
    Standard_EXPORT virtual void Next ();
  };

  /**
   * Subclass Iterator - allows to iterate all links skipping invalid ones.
   */
  class IteratorOfLink : public Poly_BaseIteratorOfCoherentLink
  {
  public:
    //! Constructor
    Standard_EXPORT IteratorOfLink
                        (const Handle_Poly_CoherentTriangulation& theTri);
    //! Make step
    Standard_EXPORT virtual void Next ();
  };

  //! Couple of integer indices (used in RemoveDegenerated()).
  struct TwoIntegers
  {
    Standard_Integer myValue[2];
    TwoIntegers() {}
    TwoIntegers(Standard_Integer i0, Standard_Integer i1) {
      myValue[0] = i0; myValue[1] = i1;
    }
  };

 public:
  // ---------- PUBLIC METHODS ----------


  /**
   * Empty constructor.
   */
  Standard_EXPORT Poly_CoherentTriangulation
                (const Handle_NCollection_BaseAllocator& theAlloc = 0L);

  /**
   * Constructor. It does not create Links, you should call ComputeLinks
   * following this constructor if you need these links.
   */
  Standard_EXPORT Poly_CoherentTriangulation
                (const Handle_Poly_Triangulation&        theTriangulation,
                 const Handle_NCollection_BaseAllocator& theAlloc = 0L);

  /**
   * Destructor.
   */
  Standard_EXPORT virtual ~Poly_CoherentTriangulation ();

  /**
   * Create an instance of Poly_Triangulation from this object.
   */
  Standard_EXPORT Handle_Poly_Triangulation
                                   GetTriangulation () const;

  /**
   * Find and remove degenerated triangles in Triangulation.
   * @param theTol
   *   Tolerance for the degeneration case. If any two nodes of a triangle have
   *   the distance less than this tolerance, this triangle is considered
   *   degenerated and therefore removed by this method.
   * @param pLstRemovedNode
   *   Optional parameter. If defined, then it will receive the list of arrays
   *   where the first number is the index of removed node and the seond -
   *   the index of remaining node to which the mesh was reconnected.
   */
  Standard_EXPORT Standard_Boolean RemoveDegenerated
                        (const Standard_Real             theTol,
                         NCollection_List<TwoIntegers> * pLstRemovedNode = 0L);

  /**
   * Create a list of free nodes. These nodes may appear as a result of any
   * custom mesh decimation or RemoveDegenerated() call. This analysis is
   * necessary if you support additional data structures based on the
   * triangulation (e.g., edges on the surface boundary).
   * @param lstNodes
   *   <tt>[out]</tt> List that receives the indices of free nodes.
   */
  Standard_EXPORT Standard_Boolean GetFreeNodes
                        (NCollection_List<Standard_Integer>& lstNodes) const;

  /**
   * Query the index of the last node in the triangulation
   */
  inline Standard_Integer          MaxNode      () const
  { return myNodes.Length() - 1; }

  /**
   * Query the index of the last triangle in the triangulation
   */
  inline Standard_Integer          MaxTriangle  () const
  { return myTriangles.Length() - 1; }

  /**
   * Set the Deflection value as the parameter of the given triangulation.
   */
  inline void                      SetDeflection(const Standard_Real theDefl)
  { myDeflection = theDefl; }

  /**
   * Query the Deflection parameter (default value 0. -- if never initialized)
   */
  inline Standard_Real             Deflection   () const
  { return myDeflection; }

  /**
   * Initialize a node
   * @param thePoint
   *   3D Coordinates of the node.
   * @param iN
   *   Index of the node. If negative (default), the node is added to the
   *   end of the current array of nodes.
   * @return
   *   Index of the added node.
   */
  Standard_EXPORT Standard_Integer SetNode      (const gp_XYZ&          thePnt,
                                                 const Standard_Integer iN= -1);

  /**
   * Get the node at the given index 'i'.
   */
  inline const Poly_CoherentNode&  Node         (const Standard_Integer i) const
  { return myNodes.Value(i); }

  /**
   * Get the node at the given index 'i'.
   */
  inline Poly_CoherentNode&        ChangeNode   (const Standard_Integer i) 
  { return myNodes.ChangeValue(i); }

  /**
   * Query the total number of active nodes (i.e. nodes used by 1 or more
   * triangles)
   */
  Standard_EXPORT Standard_Integer NNodes       () const;

  /**
   * Get the triangle at the given index 'i'.
   */
  inline const Poly_CoherentTriangle&  Triangle (const Standard_Integer i) const
  { return myTriangles.Value(i); }

  /**
   * Query the total number of active triangles (i.e. triangles that refer
   * nodes, non-empty ones)
   */
  Standard_EXPORT Standard_Integer NTriangles   () const;

  /**
   * Query the total number of active Links.
   */
  Standard_EXPORT Standard_Integer NLinks       () const;  

  /**
   * Removal of a single triangle from the triangulation.
   */
  Standard_EXPORT Standard_Boolean RemoveTriangle(Poly_CoherentTriangle& theTr);

  /**
   * Removal of a single link from the triangulation.
   */
  Standard_EXPORT void             RemoveLink   (Poly_CoherentLink& theLink);

  /**
   * Add a triangle to the triangulation.
   * @return
   *   Pointer to the added triangle instance or NULL if an error occurred.
   */
  Standard_EXPORT Poly_CoherentTriangle *
                                   AddTriangle  (const Standard_Integer iNode0,
                                                 const Standard_Integer iNode1,
                                                 const Standard_Integer iNode2);

  /**
   * Replace nodes in the given triangle.
   * @return
   *   True if operation succeeded.
   */
  Standard_EXPORT Standard_Boolean ReplaceNodes
                    (Poly_CoherentTriangle& theTriangle,
                     const Standard_Integer iNode0,
                     const Standard_Integer iNode1,
                     const Standard_Integer iNode2);

  /**
   * Add a single link to triangulation, based on a triangle and its side index.
   * This method does not check for coincidence with already present links.
   * @param theTri
   *   Triangle that contains the link to be added.
   * @param theConn
   *   Index of the side (i.e., 0, 1 0r 2) defining the added link.
   */
  Standard_EXPORT Poly_CoherentLink *
                                   AddLink (const Poly_CoherentTriangle& theTri,
                                            const Standard_Integer    theConn);

  /**
   * Find one or two triangles that share the given couple of nodes.
   * @param theLink
   *   Link (in fact, just a couple of nodes) on which the triangle is
   *   searched.
   * @param pTri
   *   <tt>[out]</tt> Array of two pointers to triangle. pTri[0] stores the
   *   triangle to the left of the link, while pTri[1] stores the one to the
   *   right of the link.
   * @return
   *   True if at least one triangle is found and output as pTri.
   */ 
  Standard_EXPORT Standard_Boolean FindTriangle
                                (const Poly_CoherentLink&       theLink,
                                 const Poly_CoherentTriangle*   pTri[2]) const;

  /**
   * (Re)Calculate all links in this Triangulation.
   */
  Standard_EXPORT Standard_Integer ComputeLinks ();

  /**
   * Clear all Links data from the Triangulation data.
   */
  Standard_EXPORT void             ClearLinks   ();

  /**
   * Query the allocator of elements, this allocator can be used for other
   * objects 
   */
  inline const Handle_NCollection_BaseAllocator&
                                Allocator       () const
  {
    return myAlloc;
  }
  /**
   * Create a copy of this Triangulation, using the given allocator.
   */
  Standard_EXPORT Handle_Poly_CoherentTriangulation  Clone
                (const Handle_NCollection_BaseAllocator& theAlloc) const;

  /**
   * Debugging output.
   */
  Standard_EXPORT void             Dump         (Standard_OStream&) const;

 protected:
  // ---------- PROTECTED METHODS ----------



 protected:
  // ---------- PROTECTED FIELDS ----------

  NCollection_Vector<Poly_CoherentTriangle> myTriangles;
  NCollection_Vector<Poly_CoherentNode>     myNodes;
  NCollection_Vector<Poly_CoherentLink>     myLinks;
  Handle_NCollection_BaseAllocator          myAlloc;
  Standard_Real                             myDeflection;

 public:
// Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTI (Poly_CoherentTriangulation)

  friend class IteratorOfTriangle;
  friend class IteratorOfNode;
  friend class IteratorOfLink;
};

#include <Handle_Poly_CoherentTriangulation.hxx>

#endif