Point Cloud Library (PCL)  1.9.1-dev
opennurbs_mesh.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 #if !defined(OPENNURBS_MESH_INC_)
18 #define OPENNURBS_MESH_INC_
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 //
22 // Class ON_Mesh
23 //
24 class ON_CLASS ON_MeshParameters
25 {
26  // surface meshing perameters
27 public:
28 
30  {
31  // All of these enum values must be in the range 0-255 because
32  // unsigned chars are use for storage in some locations.
33  unset_mesh_style = 0,
34  render_mesh_fast = 1, // Use ON_MeshParameters::FastRenderMesh
35  render_mesh_quality = 2, // Use ON_MeshParameters::QualityRenderMesh
36  // 3 - 8 reserved for future predefined render mesh styles
37  render_mesh_custom = 9,// Use ON_3dmSettings::m_CustomRenderMeshSettings
38  render_mesh_per_object = 10 // Use ON_Object::GetMeshParameters().
39  };
40 
41  /*
42  Description:
43  Parameters that create render meshes where meshing
44  speed is prefered over mesh quality.
45  */
46  static
48 
49  /*
50  Description:
51  Parameters that create render meshes where mesh quality
52  is prefered over meshing speed.
53  */
54  static
56 
57  /*
58  Description:
59  Get a value to use for tolerance based on the relative_tolerance
60  and actual size.
61  Parameters:
62  relative_tolerance - [in]
63  See m_relative_tolerance field
64  actual_size - [in]
65  Diagonal ov object bounding box or some similar measure of
66  an object's 3d size.
67  Returns:
68  A value that can be used for m_tolerance if no
69  user specified value is available.
70  */
71  static
72  double Tolerance( double relative_tolerance, double actual_size );
73 
74  /*
75  Description:
76  Get a value to use for minimum edge length base on max_edge_length
77  and tolerance settings.
78  Parameters:
79  max_edge_length - [in]
80  3d maximum edge length used to create mesh.
81  tolerance - [in]
82  3d distance tolerance used to create mesh.
83  Returns:
84  A value that can be used for m_min_edge_length if no
85  user specified value is available.
86  */
87  static
88  double MinEdgeLength( double max_edge_length, double tolerance );
89 
92  // C++ default works fine // ON_MeshParameters(const ON_MeshParameters& );
93  // C++ default works fine // ON_MeshParameters& operator=(const ON_MeshParameters&);
94 
95  bool operator!=(const ON_MeshParameters&) const;
96  bool operator==(const ON_MeshParameters&) const;
97 
98  // compares with mesh's mesh parameters
99  bool operator==(const ON_Mesh&) const;
100  bool operator!=(const ON_Mesh&) const;
101 
102  void Dump( ON_TextLog& test_log ) const;
103 
104  void Default();
105 
106  /*
107  Description:
108  Tool for provding a simple slider interface.
109  Parameters:
110  density - [in] 0.0 <= density <= 1.0
111  0 quickly creates coarse meshes.
112  1 creates accurate meshes but takes lots of time.
113  */
114  void Set(
115  double density,
116  double min_edge_length = 0.0001
117  );
118 
119  /*
120  Description:
121  Sets the meshing parameters to ON_MeshParameters::FastRenderMesh.
122  */
123  ON_DEPRECATED
124  void JaggedAndFasterMeshParameters();
125 
126  /*
127  Description:
128  Sets the meshing parameters to ON_MeshParameters::QualityRenderMesh.
129  */
130  ON_DEPRECATED
131  void SmoothAndSlowerMeshParameters();
132 
133  /*
134  Description:
135  Sets the meshing parameters to create the default
136  analysis mesh.
137  */
138  void DefaultAnalysisMeshParameters();
139 
140  // Compare() ignores weld and curvature settings
141  // Ignores m_min_tolerance setting.
142  int Compare( const ON_MeshParameters& ) const;
143 
144  /*
145  Description:
146  Compares all meshing parameters that control mesh geometry.
147  Does not compare m_bCustomSettings, m_bComputeCurvature,
148  m_bDoublePrecision, m_min_tolerance, and m_texture_range.
149  */
150  int CompareGeometrySettings( const ON_MeshParameters& ) const;
151 
152 
153  bool Write( ON_BinaryArchive& ) const;
154  bool Read( ON_BinaryArchive& );
155  ON__UINT32 DataCRC(ON__UINT32) const;
156 
157 
158  // Meshing happens in two stages. The first stage creates a
159  // rectangular grid. The second stage refines the grid until
160  // the mesh meets all meshing requirements. The third stage
161  // combines coincident vertices if the resulting mesh is a composite.
162 
163  bool m_bCustomSettings; // false - if these settings were used to create
164  // a mesh and the app settings don't match,
165  // then remesh the object using the app
166  // settings.
167  // true - these settings are customized for a
168  // particular object - ignore app mesh
169  // settings.
170 
171  bool m_bComputeCurvature; // false - (default) - ON_Mesh::m_K[] not computed
172  // true - ON_Mesh::m_K[] computed
173 
174  bool m_bSimplePlanes; // false - (default) planar surfaces are meshed
175  // using the controls below.
176  // true - planar surfaces are meshed using
177  // minimal number of triangles and
178  // aspect/edge controls are ignored.
179 
180  bool m_bRefine; // false - skip stage 2
181  // true - (default) do stage 2
182 
183  bool m_bJaggedSeams; // false - (default) edges of meshes of joined
184  // b-rep faces match with no gaps or
185  // "T" joints.
186  // true - faces in b-reps are meshed independently.
187  // This is faster but results in gaps and
188  // "T" joints along seams between faces.
189 
190  bool m_bDoublePrecision; // false - (default) the mesh vertices will be
191  // float precision values in the m_V[] array.
192  // true - The mesh vertices will be double precision
193  // values in the DoublePrecisionVertices()
194  // array. Float precision values will also
195  // be returned in the m_V[] array.
196  bool m_bCustomSettingsEnabled; // false - if these settings should be ignored
197  // when used as per object custom render mesh
198  // settings.
199  // true - ignore these settings.
200  unsigned char m_mesher; // 0 = slow mesher, 1 = fast mesher
201 
202  int m_texture_range; // 1: normalized
203  //
204  // each face has a normalized texture range
205  // [0,1]x[0,1].
206  //
207  // 2: packed normalized (default)
208  //
209  // each face in a polysurface is assigned
210  // a texture range that is a subrectangle
211  // of [0,1]x[0,1]. The subrectangles are
212  // mutually disjoint and packed into
213  // into [0,1]x[0,1] in a way that minimizes
214  // distortion and maximizes the coverage
215  // of [0,1]x[0,1]. (This texture style
216  // is suitable for creating texture maps
217  // with popular 3D painting programs.)
218 
219 private:
220  unsigned int m_reserved2;
221 public:
222 
223  // These controls are used in both stages
224 
225  double m_tolerance; // maximum distance from center of edge to surface
226 
227 
228  double m_relative_tolerance; // If 0 < m_relative_tolerance < 1,
229  double m_min_tolerance; // then the maximum distance from the
230  // center of an edge to the surface will
231  // be <= T, where T is the larger of
232  // (m_min_tolerance,d*m_relative_tolerance),
233  // where d is an esimate of the size of the
234  // object being meshed.
235 
236 
237  double m_min_edge_length; // edges shorter than m_min_edge_length will
238  // not be split even if the do not meet other
239  // meshing requirements
240 
241  double m_max_edge_length; // edges longer than m_max_edge_length will
242  // be split even when they meet all other
243  // meshing requirements
244 
245  // These controls are used during stage 1 to generate the grid
246  double m_grid_aspect_ratio; // desired aspect ratio of quads in grid
247  // 0.0 = any aspect ratio is acceptable
248  // values >0 and < sqrt(2) are treated as sqrt(2)
249  int m_grid_min_count; // minimum number of quads in initial grid
250  int m_grid_max_count; // desired masimum number of quads in initial grid
251  double m_grid_angle; // (in radians) maximum angle between surface
252  // normal evaluated at adjacent vertices.
253  // 0.0 is treated as pi.
254  double m_grid_amplification; // The parameters above generate a grid.
255  // If you want fewer quads, set m_grid_amplification
256  // to a value < 1. If you want more quads,
257  // set m_grid_amplification to a value > 1.
258  // default = 1 and values <= 0 are treated as 1.
259 
260  // These controls are used during stage 2 to refine the grid
261  double m_refine_angle; // (in radians) maximum angle in radians between
262  // surface normal evaluated at adjacent vertices.
263 
264  // These controls are used during stage 3
265  int m_face_type; // 0 = mixed triangle and quads
266  // 1 = all triangles
267  // 2 = all quads
268 private:
269  unsigned int m_reserved3;
270 };
271 
272 class ON_CLASS ON_MeshCurvatureStats
273 {
274 public:
278  ON_MeshCurvatureStats& operator=(const ON_MeshCurvatureStats&);
279 
280  void Destroy();
281  void EmergencyDestroy();
282 
283  bool Set( ON::curvature_style,
284  int, // Kcount,
285  const ON_SurfaceCurvature*, // K[]
286  const ON_3fVector*, // N[] surface normals needed for normal sectional curvatures
287  double = 0.0 // if > 0, value is used for "infinity"
288  );
289 
290  bool Write( ON_BinaryArchive& ) const;
291  bool Read( ON_BinaryArchive& );
292 
293  ON::curvature_style m_style;
294 
295  double m_infinity; // curvature values >= this are considered infinite
296  // and not used to compute the m_average or m_adev
297  int m_count_infinite; // number of "infinte" values
298  int m_count; // count of "finite" values
299  double m_mode; // mode of "finite" values
300  double m_average; // average of "finite" values
301  double m_adev; // average deviation of "finite" values
302 
304 };
305 
306 ///////////////////////////////////////////////////////////////////////////////
307 //
308 // Class ON_MeshTopology
309 //
310 
312 {
313  // m_tope_count = number of topological edges that begin or
314  // end at this topological vertex.
316 
317  // m_topei[] is an array of length m_tope_count with the indices
318  // of the topological edges that begin or end at this topological
319  // vertex. Generally, these edges are listed in no particular
320  // order. If you want the edges listed "radially", then call
321  // ON_MeshTopology::SortVertexEdges.
322  const int* m_topei;
323 
324  // m_v_count = number of ON_Mesh vertices that correspond to
325  // this topological vertex.
327 
328  // m_vi[] is an array of length m_v_count with the indices of the
329  // ON_Mesh vertices that correspond to this topological vertex.
330  const int* m_vi;
331 };
332 
334 {
335  // m_topvi[] = indices of the topological verteices where the
336  // edge begins and ends.
337  int m_topvi[2];
338 
339  // m_topf_count = number of topological faces tat share this topological edge
341 
342  // m_topfi[] is an array of length m_topf_count with the indices of the
343  // topological faces that share this topological edge.
344  const int* m_topfi;
345 };
346 
347 struct ON_CLASS ON_MeshTopologyFace
348 {
349  /*
350  m_topei[] = indices of the topological edges that bound the face.
351  If m_topei[2] = m_topei[3], then the face is a triangle, otherwise
352  the face is a quad.
353 
354  NOTE WELL:
355  The topological edge with index m_topei[k] ENDS at the
356  vertex corresponding to ON_MeshFace.vi[k]. So, ...
357 
358  If the face is a quad, (ON_MeshFace.vi[2]!=ON_MeshFace.vi[3]),
359  the topological edge with index m_topei[0] STARTS at
360  ON_MeshFace.vi[3] and ENDS at ON_MeshFace.vi[0],
361  the topological edge with index m_topei[1] STARTS at
362  ON_MeshFace.vi[0] and ENDS at ON_MeshFace.vi[1],
363  the topological edge with index m_topei[2] STARTS at
364  ON_MeshFace.vi[1] and ENDS at ON_MeshFace.vi[2], and
365  the topological edge with index m_topei[3] STARTS at
366  ON_MeshFace.vi[0] and ENDS at ON_MeshFace.vi[1],
367 
368  If the face is a triangle, (ON_MeshFace.vi[2]==ON_MeshFace.vi[3]),
369  the topological edge with index m_topei[0] STARTS at
370  ON_MeshFace.vi[2] and ENDS at ON_MeshFace.vi[0],
371  the topological edge with index m_topei[1] STARTS at
372  ON_MeshFace.vi[0] and ENDS at ON_MeshFace.vi[1],
373  the topological edge with index m_topei[2] STARTS at
374  ON_MeshFace.vi[1] and ENDS at ON_MeshFace.vi[2].
375  */
376  int m_topei[4];
377 
378  /*
379  If m_reve[i] is 0, then the orientation of the edge matches the
380  orientation of the face. If m_reve[i] is 1, then the orientation
381  of the edge is opposite that of the face.
382  */
383  char m_reve[4];
384 
385  /*
386  Description:
387  A topological mesh face is a valid triangle if m_topei[0],
388  m_topei[1], m_topei[2] are distinct edges and
389  m_topei[3]=m_topei[2].
390  Returns:
391  True if face is a triangle.
392  */
393  bool IsTriangle() const;
394 
395  /*
396  Description:
397  A topological mesh face is a valid quad if m_topei[0],
398  m_topei[1], m_topei[2], and m_topei[3] are distinct edges.
399  Returns:
400  True if face is a quad.
401  */
402  bool IsQuad() const;
403 
404  /*
405  Description:
406  A topological mesh face is valid if m_topei[0], m_topei[1],
407  and m_topei[2] are mutually distinct, and m_topei[3] is
408  either equal to m_topei[2] or mutually distinct from the
409  first three indices.
410  Returns:
411  True if face is valid.
412  */
413  bool IsValid( ) const;
414 };
415 
416 class ON_CLASS ON_MeshFace
417 {
418 public:
419  int vi[4]; // vertex index - vi[2]==vi[3] for tirangles
420 
421  /*
422  Returns:
423  True if vi[2] == vi[3];
424  Remarks:
425  Assumes the face is valid.
426  */
427  bool IsTriangle() const;
428 
429  /*
430  Returns:
431  True if vi[2] != vi[3];
432  Remarks:
433  Assumes the face is valid.
434  */
435  bool IsQuad() const;
436 
437  /*
438  Description:
439  Determine if a face is valid by checking that the vertices
440  are distinct.
441  Parameters:
442  mesh_vertex_count - [in]
443  number of vertices in the mesh
444  V - [in]
445  optional array of mesh_vertex_count vertex locations.
446  Returns:
447  true
448  The face is valid.
449  false
450  The face is not valid. It may be possible to repair the
451  face by calling ON_MeshFace::Repair().
452  */
453  bool IsValid(
454  int mesh_vertex_count
455  ) const;
456  bool IsValid(
457  int mesh_vertex_count,
458  const ON_3fPoint* V
459  ) const;
460  bool IsValid(
461  int mesh_vertex_count,
462  const ON_3dPoint* V
463  ) const;
464 
465  /*
466  Description:
467  Reverses the order of the vertices in v[].
468  vi[0] is not changed.
469  */
470  void Flip();
471 
472  /*
473  Description:
474  If IsValid() returns false, then you can use Repair()
475  to attempt to create a valid triangle.
476  Parameters:
477  mesh_vertex_count - [in]
478  number of vertices in the mesh
479  V - [in]
480  optional array of mesh_vertex_count vertex locations.
481  Returns:
482  true
483  repair was successful and v[0], v[1], vi[2] have distinct valid
484  values and v[2] == v[3].
485  false
486  this face's vi[] values cannot be repaired
487  */
488  bool Repair(
489  int mesh_vertex_count
490  );
491  bool Repair(
492  int mesh_vertex_count,
493  const ON_3fPoint* V
494  );
495  bool Repair(
496  int mesh_vertex_count,
497  const ON_3dPoint* V
498  );
499 
500  /*
501  Description:
502  Compute the face normal
503  Parameters:
504  dV - [in] double precision vertex array for the mesh
505  fV - [in] float precision vertex array for the mesh
506  FN - [out] face normal
507  Returns:
508  true if FN is valid.
509  */
510  bool ComputeFaceNormal( const ON_3dPoint* dV, ON_3dVector& FN ) const;
511  bool ComputeFaceNormal( const ON_3fPoint* fV, ON_3dVector& FN ) const;
512 };
513 
515 {
516  int vi[2]; // vertex indices
517  int fi; // mesh m_F[] array face index
518  unsigned char side; // edge connects mesh m_V[m_F[fi].vi[side]] and m_V[m_F[fi].vi[(side+1)%4]]
519  unsigned char dir; // 0 = counterclockwise, 1 = clockwise (reversed)
520  unsigned short value; // Set to zero by ON_Mesh::GetFaceSideList(). Can be used as needed.
521 };
522 
523 
524 /*
525 Description:
526  Sort the sides[] array of ON_MeshFaceSide structs in dictionary
527  order by "vi[0]", "vi[1]", "fi", and "side" values.
528 Paramters:
529  sides_count - [in]
530  number of elements in the sides[] array.
531  sides - [in/out]
532 Remarks:
533  The function is thread safe.
534 */
535 ON_DECL
536 void ON_SortMeshFaceSidesByVertexIndex(
537  int sides_count,
538  struct ON_MeshFaceSide* sides
539  );
540 
542 {
543  // ON_Mesh faces with indices fi[0] <= i < fi[1] reference
544  // vertices with indices vi[0] <= j < vi[1].
545  int vi[2]; // subinterval of mesh m_V[] array
546  int fi[2]; // subinterval of mesh m_F[] array
547  int vertex_count; // = vi[1] - vi[0];
548  int triangle_count; // tris + 2*quads >= fi[1] - fi[0]
549 };
550 
551 #if defined(ON_DLL_TEMPLATE)
552 // This stuff is here because of a limitation in the way Microsoft
553 // handles templates and DLLs. See Microsoft's knowledge base
554 // article ID Q168958 for details.
555 #pragma warning( push )
556 #pragma warning( disable : 4231 )
557 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_MeshFace>;
558 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_MeshTopologyVertex>;
559 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_MeshTopologyEdge>;
560 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_MeshTopologyFace>;
561 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<struct ON_MeshPart>;
562 #pragma warning( pop )
563 #endif
564 
565 class ON_CLASS ON_MeshTopology
566 {
567  // A mesh topology class is always associated with an ON_Mesh
568  // and can be retrieved by calling ON_Mesh::Topology()
569 public:
570  ON_MeshTopology();
571  ~ON_MeshTopology();
572 
573  bool IsValid() const;
574 
575  void Dump( ON_TextLog& ) const;
576 
577  //////////
578  // The parent ON_Mesh geometry used to compute this mesh topology.
579  const ON_Mesh* m_mesh;
580 
581  //////////
582  // number of topoligical vertices (<= m_mesh.VertexCount())
583  int TopVertexCount() const;
584 
585  //////////
586  // number of topoligical edges
587  int TopEdgeCount() const;
588 
589  //////////
590  // number of topoligical faces (same as m_mesh.FaceCount())
591  int TopFaceCount() const;
592 
593  /*
594  Description:
595  Get a vertex reference to a mesh vertex index.
596  Parameters:
597  ci - [in] component index with type mesh_vertex or meshtop_vertex.
598  Returns:
599  a reference to the vertex
600  */
601  class ON_MeshVertexRef VertexRef(ON_COMPONENT_INDEX ci) const;
602 
603  class ON_MeshVertexRef VertexRef(int topv_index) const;
604 
605  /*
606  Description:
607  Get an edge reference.
608  Parameters:
609  ci - [in] component index with type meshtop_edge.
610  Returns:
611  a reference to the edge
612  */
613  class ON_MeshEdgeRef EdgeRef(ON_COMPONENT_INDEX ci) const;
614 
615  class ON_MeshEdgeRef EdgeRef(int tope_index) const;
616 
617  /*
618  Description:
619  Get a face reference from a mesh face index.
620  Parameters:
621  ci - [in] component index with type mesh_face.
622  Returns:
623  a reference to the face.
624  Remarks:
625  The OM_Mesh.m_F[] and ON_MeshTopology.m_topf[] arrays
626  are parallel arrays; corresponding faces have identical
627  indices.
628  */
629  class ON_MeshFaceRef FaceRef(ON_COMPONENT_INDEX ci) const;
630 
631  class ON_MeshFaceRef FaceRef(int topf_index) const;
632 
633 
634  /*
635  Description:
636  Get the 3d point location of a vertex.
637  Parameters:
638  topv_index - [in];
639  Returns:
640  Location of vertex.
641  */
642  ON_3fPoint TopVertexPoint(
643  int topv_index
644  ) const;
645 
646  /*
647  Description:
648  Get the 3d line along an edge.
649  Parameters:
650  tope_index - [in];
651  Returns:
652  Line along edge. If input is not valid,
653  the line.from and to are ON_UNSET_POINT
654  */
655  ON_Line TopEdgeLine(
656  int tope_index
657  ) const;
658 
659  ////////
660  // returns index of edge that connects topological vertices
661  // returns -1 if no edge is found.
662  int TopEdge(
663  int vtopi0,
664  int vtopi1 // ON_MeshTopology vertex topology indices
665  ) const;
666 
667  ////////
668  // returns ON_MeshTopology vertex topology index of a face
669  // corner. The face is triangle iv TopFaceVertex(2) = TopFaceVertex(3)
670  bool GetTopFaceVertices(
671  int topfi, // ON_MeshTopology face topology index (= ON_Mesh face index)
672  int topvi[4] // ON_MeshTopology vertex indices returned here
673  ) const;
674 
675  /*
676  Description:
677  Sort the m_topei[] list of a mesh topology vertex so that
678  the edges are in radial order. The "const" is a white
679  lie to make this function easier to call.
680  Parameter:
681  topvi - [in] index of vertex in m_topv[] array.
682  Remarks:
683  A nonmanifold edge is treated as a boundary edge with respect
684  to sorting. If any boundary or nonmanifold edges end at the
685  vertex, then the first edge will be a boundary or nonmanifold
686  edge.
687  */
688  bool SortVertexEdges( int topvi ) const;
689 
690  /*
691  Description:
692  Sort the m_topei[] list of every mesh topology vertex so
693  that the edges are in radial order. The "const" is a white
694  lie to make this function easier to call.
695  Remarks:
696  Same as
697  for ( int topvi = 0; topvi < m_topv.Count(); topvi++ )
698  SortVertexEdges(topvi);
699  */
700  bool SortVertexEdges() const;
701 
702  /*
703  Description:
704  Returns true if the topological vertex is hidden.
705  Parameters:
706  topvi - [in] mesh topology vertex index.
707  Returns:
708  True if mesh topology vertex is hidden.
709  Remarks:
710  The mesh topology vertex is hidden if and only if
711  all the ON_Mesh vertices it represents is hidden.
712  */
713  bool TopVertexIsHidden( int topvi ) const;
714 
715  /*
716  Description:
717  Returns true if the topological edge is hidden.
718  Parameters:
719  topei - [in] mesh topology edge index.
720  Returns:
721  True if mesh topology edge is hidden.
722  Remarks:
723  The mesh topology edge is hidden if and only if
724  either of its mesh topology vertices is hidden.
725  */
726  bool TopEdgeIsHidden( int topei ) const;
727 
728  /*
729  Description:
730  Returns true if the topological face is hidden.
731  Parameters:
732  topfi - [in] mesh topology face index.
733  Returns:
734  True if mesh topology face is hidden.
735  Remarks:
736  The mesh topology face is hidden if and only if
737  any of its mesh topology edges are hidden.
738  */
739  bool TopFaceIsHidden( int topfi ) const;
740 
741  //////////
742  // m_topv_map[] has length m_mesh.VertexCount() and
743  // m_topv[m_topv_map[vi]] is the topological mesh vertex that is assocated
744  // the with the mesh vertex m_mesh.m_V[vi].
746 
747  ////////////
748  // Array of topological mesh vertices. See the comments in the definition
749  // of ON_MeshTopologyVertex for details.
751 
752  ////////////
753  // Array of topological mesh edges. See the comments in the definition
754  // of ON_MeshTopologyEdge for details.
756 
757  ////////////
758  // Array of topological mesh faces. The topological face
759  // m_topf[fi] corresponds to the mesh face ON_Mesh.m_F[fi].
760  // See the comments in the definition of ON_MeshTopologyFace
761  // for details. To get the indices of the mesh topology
762  // vertices at the face corners use
763  // topvi = m_topv_map[m_mesh.m_F[fi].vi[n]]
765 
766  /*
767  Description:
768  Expert user function for efficiently getting the
769  integer arrays used by the ON_MeshTopologyVertex
770  and ON_MeshTopologyEdge classes.
771  Parameters:
772  count - [in] number of integers in array
773  Returns:
774  pointer to integer array. The array memory
775  will be freed by ~ON_MeshTopology()
776  */
777  int* GetIntArray(int count);
778 
779 private:
780  friend class ON_Mesh;
781 
782  bool Create();
783  void Destroy();
784  void EmergencyDestroy();
785 
786  // efficient workspaces for
787  struct memchunk
788  {
789  struct memchunk* next;
790  } *m_memchunk;
791 
792  // NOTE: this field is a bool with valid values of 0 and 1.
793  volatile int m_b32IsValid; // sizeof(m_bIsValid) must be 4 - it is used in sleep locks.
794  // 0: Not Valid
795  // 1: Valid
796  // -1: Sleep locked - ON_Mesh::Topology() calculation is in progress
797  int WaitUntilReady(int sleep_value) const; // waits until m_b32IsValid >= 0
798 
799 private:
800  // no implementation
802  ON_MeshTopology& operator=(const ON_MeshTopology&);
803 };
804 
806 {
807  // Number of N-gon corners (N >= 3)
808  int N;
809 
810  // N-gon vertex indices
811  // An array of N indices into the mesh's m_V[] vertex array.
812  // If the ON_MeshNgon is returned by the ON_MeshNgonList::AddNgon()
813  // function, then the memory for vi is managed by the ON_MeshNgonList
814  // class.
815  int* vi;
816 
817  // N-gon face indices
818  // An array of N indices into the mesh's m_F[] face array.
819  // Often, only N-2 indices are used. Unused indices are set to -1.
820  // If the ON_MeshNgon is returned by the ON_MeshNgonList::AddNgon()
821  // function, then the memory for fi is managed by the ON_MeshNgonList
822  // class.
823  int* fi;
824 };
825 
826 class ON_CLASS ON_MeshNgonList
827 {
828 public:
829  ON_MeshNgonList();
830  ~ON_MeshNgonList();
832  ON_MeshNgonList& operator=(const ON_MeshNgonList&);
833 
834 
835  /*
836  Description:
837  Add an N-gon to the list
838  Parameters:
839  N - [in] number of vertices ( >= 5)
840  vi - [in] array of N vertex indices into the mesh's m_V[] array.
841  fi - [in] array of N face indices into the mesh's m_F[] array.
842  Unused indices are set to -1. In many cases
843  there are N-2 valid indices and these are triangles.
844  Remarks:
845  Adding an N-gon may invalidate any pointers previously
846  returned by Ngon.
847  */
848  bool AddNgon(int N, const int* vi, const int* fi);
849  struct ON_MeshNgon* AddNgon(int N);
850 
851  /*
852  Returns:
853  Number of Ngons
854  */
855  int NgonCount() const;
856 
857  /*
858  Parameters:
859  Ngon_index - [in] zero based index
860  Returns:
861  NULL or a pointer to the Ngon
862  */
863  ON_MeshNgon* Ngon(int Ngon_index) const;
864 
865  /*
866  Description:
867  If you know about how many ngons you will need,
868  then use the function to reserve space for them.
869  */
870  bool ReserveNgonCapacity(int capacity);
871 
872  /*
873  Description:
874  Destroy N-gon list
875  */
876  void Destroy();
877 
878  /*
879  Returns:
880  Approximate number of bytes used by this class.
881  */
882  unsigned int SizeOf() const;
883 
884 private:
885  int m_ngons_count;
886  int m_ngons_capacity;
887  ON_MeshNgon* m_ngons;
888  struct ON_NGON_MEMBLK* m_memblk_list;
889 };
890 
891 class ON_CLASS ON_MeshPartition
892 {
893 public:
895  ~ON_MeshPartition();
896 
897  // maximum number of vertices in a partition
899  // maximum number of triangles in a partition (quads count as 2 triangles)
901 
902  // Partition i uses
903  // vertices m_V[j] where
904  //
905  // m_part[i].vi[0] <= j < m_part[i].vi[1]
906  //
907  // and uses faces m_F[k] where
908  //
909  // m_part[i].fi[0] <= k < m_part[i].fi[1]
911 };
912 
913 
914 
915 class ON_CLASS ON_MappingTag
916 {
917 public:
918  ON_MappingTag();
919  void Default();
920  bool Write(ON_BinaryArchive&) const;
921  bool Read(ON_BinaryArchive&);
922  void Dump( ON_TextLog& ) const;
923  void Transform( const ON_Xform& xform );
924  void Set(const ON_TextureMapping& mapping);
925 
926  /*
927  Description:
928  Sets the tag to the value the meshes have that
929  come out of ON_Brep::CreateMesh().
930  */
931  void SetDefaultSurfaceParameterMappingTag();
932 
933  int Compare( const ON_MappingTag& other,
934  bool bCompareId = true,
935  bool bCompareCRC = true,
936  bool bCompareXform = true
937  ) const;
938 
939  /*
940  Returns:
941  True if the mapping tag is set.
942  */
943  bool IsSet() const;
944 
945  /*
946  Returns:
947  True if the mapping tag is for a mapping with
948  type ON_TextureMapping::srfp_mapping with
949  m_uvw = identity.
950  */
951  bool IsDefaultSurfaceParameterMapping() const;
952 
953  // Identifies the mapping used to create the texture
954  // coordinates and records transformations applied
955  // to the mesh after the texture coordinates were
956  // calculated. If the texture mapping does not
957  // change when the mesh is transformed, then set
958  // m_mesh_xform to zero so that compares will work right.
959  //
960  //
961  ON_UUID m_mapping_id; // ON_TextureMapping::m_mapping_id
962  ON_TextureMapping::TYPE m_mapping_type; // ON_TextureMapping::m_type
963  ON__UINT32 m_mapping_crc; // ON_TextureMapping::MappingCRC()
965 };
966 
967 class ON_CLASS ON_TextureCoordinates
968 {
969 public:
971 
973  int m_dim; // 1, 2, or 3
974  ON_SimpleArray<ON_3fPoint> m_T; // texture coordinates
975 };
976 
977 
978 #if defined(ON_DLL_TEMPLATE)
979 // This stuff is here because of a limitation in the way Microsoft
980 // handles templates and DLLs. See Microsoft's knowledge base
981 // article ID Q168958 for details.
982 #pragma warning( push )
983 #pragma warning( disable : 4231 )
984 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_MappingTag>;
985 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_TextureCoordinates>;
986 #pragma warning( pop )
987 #endif
988 
989 class ON_CLASS ON_Mesh : public ON_Geometry
990 {
991  ON_OBJECT_DECLARE(ON_Mesh);
992 public:
993  ON_Mesh();
994  ON_Mesh(
995  int initial_face_array_capacity, // initial face array capacity
996  int initial_vertex_array_capacity, // initial vertex array capacity
997  bool has_vertex_normals, // true if mesh has vertex normals
998  bool has_texture_coordinates // true if mesh has texture coordinates
999  );
1000  ON_Mesh( const ON_Mesh& );
1001  ON_Mesh& operator=( const ON_Mesh& );
1002  ~ON_Mesh();
1003 
1004  // Override of virtual ON_Object::MemoryRelocate
1005  void MemoryRelocate();
1006 
1007  // virtual ON_Object::DestroyRuntimeCache override
1008  void DestroyRuntimeCache( bool bDelete = true );
1009 
1010  void Destroy();
1011  void EmergencyDestroy(); // Call only when memory used by this class's
1012  // members will soon become invalid for reasons
1013  // beyond your control. EmergencyDestroy() zeros
1014  // anything that could possibly cause
1015  // ~ON_Mesh() to crash. Calling
1016  // EmergencyDestroy() under normal conditions
1017  // will result in ~ON_Mesh() leaking
1018  // memory.
1019 
1020  void DestroyTree( bool bDeleteTree = true );
1021 
1022  /////////////////////////////////////////////////////////////////
1023  // ON_Object overrides
1024 
1025  // virtual ON_Object::SizeOf override
1026  unsigned int SizeOf() const;
1027 
1028  // virtual ON_Object::DataCRC override
1029  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
1030 
1031  /*
1032  Description:
1033  Tests an object to see if its data members are correctly
1034  initialized.
1035  Parameters:
1036  text_log - [in] if the object is not valid and text_log
1037  is not NULL, then a brief englis description of the
1038  reason the object is not valid is appened to the log.
1039  The information appended to text_log is suitable for
1040  low-level debugging purposes by programmers and is
1041  not intended to be useful as a high level user
1042  interface tool.
1043  Returns:
1044  @untitled table
1045  true object is valid
1046  false object is invalid, uninitialized, etc.
1047  Remarks:
1048  Overrides virtual ON_Object::IsValid
1049  */
1050  ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
1051 
1052  void Dump( ON_TextLog& ) const; // for debugging
1053 
1054  ON_BOOL32 Write( ON_BinaryArchive& ) const;
1055 
1056  ON_BOOL32 Read( ON_BinaryArchive& );
1057 
1058  ON::object_type ObjectType() const;
1059 
1060  /////////////////////////////////////////////////////////////////
1061  // ON_Geometry overrides
1062 
1063  int Dimension() const;
1064 
1065  ON_BOOL32 GetBBox( // returns true if successful
1066  double*, // minimum
1067  double*, // maximum
1068  ON_BOOL32 = false // true means grow box
1069  ) const;
1070 
1071  /*
1072  Description:
1073  Get tight bounding box of the mesh.
1074  Parameters:
1075  tight_bbox - [in/out] tight bounding box
1076  bGrowBox -[in] (default=false)
1077  If true and the input tight_bbox is valid, then returned
1078  tight_bbox is the union of the input tight_bbox and the
1079  mesh's tight bounding box.
1080  xform -[in] (default=NULL)
1081  If not NULL, the tight bounding box of the transformed
1082  mesh is calculated. The mesh is not modified.
1083  Returns:
1084  True if the returned tight_bbox is set to a valid
1085  bounding box.
1086  */
1087  bool GetTightBoundingBox(
1088  ON_BoundingBox& tight_bbox,
1089  int bGrowBox = false,
1090  const ON_Xform* xform = 0
1091  ) const;
1092 
1093  ON_BOOL32 Transform(
1094  const ON_Xform&
1095  );
1096 
1097  // virtual ON_Geometry::IsDeformable() override
1098  bool IsDeformable() const;
1099 
1100  // virtual ON_Geometry::MakeDeformable() override
1101  bool MakeDeformable();
1102 
1103  ON_BOOL32 SwapCoordinates(
1104  int, int // indices of coords to swap
1105  );
1106 
1107  // virtual ON_Geometry override
1108  bool EvaluatePoint( const class ON_ObjRef& objref, ON_3dPoint& P ) const;
1109 
1110 
1111  /////////////////////////////////////////////////////////////////
1112  // Interface
1113  //
1114 
1115  // creation
1116  bool SetVertex(
1117  int, // vertex index
1118  const ON_3dPoint& // vertex location
1119  );
1120  bool SetVertex(
1121  int, // vertex index
1122  const ON_3fPoint& // vertex location
1123  );
1124  bool SetVertexNormal(
1125  int, // vertex index
1126  const ON_3dVector& // unit normal
1127  );
1128  bool SetVertexNormal(
1129  int, // vertex index
1130  const ON_3fVector& // unit normal
1131  );
1132  bool SetTextureCoord(
1133  int, // vertex index
1134  double, double // texture coordinates
1135  );
1136  bool SetTriangle(
1137  int, // face index
1138  int,int,int // vertex indices
1139  );
1140  bool SetQuad(
1141  int, // face index
1142  int,int,int,int // vertex indices
1143  );
1144 
1145  /*
1146  Description:
1147  Get a vertex reference to a mesh vertex index.
1148  Parameters:
1149  ci - [in] component index with type mesh_vertex or meshtop_vertex.
1150  Returns:
1151  a reference to the vertex
1152  */
1153  ON_MeshVertexRef VertexRef(ON_COMPONENT_INDEX ci) const;
1154 
1155  ON_MeshVertexRef VertexRef(int mesh_V_index) const;
1156 
1157  /*
1158  Description:
1159  Get an edge reference from a mesh topology edge index.
1160  Parameters:
1161  ci - [in] component index with type meshtop_edge
1162  Returns:
1163  a reference to the edge
1164  */
1165  ON_MeshEdgeRef EdgeRef(ON_COMPONENT_INDEX ci) const;
1166 
1167  ON_MeshEdgeRef EdgeRef(int tope_index) const;
1168 
1169  /*
1170  Description:
1171  Get a face reference from a mesh face index.
1172  Parameters:
1173  ci - [in] component index with type mesh_face.
1174  Returns:
1175  a reference to the face
1176  */
1177  ON_MeshFaceRef FaceRef(ON_COMPONENT_INDEX ci) const;
1178 
1179  ON_MeshFaceRef FaceRef(int mesh_F_index) const;
1180 
1181  /*
1182  Parameters:
1183  ci - [in] a component index with type mesh_vertex, meshtop_vertex,
1184  meshtop_edge, or mesh_face.
1185  Returns:
1186  A pointer to an ON_MeshVertexRef, ON_MeshEdgeRef, or ON_MeshFaceRef.
1187  The caller must delete the returned object when it is no longer
1188  needed.
1189  See Also:
1190  ON_Mesh::VertexRef
1191  ON_Mesh::EdgeRef
1192  ON_Mesh::FaceRef
1193  */
1194  ON_Geometry* MeshComponent(
1195  ON_COMPONENT_INDEX ci
1196  ) const;
1197 
1198  // query
1199  int VertexCount() const;
1200  int FaceCount() const;
1201  int QuadCount() const; // number of faces that are quads
1202  int TriangleCount() const; // number of faces that are triangles
1203  int InvalidFaceCount() const; // number of face that have invalid m_vi[] values.
1204  bool HasVertexNormals() const; // normals at vertices
1205  bool HasFaceNormals() const;
1206  bool HasTextureCoordinates() const;
1207  bool HasSurfaceParameters() const;
1208  bool HasPrincipalCurvatures() const;
1209  bool HasVertexColors() const;
1210 
1211  /*
1212  Returns:
1213  Number of vertices that are hidden.
1214  */
1215  int HiddenVertexCount() const;
1216 
1217  bool GetCurvatureStats(
1218  ON::curvature_style,
1220  ) const;
1221 
1222  void InvalidateVertexBoundingBox(); // Call if defining geometry is changed by
1223  // directly manipulating the m_V[] array.
1224  void InvalidateVertexNormalBoundingBox(); // Call if defining geometry is changed by
1225  // directly manipulating the m_N[] array.
1226  void InvalidateTextureCoordinateBoundingBox(); // Call if defining geometry is changed by
1227  // directly manipulating the m_T[] array.
1228  void InvalidateCurvatureStats(); // Call if defining geometry is changed by
1229  // directly manipulating the m_T[] array.
1230  void InvalidateBoundingBoxes(); // Invalidates all cached bounding box information.
1231 
1232 
1233  void Flip(); // reverses face orientations and flips vertex and face normals
1234 
1235  void FlipVertexNormals(); // reverses vertex normals
1236  void FlipFaceNormals(); // reverses face normals
1237  void FlipFaceOrientation(); // reverses face orientation (does nothing to normals)
1238 
1239  void SetMeshParameters( const ON_MeshParameters& );
1240  const ON_MeshParameters* MeshParameters() const;
1241  void DeleteMeshParameters();
1242 
1243 
1244  bool UnitizeVertexNormals();
1245  bool UnitizeFaceNormals();
1246  bool CountQuads();
1247 
1248  /*
1249  Description:
1250  Splits all quads along the short diagonal.
1251  */
1252  bool ConvertQuadsToTriangles();
1253 
1254  /*
1255  Description:
1256  Joins adjacent triangles into quads if the resulting quad
1257  is nice.
1258  Parameters:
1259  angle_tol_radians - [in] Used to compare adjacent
1260  triangles' face normals. For two triangles to be considered,
1261  the angle between their face normals has to be <= angle_tol_radians.
1262  When in doubt use ON_PI/90.0 (2 degrees).
1263  min_diagonal_length_ratio - [in] ( <= 1.0) For two triangles to be
1264  considered the ratio of the resulting quad's diagonals
1265  (length of the shortest diagonal)/(length of longest diagonal).
1266  has to be >= min_diagonal_length_ratio.
1267  When in doubt us .875.
1268  */
1269  bool ConvertTrianglesToQuads(
1270  double angle_tol_radians,
1271  double min_diagonal_length_ratio
1272  );
1273 
1274  bool ComputeFaceNormals(); // compute face normals for all faces
1275  bool ComputeFaceNormal(int); // computes face normal of indexed face
1276 
1277  /*
1278  Description:
1279  Get a list of pairs of faces that clash.
1280  Parameters:
1281  max_pair_count - [in]
1282  If max_pair_count > 0, then at most this many pairs
1283  will be appended to the clashing_pairs[] array.
1284  If max_pair_count <= 0, then all clashing pairs
1285  will be appended to the clashing_pairs[] array.
1286  clashing_pairs - [out]
1287  The faces indices of clashing pairs are appended
1288  to this array.
1289  Returns:
1290  Number of pairs appended to clashing_pairs[].
1291  */
1292  int GetClashingFacePairs(
1293  int max_pair_count,
1294  ON_SimpleArray< ON_2dex >& clashing_pairs
1295  ) const;
1296 
1297  /*
1298  Description:
1299  Cull clashing faces from the mesh.
1300  Parameters:
1301  what_to_cull - [in]
1302  0: when a pair of faces clash, cull both faces
1303  1: when a pair of faces clash, leave the face with the
1304  longest edge.
1305  2: when a pair of faces clash, cull the face with the
1306  longest edge.
1307  3: when a pair of faces clash, leave the face with
1308  the largest area.
1309  4: when a pair of faces clash, cull the face with
1310  the largest area.
1311  Returns:
1312  Number of faces culled from the mesh.
1313  Remarks:
1314  If a large face clashes with many small faces, the large
1315  face and one small face will be removed. When a degenerate
1316  face is encountered, it is also culled.
1317  */
1318  int CullClashingFaces( int what_to_cull );
1319 
1320  int CullDegenerateFaces(); // returns number of degenerate faces
1321 
1322  int CullUnusedVertices(); // returns number of culled vertices
1323 
1324  // Description:
1325  // Removes any unreferenced objects from arrays, reindexes as needed,
1326  // and shrinks arrays to minimum required size.
1327  bool Compact();
1328 
1329  bool ComputeVertexNormals(); // uses face normals to cook up a vertex normal
1330 
1331  //////////
1332  // Scales textures so the texture domains are [0,1] and
1333  // eliminates any texture rotations.
1334  bool NormalizeTextureCoordinates();
1335 
1336  /////////
1337  // Description:
1338  // Transposes the texture coordinates
1339  // Returns
1340  // true - success
1341  bool TransposeTextureCoordinates();
1342  bool TransposeSurfaceParameters();
1343 
1344  /////////
1345  // Description:
1346  // Reverse one coordinate direction of the texture coordinates, within texture domain m_tex_domain
1347  // Parameters:
1348  // dir -[in] - dir=0 first texture coordinate is reversed
1349  // dir=1 second texture coordinate is reversed
1350  // Returns
1351  // true - success
1352  bool ReverseTextureCoordinates( int dir );
1353  bool ReverseSurfaceParameters( int dir );
1354 
1355 
1356 
1357  /*
1358  Description:
1359  Use a texture mapping function to set the m_T[] values.
1360  Parameters:
1361  mapping - [in]
1362  mesh_xform - [in]
1363  If not NULL, the mapping calculation is performed as
1364  if the mesh were transformed by mesh_xform; the
1365  location of the mesh is not changed.
1366  bLazy - [in]
1367  If true and the m_T[] values were set using the same
1368  mapping parameters, then no calculation is performed.
1369  Returns:
1370  True if successful.
1371  See Also:
1372  ON_TextureMapping::GetTextureCoordinates
1373  */
1374  bool SetTextureCoordinates(
1375  const class ON_TextureMapping& mapping,
1376  const class ON_Xform* mesh_xform = 0,
1377  bool bLazy = true
1378  );
1379 
1380  bool HasCachedTextureCoordinates() const;
1381 
1382  const ON_TextureCoordinates* CachedTextureCoordinates(
1383  const ON_UUID& mapping_id
1384  ) const;
1385 
1386  const ON_TextureCoordinates* SetCachedTextureCoordinates(
1387  const class ON_TextureMapping& mapping,
1388  const class ON_Xform* mesh_xform = 0,
1389  bool bLazy = true
1390  );
1391 
1392  bool EvaluateMeshGeometry( const ON_Surface& ); // evaluate surface at tcoords
1393  // to set mesh geometry
1394 
1395  // finds all coincident vertices and merges them if break angle is small enough
1396  bool CombineCoincidentVertices(
1397  ON_3fVector, // coordinate tols for considering vertices
1398  // to be coincident
1399  double // cosine normal angle tolerance in radians
1400  // if vertices are coincident, then they are combined
1401  // if NormalA o NormalB >= this value
1402  );
1403 
1404  /*
1405  Description:
1406  Combines identical vertices.
1407  Parameters:
1408  bIgnoreVertexNormals - [in] If true, then vertex normals
1409  are ignored when comparing vertices.
1410  bIgnoreTextureCoordinates - [in] If true, then vertex
1411  texture coordinates, colors, and principal curvatures
1412  are ignored when comparing vertices.
1413  Returns:
1414  True if the mesh is changed, in which case the returned
1415  mesh will have fewer vertices than the input mesh.
1416  */
1417  bool CombineIdenticalVertices(
1418  bool bIgnoreVertexNormals = false,
1419  bool bIgnoreTextureCoordinates = false
1420  );
1421 
1422  void Append( const ON_Mesh& ); // appends a copy of mesh to this and updates
1423  // indices of appended mesh parts
1424 
1425  /*
1426  Description:
1427  Append a list of meshes. This function is much more efficient
1428  than making repeated calls to ON_Mesh::Append(const ON_Mesh&)
1429  when lots of meshes are being joined into a single large mesh.
1430  Parameters:
1431  count - [in]
1432  length of meshes[] array.
1433  meshes - [in]
1434  array of meshes to append.
1435  */
1436  void Append( int count, const ON_Mesh* const* meshes );
1437 
1438  /*
1439  Description:
1440  Expert user function to set m_is_closed member.
1441  Setting this value correctly after a mesh is constructed
1442  can save time when IsClosed() is called.
1443  This function sets the private member variable m_is_closed.
1444  Paramters:
1445  closed - [in]
1446  0: The mesh is not closed. There is at least one face with an
1447  edge that is geometrically distinct (as an unoriented line segment)
1448  from all other edges.
1449  1: The mesh is closed. Every geometrically distict edge is used
1450  by two or more faces.
1451  */
1452  void SetClosed(int closed);
1453 
1454  /*
1455  Returns:
1456  True if every mesh "edge" has two or more faces.
1457  */
1458  bool IsClosed() const;
1459 
1460  /*
1461  Returns:
1462  True if every mesh "edge" has at most two faces.
1463  */
1464  bool IsManifold() const;
1465 
1466  /*
1467  Returns:
1468  True if the mesh is manifold and every pair of faces
1469  that share an "edge" have compatible orientations.
1470  */
1471  bool IsOriented() const;
1472 
1473  /*
1474  Description:
1475  Determine if the mesh is a manifold.
1476  Parameters:
1477  bTopologicalTest - [in]
1478  If true, the query treats coincident vertices as
1479  the same.
1480  pbIsOriented - [out]
1481  If the input pointer is not NULL, then the returned
1482  value of *pbIsOriented will be true if the mesh
1483  is a manifold and adjacent faces have compatible
1484  face normals.
1485  pbHasBoundary - [out]
1486  If the input pointer is not NULL, then the returned
1487  value of *pbHasBoundary will be true if the mesh
1488  is a manifold and there is at least one "edge"
1489  with no adjacent faces have compatible
1490  face normals.
1491  Returns:
1492  True if every mesh "edge" has at most two adjacent faces.
1493  */
1494  bool IsManifold(
1495  bool bTopologicalTest,
1496  bool* pbIsOriented = NULL,
1497  bool* pbHasBoundary = NULL
1498  ) const;
1499 
1500  /*
1501  Description:
1502  Expert user function to set m_is_solid member.
1503  Setting this value correctly after a mesh is constructed
1504  can save time when IsSolid() is called.
1505  This function sets the private member variable m_is_solid.
1506  If solid is nonzero, it will set m_is_closed to 1.
1507  Paramters:
1508  solid - [in]
1509  0: The mesh is not an oriented manifold solid mesh. Either
1510  the mesh is not closed, not manifold, or the faces are
1511  not oriented compatibly.
1512  1: The mesh is an oriented manifold solid whose face normals
1513  point outwards.
1514  -1: The mesh is an oriented manifold solid whose face normals
1515  point inwards.
1516  */
1517  void SetSolidOrientation(int solid_orientation);
1518 
1519  /*
1520  Description:
1521  Determine orientation of a mesh.
1522  Returns:
1523  +1 mesh is a solid with outward facing normals
1524  -1 mesh is a solid with inward facing normals
1525  0 mesh is not a solid
1526  See Also:
1527  ON_Mesh::IsSolid
1528  */
1529  int SolidOrientation() const;
1530 
1531  /*
1532  Description:
1533  Test mesh to see if it is a solid. (A "solid" is
1534  a closed oriented manifold.)
1535  Returns:
1536  true mesh is a solid
1537  fals mesh is not a solid
1538  See Also:
1539  ON_Mesh::SolidOrientation
1540  ON_Mesh::IsManifold
1541  */
1542  bool IsSolid() const;
1543 
1544  /*
1545  Description:
1546  Appends a list of mesh edges that begin or end at the specified
1547  vertices to the edges[] array.
1548  Parameters:
1549  vcount - [in]
1550  number of vertices
1551  vertex_index - [in]
1552  array of vertex indices
1553  bNoDuplicates - [in]
1554  If true, then only one edges[] is added for each edge,
1555  the first vertex index will alwasy be less than the
1556  second, and the returned elements are sorted in dictionary
1557  order.
1558  If false and an edge is shared by multiple faces, then
1559  there will be an edges[] element added for each face and the
1560  order of the vertex indicies will indicate the orientation
1561  of the edge with respect to the face. No sorting is performed
1562  in this case.
1563  edges - [out]
1564  Edges that begin or end at one of the specified vertices are
1565  appended to this array. Each ON_2dex records the start and
1566  end vertex index.
1567  Returns:
1568  Number of ON_2dex values appended to the edges[] array.
1569  */
1570  int GetVertexEdges(
1571  int vcount,
1572  const int* vertex_index,
1573  bool bNoDuplicates,
1575  ) const;
1576 
1577 
1578  /*
1579  Description:
1580  Appends a list of mesh edges to the edges[] array.
1581  Parameters:
1582  edges - [out]
1583  Each edges[] element is a pair of vertex indices. There
1584  is at least one face in the mesh with an edge running between
1585  the indicies.
1586  Returns:
1587  Number of ON_2dex values appended to the edges[] array.
1588  */
1589  int GetMeshEdges(
1591  ) const;
1592 
1593  /*
1594  Description:
1595  Assign a unique id to each vertex location. Coincident vertices
1596  get the same id.
1597  Parameters:
1598  first_vid - [in]
1599  Initial vertex id. Typically 1 or 0.
1600  Vid - [out]
1601  If not null, then Vid[] sould be an array of length VertexCount().
1602  and the vertex ids will be stored in this array. If null,
1603  the array will be allocated by calling onmalloc(). The returned
1604  array Vid[i] is the id of the vertex m_V[i]. If m_V[i] and
1605  m_V[j] are the same 3d point, then Vid[i] and Vid[j] will have
1606  the same value.
1607  Vindex - [out] (can be null)
1608  If Vindex is not null, then it must have length at least m_V.Count()
1609  and the returned array will be a permutation of (0,1,...,m_V.Count()-1)
1610  such (Vid[Vindex[0]], Vid[Vindex[1]], ..., Vid[Vindex[m_V.Count()-1]])
1611  is an increasing list of value.
1612  Returns:
1613  null if the mesh has no vertices.
1614  An array of length VertexCount(). If vertices m_V[i] and m_V[j]
1615  are coincident, then Vid[i] = Vid[j]. The id values begin at first_vid.
1616  The maximum vertex id is Vid[Vindex[m_V.Count()-1]]. The number of
1617  unique vertex locations is (Vid[Vindex[m_V.Count()-1]] - first_vid + 1).
1618  */
1619  int* GetVertexLocationIds(
1620  int first_vid,
1621  int* Vid,
1622  int* Vindex
1623  ) const;
1624 
1625  /*
1626  Description:
1627  Get a list of the sides of every face.
1628  Parameters:
1629  Vid - [in] (can be null)
1630  If Vid is null, then the mesh m_V[] index values are used to set
1631  the ON_MeshFaceSide::vi[] values.
1632  If Vid is not null, then it must be an array of length VertexCount().
1633  The value Vid[mesh m_V[] index] will be used to set the
1634  ON_MeshFaceSide::vi[] values.
1635  sides - [out]
1636  If the input value of sides is not null, then sides[] must be long
1637  enough to hold the returned side list. The maximum posssible length
1638  is 4*FaceCount() for a mesh contining FaceCount() nondegenerate quads.
1639  If the input value of sides is null, memory will be allocated using
1640  onmalloc() and the caller is responsible for calling onfree() at an
1641  appropriate time. This function fills in the sides[] array
1642  with face side information. The returned list is sorted by sides[].fi
1643  and the sides[].side and each element has vi[0] <= vi[1].
1644  The function ON_SortMeshFaceSidesByVertexIndex() can be used to sort the
1645  list by the sides[].vi[] values.
1646  Returns:
1647  Number of elements added to sides[].
1648  Remarks:
1649  Faces with out of range ON_MeshFace.vi[] values are skipped.
1650  Degenerate faces are processed, but degenerate sides (equal vertex indices)
1651  are not added to the list.
1652  */
1653  int GetMeshFaceSideList(
1654  const int* Vid,
1655  struct ON_MeshFaceSide*& sides
1656  ) const;
1657 
1658  /*
1659  Description:
1660  Get a list of the geometrically uniqued edges in a mesh.
1661  Parameters:
1662  edge_list - [out]
1663  The edge list for this mesh is appended to edge_list[].
1664  The ON_2dex i and j values are mesh->m_V[] array indices.
1665  There is exactly one element in edge_list[] for each
1666  unoriented 3d line segment in the mesh. The edges are
1667  oriented the same way the corresponding ON_MeshTopology
1668  edge is oriented.
1669  ci_meshtop_edge_map - [out]
1670  If you call the verson of GetMeshEdgeList() with the ci_meshtop_edge_map[],
1671  parameter, then the edge in edge_list[i] cooresponds to the edge
1672  in ON_MeshTopology.m_tope[ci_meshtop_edge_map[i]]. The value
1673  ci_meshtop_edge_map[i] is useful if you need to convert an edge_list[]
1674  index into an ON_COMPONENT_INDEX with type meshtop_edge.
1675  ci_meshtop_vertex_map - [out]
1676  If you call the verson of GetMeshEdgeList() with the ci_meshtop_vertex_map[],
1677  parameter, then the vertex m_V[i] cooresponds to the vertex
1678  in ON_MeshTopology.m_topv[ci_meshtop_vertex_map[i]]. The value
1679  ci_meshtop_vertex_map[i] is useful if you need to convert an m_V[]
1680  index into an ON_COMPONENT_INDEX with type meshtop_vertex.
1681  edge_list_partition - [out] (can be null)
1682  The edge_list[] is always ordered so that edge_types
1683  are partitioned into contiguous regions. The edge_list_partition[5]
1684  values report the edge type regions.
1685  * If edge_type_partition[0] <= ei < edge_type_partition[1], then
1686  edge_list[ei] is an edge of exactly two faces and the vertices
1687  used by the faces are identical. These are also called
1688  "manifold edges".
1689  * If edge_type_partition[1] <= ei < edge_type_partition[2], then
1690  edge_list[ei] is an edge of exactly two faces, but at least
1691  one of the vertices is duplicated. These are also called
1692  "crease edges".
1693  * If edge_type_partition[2] <= ei < edge_type_partition[3], then
1694  edge_list[ei] is an edge of 3 or more faces. These are also called
1695  "nonmanifold edges".
1696  * If edge_type_partition[3] <= ei < edge_type_partition[4],
1697  then edge_list[ei] is a boundary edge of exactly one mesh face.
1698  These are also called "naked edges".
1699  Returns:
1700  Number of edges added to edge_list[].
1701  Remarks:
1702  This calculation also sets m_closed. If you modify the mesh's
1703  m_V or m_F information after calling this function, be sure to
1704  clear m_is_closed.
1705  */
1706  int GetMeshEdgeList(
1707  ON_SimpleArray<ON_2dex>& edge_list,
1708  int edge_type_partition[5]
1709  ) const;
1710 
1711  int GetMeshEdgeList(
1712  ON_SimpleArray<ON_2dex>& edge_list,
1713  ON_SimpleArray<int>& ci_meshtop_edge_map,
1714  int edge_type_partition[5]
1715  ) const;
1716 
1717  int GetMeshEdgeList(
1718  ON_SimpleArray<ON_2dex>& edge_list,
1719  ON_SimpleArray<int>& ci_meshtop_edge_map,
1720  ON_SimpleArray<int>& ci_meshtop_vertex_map,
1721  int edge_type_partition[5]
1722  ) const;
1723 
1724  ///////////////////////////////////////////////////////////////////////
1725  //
1726  // mesh editing
1727  //
1728 
1729  /*
1730  Description:
1731  Replace a mesh edge with a vertex at its center and update
1732  adjacent faces as needed.
1733  Parameters:
1734  topei - [in] index of edge in MeshTopology().m_tope[] array
1735  Returns:
1736  true if successful.
1737  */
1738  bool CollapseEdge( int topei );
1739 
1740  /*
1741  Description:
1742  Tests a mesh edge to see if it is valid as input to
1743  ON_Mesh::SwapMeshEdge.
1744  Parameters:
1745  topei - [in] index of edge in MeshTopology().m_tope[] array
1746  Returns:
1747  true if edge can be swapped by ON_Mesh::SwapMeshEdge.
1748  See Also:
1749  ON_Mesh::SwapEdge
1750  */
1751  bool IsSwappableEdge( int topei );
1752 
1753 
1754  /*
1755  Description:
1756  If the edge is shared by two triangular face, then
1757  the edge is "swapped".
1758  Parameters:
1759  topei - [in] index of edge in MeshTopology().m_tope[] array
1760  Returns:
1761  true if successful
1762  See Also:
1763  ON_Mesh::IsSwappableEdge
1764  */
1765  bool SwapEdge( int topei );
1766 
1767  /*
1768  Description:
1769  Removes a face from a mesh and does not alter the
1770  geometry of the remaining mesh.
1771  Parameters:
1772  meshfi - [in] index of face in ON_Mesh.m_F[] array
1773  Remarks:
1774  This function calls DestroyTopology() and DestroyPartition().
1775  The caller is responsible for calling Compact() if that step
1776  is required.
1777  Returns:
1778  true if successful
1779  */
1780  bool DeleteFace( int meshfi );
1781 
1782  /*
1783  Description:
1784  Destroys the m_H[] array and sets m_hidden_count=0.
1785  */
1786  void DestroyHiddenVertexArray();
1787 
1788  /*
1789  Returns:
1790  If the mesh has some hidden vertices, then an array
1791  of length VertexCount() is returned and the i-th
1792  element is true if the i-th vertex is hidden.
1793  If no vertices are hidden, NULL is returned.
1794  */
1795  const bool* HiddenVertexArray() const;
1796 
1797  /*
1798  Description:
1799  Set the runtime vertex hidden flag.
1800  Parameters:
1801  meshvi - [in] mesh vertex index
1802  bHidden - [in] true to hide vertex
1803  */
1804  void SetVertexHiddenFlag( int meshvi, bool bHidden );
1805 
1806  /*
1807  Description:
1808  Returns true if the mesh vertex is hidden. This is a runtime
1809  setting that is not saved in 3dm files.
1810  Parameters:
1811  meshvi - [in] mesh vertex index.
1812  Returns:
1813  True if mesh vertex is hidden.
1814  */
1815  bool VertexIsHidden( int meshvi ) const;
1816 
1817  /*
1818  Description:
1819  Returns true if the mesh face is hidden. This is a runtime
1820  setting that is not saved in 3dm files.
1821  Parameters:
1822  meshfi - [in] mesh face index.
1823  Returns:
1824  True if mesh face is hidden.
1825  Remarks:
1826  A face is hidden if, and only if, at least one of its
1827  vertices is hidden.
1828  */
1829  bool FaceIsHidden( int meshvi ) const;
1830 
1831 
1832  ///////////////////////////////////////////////////////////////////////
1833  //
1834  // mesh topology
1835  //
1836  // In order to keep the mesh facet definition simple and make the mesh
1837  // definition easily used in common rendering application, if two facets
1838  // share a vertex location but have different normals, curvatures,
1839  // textures, etc., at that common vertex location, then the vertex is
1840  // duplicated. When the topology of the mesh needs to be known,
1841  // use Topology() to get a class that provides complete topological
1842  // information about the mesh.
1843  const ON_MeshTopology& Topology() const;
1844 
1845  ///////////////////////////////////////////////////////////////////////
1846  // If you modify the mesh in any way that may change its topology,
1847  // then call DestroyTopology(). Specifically if you add or remove
1848  // vertices or face, change vertex locations, or change the face m_vi[]
1849  // values, then you must call DestroyTopology().
1850  void DestroyTopology();
1851 
1852  /*
1853  Returns:
1854  This is an expert user function that returns true if the topology
1855  information is already calculated and cached. It can be used to
1856  to avoid calling the Topology() function when the expensive creation
1857  step will be performed.
1858  */
1859  bool TopologyExists() const;
1860 
1861 
1862  ///////////////////////////////////////////////////////////////////////
1863  //
1864  // mesh partitions
1865  //
1866  // In ancient times, some rendering engines were only able to process
1867  // small batches of triangles and th CreatePartition() function was
1868  // provided to partition the mesh into subsets of vertices and faces
1869  // that those renering engines could handle.
1870  //
1871  const ON_MeshPartition* CreatePartition(
1872  int, // maximum number of vertices in a partition
1873  int // maximum number of triangles in a partition
1874  );
1875  const ON_MeshPartition* Partition() const;
1876  void DestroyPartition();
1877 
1878  /*
1879  Description:
1880  Extract the portion of this mesh defined by mesh_part.
1881  Parameters:
1882  mesh_part - [in]
1883  defines portion of the mesh to extract.
1884  mesh - [in] (can be null, cannot be = "this).
1885  If mesh is no null, the extracted mesh will be put into
1886  this mesh. If mesh is null, the extracted mesh will
1887  be created in a mesh allocated on the heap using the
1888  new operator.
1889  Returns:
1890  A pointer to the submesh. If the input mesh parameter is null,
1891  then the caller must delete this mesh when it is no longer needed.
1892  If the input is invalid, then null is returned.
1893  */
1894  ON_Mesh* MeshPart(
1895  const ON_MeshPart& mesh_part,
1896  ON_Mesh* mesh
1897  ) const;
1898 
1899  /*
1900  Description:
1901  Create a mesh that is a single face of this mesh.
1902  Parameters:
1903  Returns:
1904  A pointer to the submesh. If the input mesh parameter is null,
1905  then the caller must delete this mesh when it is no longer needed.
1906  If the input is invalid, then null is returned.
1907  */
1908  ON_Mesh* DuplicateFace(
1909  int face_index,
1910  ON_Mesh* mesh
1911  ) const;
1912 
1913  ///////////////////////////////////////////////////////////////////////
1914  //
1915  // mesh N-gon lists.
1916  // ON_Mesh objects support faces that are triangle or quads.
1917  // When a mesh is created from a format that supports N-gons
1918  // for N larger than 4, an optional N-gon list can be added
1919  // that specifies the vertices and faces that make up the N-gon.
1920  //
1921 
1922  /*
1923  Description:
1924  If the mesh has an N-gon list, return a pointer to it.
1925  Returns:
1926  A pointer to the current N-gon list or NULL.
1927  */
1928  const class ON_MeshNgonList* NgonList() const;
1929 
1930  /*
1931  Description:
1932  If an N-gon list exists, it is returned and can be modified.
1933  If no N-gon list exists, a new empty list is returned and
1934  it can be modified.
1935  Returns:
1936  A pointer to the N-gon list that can be modified.
1937  */
1938  class ON_MeshNgonList* ModifyNgonList();
1939 
1940  /*
1941  Description:
1942  Destroy any existing N-gon list.
1943  */
1944  void DestroyNgonList();
1945 
1946  ///////////////////////////////////////////////////////////////////////
1947  //
1948  // mesh components
1949  // ON_Mesh objects can consist of sets of faces that are isolated
1950  // from any other sets of faces. The following 2 functions will
1951  // dissect a mesh into these sets, called components. Not to be
1952  // confused with ON_COMPONENT_INDEX.
1953 
1954  /*
1955  Description:
1956  Calculates the components of a mesh and sets a label for each face in
1957  the facet_component_labels array.
1958  Parameters:
1959  bUseVertexConnections- [in]
1960  If this parameter is true, then facets that share a common vertex
1961  are considered connected.
1962  If this parameter is false, then facets must share an edge to
1963  be considered connected.
1964  bUseTopologicalConnections - [in]
1965  If this parameter is true, then geometric location is used
1966  to determine if facets are connected.
1967  If this parameter is false, then facets must share the same vertex
1968  or vertices to be considered connected.
1969  facet_component_labels- [out]
1970  facet_component_labels[] will be an array with the same size
1971  as ON_Mesh.m_F.Count() and facet_component_labels[i]
1972  is the component id m_F[i] belongs to. The component id
1973  will be 1 to the number of compoents.
1974  Returns:
1975  Number of components on success, 0 on failure
1976  */
1977 
1978  int GetConnectedComponents( bool bUseVertexConnections,
1979  bool bTopologicalConnections,
1980  ON_SimpleArray<int>& facet_component_labels
1981  ) const;
1982 
1983  /*
1984  Description:
1985  Calculates the components of a mesh and sets a label for each face in
1986  the facet_component_labels array.
1987  Parameters:
1988  bUseVertexConnections- [in]
1989  If this parameter is true, then facets that share a common vertex
1990  are considered connected.
1991  If this parameter is false, then facets must share an edge to
1992  be considered connected.
1993  bUseTopologicalConnections - [in]
1994  If this parameter is true, then geometric location is used
1995  to determine if facets are connected.
1996  If this parameter is false, then facets must share the same vertex
1997  or vertices to be considered connected.
1998  components - [out]
1999  New components are appended to this array
2000  if this parameter is null, then the components are just counted.
2001  Returns:
2002  Number of components on success, 0 on failure
2003  */
2004 
2005  int GetConnectedComponents( bool bUseVertexConnections,
2006  bool bTopologicalConnections,
2007  ON_SimpleArray<ON_Mesh*>* components
2008  ) const;
2009 
2010 
2011  /////////////////////////////////////////////////////////////////
2012  //
2013  // Double precision vertex support
2014  //
2015 
2016  /*
2017  Returns:
2018  True if the mesh has single and double precision
2019  vertices, and the values of the two sets are synchronized.
2020  */
2021  bool HasSynchronizedDoubleAndSinglePrecisionVertices() const;
2022 
2023  /*
2024  Returns:
2025  True if the mesh has double precision vertices.
2026  Remarks:
2027  This function returns true if a mesh has double
2028  precision vertex information, even if it is not
2029  updated.
2030 
2031  Use ON_Mesh::DoublePrecisionVerticesAreValid()
2032  and ON_Mesh::SinglePrecisionVerticesAreValid() to
2033  check the validity.
2034 
2035  Use ON_Mesh::UpdateDoublePrecisionVertices()
2036  or ON_Mesh::UpdateSinglePrecisionVertices() to synchronize
2037  values of single and double precision vertices.
2038  */
2039  bool HasDoublePrecisionVertices() const;
2040 
2041  /*
2042  Parameters:
2043  bEnableDoublePrecisionVertices - [in]
2044  True to enable use of double precision vertices.
2045  False to destroy any existing precision vertices.
2046  */
2047  void EnableDoublePrecisionVertices(bool bEnableDoublePrecisionVertices);
2048 
2049  /*
2050  Description:
2051  If you modify the values of double precision vertices,
2052  then you must call UpdateSinglePrecisonVertices().
2053  Remarks:
2054  If double precision vertices are not present, this function
2055  does nothing.
2056  */
2057  void UpdateSinglePrecisionVertices();
2058 
2059  /*
2060  Description:
2061  If you modify the values of the single precision vertices
2062  in m_V[], then you must call UpdateDoublePrecisionVertices().
2063  Remarks:
2064  If double precision vertices are not present, this function
2065  does nothing.
2066  */
2067  void UpdateDoublePrecisionVertices();
2068 
2069  /*
2070  Description:
2071  If you have modified the single precision vertices
2072  and are certain they are valid, then call this
2073  function to update crc information.
2074  Remarks:
2075  If double precision vertices are not present, this function
2076  does nothing.
2077  */
2078  void SetSinglePrecisionVerticesAsValid();
2079 
2080  /*
2081  Description:
2082  If you have modified the double precision vertices
2083  and are certain they are valid, then call this
2084  function to update crc information.
2085  Remarks:
2086  If double precision vertices are not present, this function
2087  does nothing.
2088  */
2089  void SetDoublePrecisionVerticesAsValid();
2090 
2091  /*
2092  Description:
2093  The functions UpdateSinglePrecisionVertices(),
2094  UpdateDoublePrecisionVertices(), and
2095  SetSinglePrecisionVerticesAsValid() save
2096  the count and crc of the single precision vertex
2097  array. True is returned if there are no
2098  double precision vertices or the current
2099  count and crc of the single precision
2100  vertex array match the saved values.
2101  Remarks:
2102  If double precision vertices are not present, this function
2103  does nothing and returns true.
2104  */
2105  bool SinglePrecisionVerticesAreValid() const;
2106 
2107  /*
2108  Description:
2109  The functions UpdateSinglePrecisionVertices(),
2110  UpdateDoublePrecisionVertices(), and
2111  SetDoublePrecisionVerticesAsValid() save
2112  the count and crc of the double precision vertex
2113  array. True is returned if the current
2114  count and crc of the double precision
2115  vertex array match the saved values.
2116  Remarks:
2117  If double precision vertices are not present, this function
2118  does nothing and returns true.
2119  */
2120  bool DoublePrecisionVerticesAreValid() const;
2121 
2122  /*
2123  Description:
2124  The function removes all double precision vertex information.
2125  */
2126  void DestroyDoublePrecisionVertices();
2127 
2128 
2129  /////////////////////////////////////////////////////////////////
2130  // Implementation - mesh geometry
2131 
2132  // Vertex locations
2133  // In a case where adjacent facets share a vertex
2134  // location but have distinct normals or texture
2135  // coordinates at that location, the vertex must
2136  // be duplicated.
2137 
2138  /*
2139  Description:
2140  Get double precision vertices. If they do not exist,
2141  they will be created and match the existing single
2142  precision vertices.
2143  Returns:
2144  Array of double precision vertices. If you modify the
2145  values in this array, you must make the same modifications
2146  to the single precision vertices, or call
2147  UpdateSinglePrecisonVertices().
2148  Example:
2149 
2150  // add a bunch of double precision information
2151  ON_3dPointArray& dv = mesh.DoublePrecisionVertices();
2152  for ( i = 0; i < lots; i++ )
2153  {
2154  dv[i] = ...
2155  }
2156  // This call updates the single precison values
2157  // in m_V[] and sets all the counts and CRCs that
2158  // are used in validity checking.
2159  mesh.UpdateSinglePrecisonVertices();
2160 
2161  Remarks:
2162  Avoid mulitple calls to DoublePrecisionVertices().
2163  It is most efficient to make one call, save a local
2164  reference, and use the local reference as needed.
2165  */
2166  ON_3dPointArray& DoublePrecisionVertices();
2167  const ON_3dPointArray& DoublePrecisionVertices() const;
2168 
2169  /*
2170  Description:
2171  Get single precision vertices.
2172  Returns:
2173  Array of float precision vertices. If you modify the
2174  values in this array, you must make the same modifications
2175  to the double precision vertices, or call
2176  UpdateSinglePrecisonVertices().
2177  */
2178  ON_3fPointArray& SinglePrecisionVertices();
2179  const ON_3fPointArray& SinglePrecisionVertices() const;
2180 
2181  /*
2182  Description:
2183  In general,use one of
2184  ON_Mesh::SinglePrecisionVertices()
2185  or
2186  ON_Mesh::DoublePrecisionVertices()
2187  to get the array of vertex locations. If you modify
2188  m_V[] directly and HasDoublePrecisionVertices() is true,
2189  then you must make the same modifications to the array
2190  returned by DoublePrecisionVertices().
2191  */
2193 
2194  /*
2195  Returns:
2196  Location of the vertex. If double precision vertices
2197  are present, the double precision vertex location is
2198  returned. If vertex_index is out of range,
2199  ON_UNSET_VALUE is returned.
2200  */
2201  ON_3dPoint Vertex(int vertex_index) const;
2202 
2203  // m_F[] facets (triangles or quads)
2205 
2206  // m_N[] OPTIONAL vertex unit normals
2207  // If m_N[] is empty or m_N.Count() != m_V.Count(),
2208  // Either m_N[] has zero count or it m_N[j] is the
2209  // the unit vertex normal at m_V[j].
2211 
2212  // m_FN[] OPTIONAL face unit normals
2213  // If m_FN[] is empty or m_FN.Count() != m_F.Count(),
2214  // then m_FN is ignored. Otherwise m_FN[j] is the
2215  // unit normal for the facet m_F[j].
2217 
2218  /////////////////////////////////////////////////////////////////
2219  // Implementation - texture coordinates
2220  //
2221  // OPTIONAL texture coordinates for each vertex
2222 
2223  // It would be nice if this were an ON_TextureCoordinates,
2224  // but that breaks lots of checked out code that assumes
2225  // m_T is an array of ON_2fPoints.
2226  ON_MappingTag m_Ttag; // OPTIONAL tag for values in m_T[]
2227  ON_2fPointArray m_T; // OPTIONAL texture coordinates for each vertex
2228 
2229  // RUNTIME ONLY
2230  // This array is used to cache texture coordinates used by
2231  // rendering applications that require 1d texture coordinates,
2232  // 3d texture coordinates, or multiple sets of texture
2233  // coordinates (e.g. blended textures with different mappings).
2234  // Users are responsible for verifying
2235  // m_TC[i].m_T.Count() = m_V.Count()
2237 
2238  // If m_T.Count() == m_V.Count(), then the mesh has texture coordinates
2239  // and m_T[j] is the texture coordinate for vertex m_V[j].
2240  //
2241  // When opennurbs or Rhino meshes an ON_Surface or ON_Brep, the texture
2242  // coordinates have a "canonical" linear relationship with the surface
2243  // parameters that is described in the next section. However, various
2244  // mappings, spherical, planar, cylindrical, etc., can be applied that
2245  // change the values of the texture coordinates.
2246  //
2247  // If a texture mapping function was used to set the m_T[] values,
2248  // then the id and serial number of the mapping function is saved
2249  // in m_mapping_id and m_mapping_sn. The intended use of these fields
2250  // is to make it easy to avoid unnecessary recalculation.
2251  // If a mesh is modified, then m_mapping_id should be set to nil
2252  // and m_mapping_crc should be set to 0.
2253  //
2254  /////////////////////////////////////////////////////////////////
2255 
2256 
2257  /////////////////////////////////////////////////////////////////
2258  // Implementation - surface parameters and packed texture
2259  // information
2260  //
2261  // If m_S.Count() == m_V.Count(), then the mesh is a tesselation
2262  // of a parameteric surface and m_S[j] is the surface parameter at
2263  // m_V[j]. Storing values in m_S[] is OPTIONAL.
2264  //
2265  // If m_srf_scale[] has positive values, then they report
2266  // the world coordinate size of a rectangle that would
2267  // minimize texture distortion if it were mapped to the
2268  // mesh using normalized surface evaluation parameters.
2269  // This information is used to calculate high quality
2270  // packed texture coordinates.
2272  ON_Interval m_srf_domain[2]; // surface evaluation domain.
2273  double m_srf_scale[2];
2274 
2275 
2276  // Packed texture information.
2277  //
2278  // If either of the m_packed_tex_domain[] intervals is a
2279  // proper subinterval of (0,1), then a texture packing
2280  // calculation assigned this subrectangle to this mesh.
2281 
2282  ON_Interval m_packed_tex_domain[2];
2283 
2284  // The m_packed_tex_rotate setting is valid only when
2285  // m_S, m_srf_domain, m_packed_scale[] and
2286  // m_packed_tex_domain[] are all valid and the texture
2287  // coordinates are based on surface evaluation parameters.
2288  // In this special situation, this boolean records the
2289  // correspondence between the the surface parameters, (u,v),
2290  // and the packed texture coordinates, (s,t),
2291  //
2292  // m_packed_tex_rotate = false:
2293  // a = m_srf_domain[0].NormalizedParameterAt(u);
2294  // b = m_srf_domain[1].NormalizedParameterAt(v);
2295  // s = m_packed_tex_domain[0].ParameterAt(a);
2296  // t = m_packed_tex_domain[1].ParameterAt(b);
2297  //
2298  // x = m_packed_tex_domain[0].NormalizedParameterAt(s);
2299  // y = m_packed_tex_domain[1].NormalizedParameterAt(t);
2300  // u = m_srf_domain[0].ParameterAt(x);
2301  // v = m_srf_domain[1].ParameterAt(y);
2302  //
2303  // m_packed_tex_rotate = true:
2304  // a = m_srf_domain[0].NormalizedParameterAt(u);
2305  // b = m_srf_domain[1].NormalizedParameterAt(v);
2306  // s = m_packed_tex_domain[0].ParameterAt(a);
2307  // t = m_packed_tex_domain[1].ParameterAt(1.0-b);
2308  //
2309  // x = m_packed_tex_domain[0].NormalizedParameterAt(s);
2310  // y = m_packed_tex_domain[1].NormalizedParameterAt(t);
2311  // u = m_srf_domain[0].ParameterAt(y);
2312  // v = m_srf_domain[1].ParameterAt(1.0 - x);
2314 
2315  /*
2316  Returns:
2317  True if the m_srf_scale[] values are positive and
2318  the m_packed_tex_domain[] intervals are set to values
2319  that describe a proper subrectangle of (0,1)x(0,1).
2320  True does not necessarily mean the current values in
2321  m_T[] are packed texture coordinates.
2322  */
2323  bool HasPackedTextureRegion() const;
2324 
2325  /////////////////////////////////////////////////////////////////
2326  // Implementation - curvature
2327 
2328  ON_SimpleArray<ON_SurfaceCurvature> m_K; // OPTIONAL surface curvatures
2329  // Either m_K[] has zero count or it has the same
2330  // count as m_V[], in which case m_K[j] reports
2331  // the surface curvatures at m_V[j].
2332 
2333  /////////////////////////////////////////////////////////////////
2334  // Implementation - false color
2335  ON_MappingTag m_Ctag; // OPTIONAL tag for values in m_C[]
2336  ON_SimpleArray<ON_Color> m_C; // OPTIONAL vertex color
2337  // Either m_C[] has zero count or it has the same
2338  // count as m_V[], in which case m_C[j] reports
2339  // the color assigned to m_V[j].
2340 
2341  /////////////////////////////////////////////////////////////////
2342  // Implementation - runtime vertex visibility - not saved in 3dm files.
2343  ON_SimpleArray<bool> m_H; // OPTIONAL vertex visibility.
2344  // If m_H.Count() = m_V.Count(), then
2345  // m_H[vi] is true if the vertex m_V[vi]
2346  // is hidden. Otherwise, all vertices are visible.
2347  int m_hidden_count; // number of vertices that are hidden
2348  // = number of true values in m_H[] array.
2349 
2350  /////////////////////////////////////////////////////////////////
2351  // Implementation - runtime UI information
2352  const ON_Object* m_parent; // runtime parent geometry (use ...::Cast() to get it)
2353 
2354 protected:
2355  friend class ON_MeshVertexRef;
2356  friend class ON_MeshEdgeRef;
2357  friend class ON_MeshFaceRef;
2358 
2359 
2360  /////////////////////////////////////////////////////////////////
2361  // Implementation - mesh topology
2363 
2364  ON_MeshParameters* m_mesh_parameters; // If mesh was created from a parametric surface,
2365  // these parameters were used to create the mesh.
2369 
2370 private:
2371  char m_mesh_is_closed; // 0 = unset, 1 = all edges have 2 or more faces, 2 = at least one boundary edge
2372  char m_mesh_is_manifold; // 0 = unset, 1 = all edges have 1 or 2 faces, 2 = not manifold
2373  char m_mesh_is_oriented; // 0 = unset, 1 = faces normals agree across all edges that have 2 faces, 2 = not oriented
2374  char m_mesh_is_solid; // 0 = unset, 1 = solid with outward face normals, 2 = solid with inward face normals, 3 = not solid
2375 
2376 protected:
2377  // The bounding boxes are valid if m_?box[0][0] <= m_?box[0][1];
2378  float m_vbox[2][3]; // 3d bounding box of all referenced vertices
2379  float m_nbox[2][3]; // 3d bounding box of all referenced unit normals
2380  // (for estimation of Gauss map bounds)
2381  float m_tbox[2][2]; // 2d bounding box of all referenced texture coordinates
2382  ON_MeshCurvatureStats* m_kstat[4]; // gaussian,mean,min,max,sectionx,sectiony,sectionz
2383 
2384  // sub-mesh information rendering large meshes
2386 
2387 private:
2388  bool Write_1( ON_BinaryArchive& ) const; // uncompressed 1.x format
2389  bool Write_2( int, ON_BinaryArchive& ) const; // compressed 2.x format
2390  bool Read_1( ON_BinaryArchive& );
2391  bool Read_2( int, ON_BinaryArchive& );
2392  bool WriteFaceArray( int, int, ON_BinaryArchive& ) const;
2393  bool ReadFaceArray( int, int, ON_BinaryArchive& );
2394  bool SwapEdge_Helper( int, bool );
2395 };
2396 
2397 class ON_CLASS ON_MeshVertexRef : public ON_Geometry
2398 {
2399  ON_OBJECT_DECLARE(ON_MeshVertexRef);
2400 public:
2401  ON_MeshVertexRef();
2402  ~ON_MeshVertexRef();
2403  ON_MeshVertexRef& operator=(const ON_MeshVertexRef&);
2404 
2405 
2406  // parent mesh
2407  const ON_Mesh* m_mesh;
2408 
2409  // m_mesh->m_V[] index
2410  // (can be -1 when m_top_vi references a shared vertex location)
2412 
2413  // m_mesh->m_top.m_tope[] index
2414  int m_top_vi;
2415 
2416 
2417  /*
2418  Description:
2419  Override of the virtual ON_Geometry::ComponentIndex().
2420  Returns:
2421  A component index for the vertex. The type of the returned
2422  component index can be
2423  ON_COMPONENT_INDEX::mesh_vertex,
2424  ON_COMPONENT_INDEX::meshtop_vertex, or
2425  ON_COMPONENT_INDEX::invalid_type.
2426  */
2427  ON_COMPONENT_INDEX ComponentIndex() const;
2428 
2429  /*
2430  Returns:
2431  The mesh topology associated with this
2432  mesh vertex reference or NULL if it doesn't
2433  exist.
2434  */
2435  const ON_MeshTopology* MeshTopology() const;
2436 
2437  /*
2438  Returns:
2439  The 3d location of the mesh vertex. Returns
2440  ON_UNSET_POINT is this ON_MeshVertexRef is not
2441  valid.
2442  */
2443  ON_3dPoint Point() const;
2444 
2445  /*
2446  Returns:
2447  The mesh topology vertex associated with this
2448  mesh vertex reference.
2449  */
2450  const ON_MeshTopologyVertex* MeshTopologyVertex() const;
2451 
2452  // overrides of virtual ON_Object functions
2453  ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
2454  void Dump( ON_TextLog& ) const;
2455  unsigned int SizeOf() const;
2456  ON::object_type ObjectType() const;
2457 
2458  // overrides of virtual ON_Geometry functions
2459  int Dimension() const;
2460  ON_BOOL32 GetBBox(
2461  double* boxmin,
2462  double* boxmax,
2463  int bGrowBox = false
2464  ) const;
2465  ON_BOOL32 Transform(
2466  const ON_Xform& xform
2467  );
2468 };
2469 
2470 class ON_CLASS ON_MeshEdgeRef : public ON_Geometry
2471 {
2472  ON_OBJECT_DECLARE(ON_MeshEdgeRef);
2473 public:
2474  ON_MeshEdgeRef();
2475  ~ON_MeshEdgeRef();
2476  ON_MeshEdgeRef& operator=(const ON_MeshEdgeRef&);
2477 
2478  // parent mesh
2479  const ON_Mesh* m_mesh;
2480 
2481  // m_mesh->m_top.m_tope[] index
2482  int m_top_ei;
2483 
2484  /*
2485  Description:
2486  Override of the virtual ON_Geometry::ComponentIndex().
2487  Returns:
2488  A mesh component index for the edge. The type is
2489  ON_COMPONENT_INDEX::meshtop_edge and the index is the
2490  index into the ON_MeshTopology.m_tope[] array.
2491  */
2492  ON_COMPONENT_INDEX ComponentIndex() const;
2493 
2494  /*
2495  Returns:
2496  The mesh topology associated with this
2497  mesh edge reference or NULL if it doesn't
2498  exist.
2499  */
2500 
2501  const ON_MeshTopology* MeshTopology() const;
2502  /*
2503  Returns:
2504  The 3d location of the mesh edge. Returns
2505  ON_UNSET_POINT,ON_UNSET_POINT, is this ON_MeshEdgeRef
2506  is not valid.
2507  */
2508  ON_Line Line() const;
2509 
2510  /*
2511  Returns:
2512  The mesh topology edge associated with this
2513  mesh edge reference.
2514  */
2515  const ON_MeshTopologyEdge* MeshTopologyEdge() const;
2516 
2517  // overrides of virtual ON_Object functions
2518  ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
2519  void Dump( ON_TextLog& ) const;
2520  unsigned int SizeOf() const;
2521  ON::object_type ObjectType() const;
2522 
2523  // overrides of virtual ON_Geometry functions
2524  int Dimension() const;
2525  ON_BOOL32 GetBBox(
2526  double* boxmin,
2527  double* boxmax,
2528  int bGrowBox = false
2529  ) const;
2530  ON_BOOL32 Transform(
2531  const ON_Xform& xform
2532  );
2533 };
2534 
2535 class ON_CLASS ON_MeshFaceRef : public ON_Geometry
2536 {
2537  ON_OBJECT_DECLARE(ON_MeshFaceRef);
2538 public:
2539  ON_MeshFaceRef();
2540  ~ON_MeshFaceRef();
2541  ON_MeshFaceRef& operator=(const ON_MeshFaceRef&);
2542 
2543  // parent mesh
2544  const ON_Mesh* m_mesh;
2545 
2546  // m_mesh->m_F[] and m_mesh->m_top.m_tope[] index.
2548 
2549  /*
2550  Description:
2551  Override of the virtual ON_Geometry::ComponentIndex().
2552  Returns:
2553  A mesh component index for the face. The type is
2554  ON_COMPONENT_INDEX::mesh_face and the index is the
2555  index into the ON_Mesh.m_F[] array.
2556  */
2557  ON_COMPONENT_INDEX ComponentIndex() const;
2558 
2559  /*
2560  Returns:
2561  The mesh topology associated with this
2562  mesh face reference or NULL if it doesn't
2563  exist.
2564  */
2565  const ON_MeshTopology* MeshTopology() const;
2566 
2567  /*
2568  Returns:
2569  The mesh face associated with this mesh face reference.
2570  */
2571  const ON_MeshFace* MeshFace() const;
2572 
2573  /*
2574  Returns:
2575  The mesh topology face associated with this
2576  mesh face reference.
2577  */
2578  const ON_MeshTopologyFace* MeshTopologyFace() const;
2579 
2580  // overrides of virtual ON_Object functions
2581  ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
2582  void Dump( ON_TextLog& ) const;
2583  unsigned int SizeOf() const;
2584  ON::object_type ObjectType() const;
2585 
2586  // overrides of virtual ON_Geometry functions
2587  int Dimension() const;
2588  ON_BOOL32 GetBBox(
2589  double* boxmin,
2590  double* boxmax,
2591  int bGrowBox = false
2592  ) const;
2593  ON_BOOL32 Transform(
2594  const ON_Xform& xform
2595  );
2596 };
2597 
2598 /*
2599 Description:
2600  Calculate a mesh representation of the NURBS surface's control polygon.
2601 Parameters:
2602  nurbs_surface - [in]
2603  bCleanMesh - [in] If true, then degenerate quads are cleaned
2604  up to be triangles. Surfaces with singular
2605  sides are a common source of degenerate qauds.
2606  input_mesh - [in] If NULL, then the returned mesh is created
2607  by a class to new ON_Mesh(). If not null, then this
2608  mesh will be used to store the conrol polygon.
2609 Returns:
2610  If successful, a pointer to a mesh.
2611 */
2612 ON_DECL
2613 ON_Mesh* ON_ControlPolygonMesh(
2614  const ON_NurbsSurface& nurbs_surface,
2615  bool bCleanMesh,
2616  ON_Mesh* input_mesh = NULL
2617  );
2618 
2619 /*
2620 Description:
2621  Finds the unit normal to the triangle
2622 Parameters:
2623  A - [in] triangle corner
2624  B - [in] triangle corner
2625  C - [in] triangle corner
2626 Returns:
2627  Unit normal
2628 */
2629 ON_DECL
2630 ON_3dVector ON_TriangleNormal(
2631  const ON_3dPoint& A,
2632  const ON_3dPoint& B,
2633  const ON_3dPoint& C
2634  );
2635 
2636 
2637 /*
2638 Description:
2639  Finds the unit normal to the triangle
2640 Parameters:
2641  A - [in] triangle corner
2642  B - [in] triangle corner
2643  C - [in] triangle corner
2644  a - [out] must not be null
2645  b - [out] must not be null
2646  c - [out] must not be null
2647  d - [out] must not be null
2648  The equation of the plane is a*x + b*y + c*z + d = 0
2649  ev_tol - [out]
2650  If ev_tol is not null, then it is the maximum absolute
2651  value of the plane equation evaluated at A,B,C. Mathematically,
2652  ev_tol is zero. Since these computations are performed with
2653  finite precision doubles, ev_tol is generally not zero.
2654 Returns:
2655  Unit normal
2656 */
2657 ON_DECL
2658 bool ON_GetTrianglePlaneEquation(
2659  const ON_3dPoint& A,
2660  const ON_3dPoint& B,
2661  const ON_3dPoint& C,
2662  double* a,
2663  double* b,
2664  double* c,
2665  double* d,
2666  double* evaluation_tol
2667  );
2668 
2669 #endif
int m_partition_max_vertex_count
ON_MappingTag m_Ttag
ON_MeshPartition * m_partition
ON_MeshParameters * m_mesh_parameters
int m_quad_count
ON::curvature_style m_style
unsigned char m_mesher
ON_2fPointArray m_T
ON_SimpleArray< ON_SurfaceCurvature > m_K
int m_invalid_count
bool m_packed_tex_rotate
ON_ClassArray< ON_TextureCoordinates > m_TC
const ON_Mesh * m_mesh
ON_SimpleArray< struct ON_MeshPart > m_part
ON_3fPointArray m_V
ON_SimpleArray< ON_MeshTopologyFace > m_topf
ON_Xform m_mesh_xform
ON_2dPointArray m_S
ON_MeshTopology m_top
ON_SimpleArray< bool > m_H
const ON_Mesh * m_mesh
ON_SimpleArray< ON_MeshTopologyVertex > m_topv
ON__UINT32 m_mapping_crc
ON_3fVectorArray m_FN
ON_TextureMapping::TYPE m_mapping_type
const ON_Object * m_parent
ON_SimpleArray< int > m_topv_map
ON_SimpleArray< ON_3fPoint > m_T
ON_SimpleArray< ON_Color > m_C
ON_3fVectorArray m_N
unsigned short value
unsigned char dir
ON_SimpleArray< ON_MeshTopologyEdge > m_tope
static const ON_MeshParameters FastRenderMesh
unsigned char side
const ON_Mesh * m_mesh
ON_SimpleArray< ON_MeshFace > m_F
ON_MappingTag m_Ctag
ON_UUID m_mapping_id
int m_hidden_count
int m_partition_max_triangle_count
const ON_Mesh * m_mesh
friend class ON_MeshVertexRef
static const ON_MeshParameters QualityRenderMesh
friend class ON_MeshEdgeRef
int m_triangle_count
Definition: norms.h:54
friend class ON_Mesh
friend class ON_MeshFaceRef