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 29 enum MESH_STYLE 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 47 const ON_MeshParameters FastRenderMesh; 48 49 /* 50 Description: 51 Parameters that create render meshes where mesh quality 52 is prefered over meshing speed. 53 */ 54 static 55 const ON_MeshParameters QualityRenderMesh; 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 90 ON_MeshParameters(); 91 ~ON_MeshParameters(); 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: 275 ON_MeshCurvatureStats(); 276 ~ON_MeshCurvatureStats(); 277 ON_MeshCurvatureStats(const ON_MeshCurvatureStats& ); 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 303 ON_Interval m_range; 304 }; 305 306 /////////////////////////////////////////////////////////////////////////////// 307 // 308 // Class ON_MeshTopology 309 // 310 311 struct ON_MeshTopologyVertex 312 { 313 // m_tope_count = number of topological edges that begin or 314 // end at this topological vertex. 315 int m_tope_count; 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. 326 int m_v_count; 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 333 struct ON_MeshTopologyEdge 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 340 int m_topf_count; 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 514 struct ON_MeshFaceSide 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 541 struct ON_MeshPart 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]. 745 ON_SimpleArray<int> m_topv_map; 746 747 //////////// 748 // Array of topological mesh vertices. See the comments in the definition 749 // of ON_MeshTopologyVertex for details. 750 ON_SimpleArray<ON_MeshTopologyVertex> m_topv; 751 752 //////////// 753 // Array of topological mesh edges. See the comments in the definition 754 // of ON_MeshTopologyEdge for details. 755 ON_SimpleArray<ON_MeshTopologyEdge> m_tope; 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]] 764 ON_SimpleArray<ON_MeshTopologyFace> m_topf; 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 801 ON_MeshTopology(const ON_MeshTopology&); 802 ON_MeshTopology& operator=(const ON_MeshTopology&); 803 }; 804 805 struct ON_MeshNgon 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(); 831 ON_MeshNgonList(const 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: 894 ON_MeshPartition(); 895 ~ON_MeshPartition(); 896 897 // maximum number of vertices in a partition 898 int m_partition_max_vertex_count; 899 // maximum number of triangles in a partition (quads count as 2 triangles) 900 int m_partition_max_triangle_count; 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] 910 ON_SimpleArray<struct ON_MeshPart> m_part; 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() 964 ON_Xform m_mesh_xform; 965 }; 966 967 class ON_CLASS ON_TextureCoordinates 968 { 969 public: 970 ON_TextureCoordinates(); 971 972 ON_MappingTag m_tag; 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, 1219 ON_MeshCurvatureStats& 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, 1574 ON_SimpleArray<ON_2dex>& edges 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( 1590 ON_SimpleArray<ON_2dex>& edges 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 */ 2192 ON_3fPointArray m_V; 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) 2204 ON_SimpleArray<ON_MeshFace> m_F; 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]. 2210 ON_3fVectorArray m_N; 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]. 2216 ON_3fVectorArray m_FN; 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() 2236 ON_ClassArray<ON_TextureCoordinates> m_TC; 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. 2271 ON_2dPointArray m_S; 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); 2313 bool m_packed_tex_rotate; 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 2362 ON_MeshTopology m_top; 2363 2364 ON_MeshParameters* m_mesh_parameters; // If mesh was created from a parametric surface, 2365 // these parameters were used to create the mesh. 2366 int m_invalid_count; 2367 int m_quad_count; 2368 int m_triangle_count; 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 2385 ON_MeshPartition* m_partition; 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) 2411 int m_mesh_vi; 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. 2547 int m_mesh_fi; 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 2670