Changeset View
Changeset View
Standalone View
Standalone View
extern/opennurbs/opennurbs_objref.cpp
- This file was added.
| /* $NoKeywords: $ */ | |||||
| /* | |||||
| // | |||||
| // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. | |||||
| // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert | |||||
| // McNeel & Associates. | |||||
| // | |||||
| // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. | |||||
| // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF | |||||
| // MERCHANTABILITY ARE HEREBY DISCLAIMED. | |||||
| // | |||||
| // For complete openNURBS copyright information see <http://www.opennurbs.org>. | |||||
| // | |||||
| //////////////////////////////////////////////////////////////// | |||||
| */ | |||||
| #include "opennurbs.h" | |||||
| #if !defined(ON_COMPILING_OPENNURBS) | |||||
| // This check is included in all opennurbs source .c and .cpp files to insure | |||||
| // ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled. | |||||
| // When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined | |||||
| // and the opennurbs .h files alter what is declared and how it is declared. | |||||
| #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs | |||||
| #endif | |||||
| ON_COMPONENT_INDEX::ON_COMPONENT_INDEX() | |||||
| : m_type(ON_COMPONENT_INDEX::invalid_type), | |||||
| m_index(-1) | |||||
| { | |||||
| } | |||||
| ON_COMPONENT_INDEX::ON_COMPONENT_INDEX( | |||||
| ON_COMPONENT_INDEX::TYPE type, | |||||
| int index | |||||
| ) | |||||
| : m_type(type), | |||||
| m_index(index) | |||||
| { | |||||
| } | |||||
| ON_COMPONENT_INDEX::TYPE ON_COMPONENT_INDEX::Type(int i) | |||||
| { | |||||
| TYPE t = invalid_type; | |||||
| switch((unsigned int)i) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::no_type: t = ON_COMPONENT_INDEX::no_type; break; | |||||
| case ON_COMPONENT_INDEX::brep_vertex: t = ON_COMPONENT_INDEX::brep_vertex; break; | |||||
| case ON_COMPONENT_INDEX::brep_edge: t = ON_COMPONENT_INDEX::brep_edge; break; | |||||
| case ON_COMPONENT_INDEX::brep_face: t = ON_COMPONENT_INDEX::brep_face; break; | |||||
| case ON_COMPONENT_INDEX::brep_trim: t = ON_COMPONENT_INDEX::brep_trim; break; | |||||
| case ON_COMPONENT_INDEX::brep_loop: t = ON_COMPONENT_INDEX::brep_loop; break; | |||||
| case ON_COMPONENT_INDEX::mesh_vertex: t = ON_COMPONENT_INDEX::mesh_vertex; break; | |||||
| case ON_COMPONENT_INDEX::meshtop_vertex: t = ON_COMPONENT_INDEX::meshtop_vertex; break; | |||||
| case ON_COMPONENT_INDEX::meshtop_edge: t = ON_COMPONENT_INDEX::meshtop_edge; break; | |||||
| case ON_COMPONENT_INDEX::mesh_face: t = ON_COMPONENT_INDEX::mesh_face; break; | |||||
| case ON_COMPONENT_INDEX::mesh_ngon: t = ON_COMPONENT_INDEX::mesh_ngon; break; | |||||
| case ON_COMPONENT_INDEX::idef_part: t = ON_COMPONENT_INDEX::idef_part; break; | |||||
| case ON_COMPONENT_INDEX::polycurve_segment: t = ON_COMPONENT_INDEX::polycurve_segment; break; | |||||
| case ON_COMPONENT_INDEX::pointcloud_point: t = ON_COMPONENT_INDEX::pointcloud_point; break; | |||||
| case ON_COMPONENT_INDEX::group_member: t = ON_COMPONENT_INDEX::group_member; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_bottom_profile: t = ON_COMPONENT_INDEX::extrusion_bottom_profile; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_top_profile: t = ON_COMPONENT_INDEX::extrusion_top_profile; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_wall_edge: t = ON_COMPONENT_INDEX::extrusion_wall_edge; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_wall_surface: t = ON_COMPONENT_INDEX::extrusion_wall_surface; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_cap_surface: t = ON_COMPONENT_INDEX::extrusion_cap_surface; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_path: t = ON_COMPONENT_INDEX::extrusion_path; break; | |||||
| case ON_COMPONENT_INDEX::subd_vertex: t = ON_COMPONENT_INDEX::subd_vertex; break; | |||||
| case ON_COMPONENT_INDEX::subd_edge: t = ON_COMPONENT_INDEX::subd_edge; break; | |||||
| case ON_COMPONENT_INDEX::subd_face: t = ON_COMPONENT_INDEX::subd_face; break; | |||||
| case ON_COMPONENT_INDEX::hatch_loop: t = ON_COMPONENT_INDEX::hatch_loop; break; | |||||
| case ON_COMPONENT_INDEX::dim_linear_point: t = ON_COMPONENT_INDEX::dim_linear_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_radial_point: t = ON_COMPONENT_INDEX::dim_radial_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_angular_point: t = ON_COMPONENT_INDEX::dim_angular_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_ordinate_point: t = ON_COMPONENT_INDEX::dim_ordinate_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_text_point: t = ON_COMPONENT_INDEX::dim_text_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_centermark_point: t = ON_COMPONENT_INDEX::dim_centermark_point; break; | |||||
| case ON_COMPONENT_INDEX::dim_leader_point: t = ON_COMPONENT_INDEX::dim_leader_point; break; | |||||
| } | |||||
| return t; | |||||
| } | |||||
| void ON_COMPONENT_INDEX::Set( | |||||
| ON_COMPONENT_INDEX::TYPE type, | |||||
| int index | |||||
| ) | |||||
| { | |||||
| m_type = type; | |||||
| m_index = index; | |||||
| } | |||||
| void ON_COMPONENT_INDEX::Set( | |||||
| ON_COMPONENT_INDEX::TYPE type, | |||||
| unsigned int index | |||||
| ) | |||||
| { | |||||
| m_type = type; | |||||
| m_index = (int)index; | |||||
| } | |||||
| void ON_COMPONENT_INDEX::UnSet() | |||||
| { | |||||
| m_type = ON_COMPONENT_INDEX::invalid_type; | |||||
| m_index = -1; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsMeshComponentIndex() const | |||||
| { | |||||
| bool rc = false; | |||||
| switch(m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::mesh_vertex: | |||||
| case ON_COMPONENT_INDEX::meshtop_vertex: | |||||
| case ON_COMPONENT_INDEX::meshtop_edge: | |||||
| case ON_COMPONENT_INDEX::mesh_face: | |||||
| case ON_COMPONENT_INDEX::mesh_ngon: | |||||
| if ( m_index >= 0 ) | |||||
| { | |||||
| rc = true; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values | |||||
| break; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsSubDComponentIndex() const | |||||
| { | |||||
| bool rc = false; | |||||
| switch(m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::subd_vertex: | |||||
| case ON_COMPONENT_INDEX::subd_edge: | |||||
| case ON_COMPONENT_INDEX::subd_face: | |||||
| if ( -1 != m_index && 0 != m_index ) | |||||
| { | |||||
| rc = true; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values | |||||
| break; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsAnnotationComponentIndex() const | |||||
| { | |||||
| bool rc = false; | |||||
| switch(m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::dim_linear_point: | |||||
| case ON_COMPONENT_INDEX::dim_radial_point: | |||||
| case ON_COMPONENT_INDEX::dim_angular_point: | |||||
| case ON_COMPONENT_INDEX::dim_ordinate_point: | |||||
| case ON_COMPONENT_INDEX::dim_text_point: | |||||
| if ( m_index >= 0 ) | |||||
| { | |||||
| rc = true; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values | |||||
| break; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsBrepComponentIndex() const | |||||
| { | |||||
| bool rc = false; | |||||
| switch(m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::brep_vertex: | |||||
| case ON_COMPONENT_INDEX::brep_trim: | |||||
| case ON_COMPONENT_INDEX::brep_loop: | |||||
| case ON_COMPONENT_INDEX::brep_edge: | |||||
| case ON_COMPONENT_INDEX::brep_face: | |||||
| if ( m_index >= 0 ) | |||||
| { | |||||
| rc = true; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values | |||||
| break; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsIDefComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::idef_part == m_type && m_index >= 0 ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsPolyCurveComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::polycurve_segment == m_type && m_index >= 0 ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsGroupMemberComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::group_member == m_type && m_index >= 0 ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionProfileComponentIndex() const | |||||
| { | |||||
| return ( ( ON_COMPONENT_INDEX::extrusion_bottom_profile == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_top_profile == m_type | |||||
| ) | |||||
| && m_index >= 0 | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionPathComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::extrusion_path == m_type | |||||
| && m_index >= -1 | |||||
| && m_index <= 1 | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionWallEdgeComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::extrusion_wall_edge == m_type | |||||
| && m_index >= 0 | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionWallSurfaceComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::extrusion_wall_surface == m_type | |||||
| && m_index >= 0 | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionWallComponentIndex() const | |||||
| { | |||||
| return ( ( ON_COMPONENT_INDEX::extrusion_wall_edge == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_wall_surface == m_type | |||||
| ) | |||||
| && m_index >= 0 | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsExtrusionComponentIndex() const | |||||
| { | |||||
| return ( ( ON_COMPONENT_INDEX::extrusion_bottom_profile == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_top_profile == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_wall_edge == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_wall_surface == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_cap_surface == m_type | |||||
| || ON_COMPONENT_INDEX::extrusion_path == m_type | |||||
| ) | |||||
| && | |||||
| ( m_index >= 0 | |||||
| || (-1 == m_index && ON_COMPONENT_INDEX::extrusion_path == m_type) | |||||
| ) | |||||
| ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsPointCloudComponentIndex() const | |||||
| { | |||||
| return ( ON_COMPONENT_INDEX::pointcloud_point == m_type && m_index >= 0 ); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsHatchLoopComponentIndex() const | |||||
| { | |||||
| return (ON_COMPONENT_INDEX::hatch_loop == m_type && m_index >= 0); | |||||
| } | |||||
| static void ToStringHelper( ON_COMPONENT_INDEX ci, char* buffer, size_t sizeof_buffer ) | |||||
| { | |||||
| char* str = buffer; | |||||
| size_t str_capacity = sizeof_buffer/sizeof(buffer[0]); | |||||
| const char* s; | |||||
| const char* str_end; | |||||
| char ubuffer[32]; // unsigned int to string storage ubuffer | |||||
| unsigned int i, j; | |||||
| if ( nullptr == str || str_capacity <= 0 ) | |||||
| return; | |||||
| str[--str_capacity] = 0; | |||||
| if (str_capacity <= 0) | |||||
| return; | |||||
| str_end = str + str_capacity; | |||||
| s = "m_type="; | |||||
| while ( str < str_end ) | |||||
| { | |||||
| const char c = *s++; | |||||
| if (0 == c) | |||||
| break; | |||||
| *str++ = c; | |||||
| } | |||||
| switch(ci.m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::no_type: s = "ON_COMPONENT_INDEX::no_type"; break; | |||||
| case ON_COMPONENT_INDEX::brep_vertex: s = "ON_COMPONENT_INDEX::brep_vertex"; break; | |||||
| case ON_COMPONENT_INDEX::brep_edge: s = "ON_COMPONENT_INDEX::brep_edge"; break; | |||||
| case ON_COMPONENT_INDEX::brep_face: s = "ON_COMPONENT_INDEX::brep_face"; break; | |||||
| case ON_COMPONENT_INDEX::brep_trim: s = "ON_COMPONENT_INDEX::brep_trim"; break; | |||||
| case ON_COMPONENT_INDEX::brep_loop: s = "ON_COMPONENT_INDEX::brep_loop"; break; | |||||
| case ON_COMPONENT_INDEX::mesh_vertex: s = "ON_COMPONENT_INDEX::mesh_vertex"; break; | |||||
| case ON_COMPONENT_INDEX::meshtop_vertex: s = "ON_COMPONENT_INDEX::meshtop_vertex"; break; | |||||
| case ON_COMPONENT_INDEX::meshtop_edge: s = "ON_COMPONENT_INDEX::meshtop_edge"; break; | |||||
| case ON_COMPONENT_INDEX::mesh_face: s = "ON_COMPONENT_INDEX::mesh_face"; break; | |||||
| case ON_COMPONENT_INDEX::mesh_ngon: s = "ON_COMPONENT_INDEX::mesh_ngon"; break; | |||||
| case ON_COMPONENT_INDEX::idef_part: s = "ON_COMPONENT_INDEX::idef_part"; break; | |||||
| case ON_COMPONENT_INDEX::polycurve_segment: s = "ON_COMPONENT_INDEX::polycurve_segment"; break; | |||||
| case ON_COMPONENT_INDEX::pointcloud_point: s = "ON_COMPONENT_INDEX::pointcloud_point"; break; | |||||
| case ON_COMPONENT_INDEX::group_member: s = "ON_COMPONENT_INDEX::group_member"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_bottom_profile: s = "ON_COMPONENT_INDEX::extrusion_bottom_profile"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_top_profile: s = "ON_COMPONENT_INDEX::extrusion_top_profile"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_wall_edge: s = "ON_COMPONENT_INDEX::extrusion_wall_edge"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_wall_surface: s = "ON_COMPONENT_INDEX::extrusion_wall_surface"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_cap_surface: s = "ON_COMPONENT_INDEX::extrusion_cap_surface"; break; | |||||
| case ON_COMPONENT_INDEX::extrusion_path: s = "ON_COMPONENT_INDEX::extrusion_path"; break; | |||||
| case ON_COMPONENT_INDEX::subd_vertex: s = "ON_COMPONENT_INDEX::subd_vertex"; break; | |||||
| case ON_COMPONENT_INDEX::subd_edge: s = "ON_COMPONENT_INDEX::subd_edge"; break; | |||||
| case ON_COMPONENT_INDEX::subd_face: s = "ON_COMPONENT_INDEX::subd_face"; break; | |||||
| case ON_COMPONENT_INDEX::hatch_loop: s = "ON_COMPONENT_INDEX::hatch_loop"; break; | |||||
| case ON_COMPONENT_INDEX::dim_linear_point: s = "ON_COMPONENT_INDEX::dim_linear_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_radial_point: s = "ON_COMPONENT_INDEX::dim_radial_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_angular_point: s = "ON_COMPONENT_INDEX::dim_angular_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_ordinate_point: s = "ON_COMPONENT_INDEX::dim_ordinate_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_text_point: s = "ON_COMPONENT_INDEX::dim_text_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_centermark_point: s = "ON_COMPONENT_INDEX::dim_centermark_point"; break; | |||||
| case ON_COMPONENT_INDEX::dim_leader_point: s = "ON_COMPONENT_INDEX::dim_leader_point"; break; | |||||
| default: s = 0; break; | |||||
| } | |||||
| if ( 0 != s ) | |||||
| { | |||||
| while ( str < str_end ) | |||||
| { | |||||
| const char c = *s++; | |||||
| if (0 == c) | |||||
| break; | |||||
| *str++ = c; | |||||
| } | |||||
| } | |||||
| s = " m_index="; | |||||
| while ( str < str_end ) | |||||
| { | |||||
| const char c = *s++; | |||||
| if (0 == c) | |||||
| break; | |||||
| *str++ = c; | |||||
| } | |||||
| if ( ci.m_index < 1 ) | |||||
| { | |||||
| i = (unsigned int)(-ci.m_index); | |||||
| s = "-"; | |||||
| while ( str < str_end ) | |||||
| { | |||||
| const char c = *s++; | |||||
| if (0 == c) | |||||
| break; | |||||
| *str++ = c; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| i = (unsigned int)(ci.m_index); | |||||
| } | |||||
| j = sizeof(ubuffer)/sizeof(ubuffer[0]); | |||||
| j--; | |||||
| ubuffer[j] = 0; | |||||
| while(j > 0) | |||||
| { | |||||
| j--; | |||||
| ubuffer[j] = (char)('0'+i%10); | |||||
| i /= 10; | |||||
| if ( 0 == i ) | |||||
| break; | |||||
| } | |||||
| s = &ubuffer[j]; | |||||
| while ( str < str_end ) | |||||
| { | |||||
| if ( 0 == (*str++ = *s++)) | |||||
| break; | |||||
| } | |||||
| } | |||||
| void ON_COMPONENT_INDEX::Dump( | |||||
| class ON_TextLog& text_log | |||||
| )const | |||||
| { | |||||
| char buffer[128]; | |||||
| ToStringHelper(*this,buffer,sizeof(buffer)); | |||||
| text_log.Print(buffer); | |||||
| } | |||||
| void ON_COMPONENT_INDEX::AppendToString( | |||||
| class ON_String& s | |||||
| )const | |||||
| { | |||||
| char buffer[128]; | |||||
| ToStringHelper(*this,buffer,sizeof(buffer)); | |||||
| s += buffer; | |||||
| } | |||||
| void ON_COMPONENT_INDEX::AppendToString( | |||||
| class ON_wString& s | |||||
| )const | |||||
| { | |||||
| char buffer[128]; | |||||
| ToStringHelper(*this,buffer,sizeof(buffer)); | |||||
| s += buffer; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsNotSet() const | |||||
| { | |||||
| return (false == IsSet()); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::IsSet() const | |||||
| { | |||||
| bool rc = false; | |||||
| switch(m_type) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::invalid_type: | |||||
| rc = false; | |||||
| break; | |||||
| case ON_COMPONENT_INDEX::no_type: | |||||
| rc = false; | |||||
| break; | |||||
| case ON_COMPONENT_INDEX::brep_vertex: | |||||
| case ON_COMPONENT_INDEX::brep_edge: | |||||
| case ON_COMPONENT_INDEX::brep_face: | |||||
| case ON_COMPONENT_INDEX::brep_trim: | |||||
| case ON_COMPONENT_INDEX::brep_loop: | |||||
| case ON_COMPONENT_INDEX::mesh_vertex: | |||||
| case ON_COMPONENT_INDEX::meshtop_vertex: | |||||
| case ON_COMPONENT_INDEX::meshtop_edge: | |||||
| case ON_COMPONENT_INDEX::mesh_face: | |||||
| case ON_COMPONENT_INDEX::mesh_ngon: | |||||
| case ON_COMPONENT_INDEX::idef_part: | |||||
| case ON_COMPONENT_INDEX::polycurve_segment: | |||||
| case ON_COMPONENT_INDEX::pointcloud_point: | |||||
| case ON_COMPONENT_INDEX::group_member: | |||||
| case ON_COMPONENT_INDEX::subd_vertex: | |||||
| case ON_COMPONENT_INDEX::subd_edge: | |||||
| case ON_COMPONENT_INDEX::subd_face: | |||||
| case ON_COMPONENT_INDEX::hatch_loop: | |||||
| case ON_COMPONENT_INDEX::dim_linear_point: | |||||
| case ON_COMPONENT_INDEX::dim_radial_point: | |||||
| case ON_COMPONENT_INDEX::dim_angular_point: | |||||
| case ON_COMPONENT_INDEX::dim_ordinate_point: | |||||
| case ON_COMPONENT_INDEX::dim_text_point: | |||||
| case ON_COMPONENT_INDEX::dim_centermark_point: | |||||
| case ON_COMPONENT_INDEX::dim_leader_point: | |||||
| rc = (m_index != -1); | |||||
| break; | |||||
| default: | |||||
| rc = false; | |||||
| break; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| int ON_COMPONENT_INDEX::CompareType( const ON_COMPONENT_INDEX* lhs, const ON_COMPONENT_INDEX* rhs ) | |||||
| { | |||||
| const int lhs_i = (int)lhs->m_type; | |||||
| const int rhs_i = (int)rhs->m_type; | |||||
| if (lhs_i < rhs_i) | |||||
| return -1; | |||||
| if (lhs_i > rhs_i) | |||||
| return 1; | |||||
| return 0; | |||||
| } | |||||
| int ON_COMPONENT_INDEX::Compare( const ON_COMPONENT_INDEX* lhs, const ON_COMPONENT_INDEX* rhs ) | |||||
| { | |||||
| const int lhs_i = (int)lhs->m_type; | |||||
| const int rhs_i = (int)rhs->m_type; | |||||
| if (lhs_i < rhs_i) | |||||
| return -1; | |||||
| if (lhs_i > rhs_i) | |||||
| return 1; | |||||
| if (lhs->m_index < rhs->m_index) | |||||
| return -1; | |||||
| if (lhs->m_index > rhs->m_index) | |||||
| return 1; | |||||
| return 0; | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator==(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (m_type == other.m_type && m_index == other.m_index); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator!=(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (m_type != other.m_type || m_index != other.m_index); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator<(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (ON_COMPONENT_INDEX::Compare(this,&other) < 0); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator<=(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (ON_COMPONENT_INDEX::Compare(this,&other) <= 0); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator>(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (ON_COMPONENT_INDEX::Compare(this,&other) > 0); | |||||
| } | |||||
| bool ON_COMPONENT_INDEX::operator>=(const ON_COMPONENT_INDEX& other) const | |||||
| { | |||||
| return (ON_COMPONENT_INDEX::Compare(this,&other) >= 0); | |||||
| } | |||||
| ON_ObjRefEvaluationParameter::ON_ObjRefEvaluationParameter() | |||||
| : m_t_type(0) | |||||
| , m_reserved(0) | |||||
| { | |||||
| m_t[0] = ON_UNSET_VALUE; | |||||
| m_t[1] = ON_UNSET_VALUE; | |||||
| m_t[2] = ON_UNSET_VALUE; | |||||
| m_t[3] = ON_UNSET_VALUE; | |||||
| } | |||||
| void ON_ObjRefEvaluationParameter::Default() | |||||
| { | |||||
| ON_ObjRefEvaluationParameter d; | |||||
| *this = d; | |||||
| } | |||||
| ON_ObjRefEvaluationParameter::~ON_ObjRefEvaluationParameter() | |||||
| { | |||||
| } | |||||
| bool ON_ObjRefEvaluationParameter::Write( ON_BinaryArchive& archive ) const | |||||
| { | |||||
| bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0); | |||||
| if (!rc) | |||||
| return rc; | |||||
| for(;;) | |||||
| { | |||||
| rc = archive.WriteInt(m_t_type); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteComponentIndex(m_t_ci); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteDouble(4,m_t); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInterval(m_s[0]); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInterval(m_s[1]); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInterval(m_s[2]); | |||||
| if (!rc) break; | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndWrite3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| bool ON_ObjRefEvaluationParameter::Read( ON_BinaryArchive& archive ) | |||||
| { | |||||
| Default(); | |||||
| int major_version = 0; | |||||
| int minor_version = 0; | |||||
| bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version); | |||||
| if (!rc) | |||||
| return rc; | |||||
| for(;;) | |||||
| { | |||||
| rc = (1 == major_version); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInt(&m_t_type); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadComponentIndex(m_t_ci); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadDouble(4,m_t); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInterval(m_s[0]); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInterval(m_s[1]); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInterval(m_s[2]); | |||||
| if (!rc) break; | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndRead3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| ON_ObjRef::ON_ObjRef() | |||||
| : m_uuid(ON_nil_uuid), | |||||
| m_geometry(0), | |||||
| m_parent_geometry(0), | |||||
| m_geometry_type(ON::unknown_object_type), | |||||
| m_runtime_sn(0), | |||||
| m_point(ON_3dPoint::UnsetPoint), | |||||
| m_osnap_mode(ON::os_none), | |||||
| m__proxy1(0), | |||||
| m__proxy2(0), | |||||
| m__proxy_ref_count(0) | |||||
| { | |||||
| } | |||||
| void ON_ObjRef::Destroy() | |||||
| { | |||||
| DecrementProxyReferenceCount(); | |||||
| m_uuid = ON_nil_uuid; | |||||
| m_geometry = 0; | |||||
| m_parent_geometry = 0; | |||||
| m_geometry_type = ON::unknown_object_type; | |||||
| m_runtime_sn = 0; | |||||
| m_point = ON_3dPoint::UnsetPoint; | |||||
| m_osnap_mode = ON::os_none; | |||||
| m__proxy1 = 0; | |||||
| m__proxy2 = 0; | |||||
| m__proxy_ref_count = 0; | |||||
| } | |||||
| ON_ObjRef::ON_ObjRef( const ON_ObjRef& src ) | |||||
| : m_uuid(src.m_uuid), | |||||
| m_geometry(src.m_geometry), | |||||
| m_parent_geometry(src.m_parent_geometry), | |||||
| m_component_index(src.m_component_index), | |||||
| m_geometry_type(src.m_geometry_type), | |||||
| m_runtime_sn(src.m_runtime_sn), | |||||
| m_point(src.m_point), | |||||
| m_osnap_mode(src.m_osnap_mode), | |||||
| m_evp(src.m_evp), | |||||
| m__iref(src.m__iref), | |||||
| m__proxy1(src.m__proxy1), | |||||
| m__proxy2(src.m__proxy2), | |||||
| m__proxy_ref_count(src.m__proxy_ref_count) | |||||
| { | |||||
| if ( m__proxy_ref_count && *m__proxy_ref_count > 0 ) | |||||
| { | |||||
| *m__proxy_ref_count = *m__proxy_ref_count + 1; | |||||
| } | |||||
| } | |||||
| ON_ObjRef& ON_ObjRef::operator=( const ON_ObjRef& src ) | |||||
| { | |||||
| if ( this != &src ) | |||||
| { | |||||
| // Remove any reference this ON_ObjRef class | |||||
| // may currently have. | |||||
| DecrementProxyReferenceCount(); | |||||
| // copy the values from src | |||||
| m_uuid = src.m_uuid; | |||||
| m_geometry = src.m_geometry; | |||||
| m_parent_geometry = src.m_parent_geometry; | |||||
| m_component_index = src.m_component_index; | |||||
| m_geometry_type = src.m_geometry_type; | |||||
| m_runtime_sn = src.m_runtime_sn; | |||||
| m_point = src.m_point; | |||||
| m_osnap_mode = src.m_osnap_mode; | |||||
| m_evp = src.m_evp; | |||||
| m__iref = src.m__iref; | |||||
| m__proxy1 = src.m__proxy1; | |||||
| m__proxy2 = src.m__proxy2; | |||||
| m__proxy_ref_count = src.m__proxy_ref_count; | |||||
| if ( m__proxy_ref_count && *m__proxy_ref_count > 0 ) | |||||
| { | |||||
| *m__proxy_ref_count = *m__proxy_ref_count + 1; | |||||
| } | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| bool ON_ObjRef_IRefID::Write( ON_BinaryArchive& archive ) const | |||||
| { | |||||
| bool rc = archive.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 1 ); | |||||
| if ( !rc ) | |||||
| return false; | |||||
| for(;;) | |||||
| { | |||||
| rc = archive.WriteUuid(m_iref_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteXform(m_iref_xform); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteUuid(m_idef_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInt(m_idef_geometry_index); | |||||
| if (!rc) break; | |||||
| // 13 July 2006 - 1.1 - added m_component_index and m_evp | |||||
| rc = archive.WriteComponentIndex(m_component_index); | |||||
| if (!rc) break; | |||||
| rc = m_evp.Write(archive); | |||||
| if (!rc) break; | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndWrite3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| bool ON_ObjRef_IRefID::Read( ON_BinaryArchive& archive ) | |||||
| { | |||||
| Default(); | |||||
| int major_version = 0; | |||||
| int minor_version = 0; | |||||
| bool rc = archive.BeginRead3dmChunk( | |||||
| TCODE_ANONYMOUS_CHUNK, | |||||
| &major_version, | |||||
| &minor_version ); | |||||
| if ( !rc ) | |||||
| return false; | |||||
| for(;;) | |||||
| { | |||||
| rc = (1 == major_version); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadUuid(m_iref_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadXform(m_iref_xform); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadUuid(m_idef_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInt(&m_idef_geometry_index); | |||||
| if (!rc) break; | |||||
| if ( minor_version >= 1 ) | |||||
| { | |||||
| // 13 July 2006 - 1.1 - added m_component_index and m_evp | |||||
| rc = archive.ReadComponentIndex(m_component_index); | |||||
| if (!rc) break; | |||||
| rc = m_evp.Read(archive); | |||||
| if (!rc) break; | |||||
| } | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndRead3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| bool ON_ObjRef::Write( ON_BinaryArchive& archive ) const | |||||
| { | |||||
| bool rc = archive.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 3 ); | |||||
| if ( !rc ) | |||||
| return false; | |||||
| for(;;) | |||||
| { | |||||
| rc = archive.WriteUuid(m_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteComponentIndex(m_component_index); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInt(m_geometry_type); | |||||
| if (!rc) break; | |||||
| // Do not save the value of m_runtime_sn in the | |||||
| // archive. When the file is read in, the object | |||||
| // will have a different value of m_runtime_sn. | |||||
| rc = archive.WritePoint(m_point); | |||||
| if (!rc) break; | |||||
| // Prior to 13 July 2006, the evaluation parameters | |||||
| // m_evp were members of ON_ObjRef. That's why the | |||||
| // m_evp fields are written directly rather than | |||||
| // using m_evp.Write(). | |||||
| rc = archive.WriteInt(m_evp.m_t_type); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteComponentIndex(m_evp.m_t_ci); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteDouble(4,m_evp.m_t); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteArray(m__iref); | |||||
| if (!rc) break; | |||||
| // 1.1 IO fields | |||||
| rc = archive.WriteInterval(m_evp.m_s[0]); | |||||
| if (!rc) break; | |||||
| rc = archive.WriteInterval(m_evp.m_s[1]); | |||||
| if (!rc) break; | |||||
| // 1.2 IO fields | |||||
| rc = archive.WriteInterval(m_evp.m_s[2]); | |||||
| if (!rc) break; | |||||
| // 1.3 IO fields | |||||
| rc = archive.WriteInt((int)m_osnap_mode); | |||||
| if (!rc) break; | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndWrite3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| bool ON_ObjRef::Read( ON_BinaryArchive& archive ) | |||||
| { | |||||
| int major_version = 0; | |||||
| int minor_version = 0; | |||||
| bool rc = archive.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version ); | |||||
| if ( !rc ) | |||||
| return false; | |||||
| for(;;) | |||||
| { | |||||
| rc = (1 == major_version); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadUuid(m_uuid); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadComponentIndex(m_component_index); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInt(&m_geometry_type); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadPoint(m_point); | |||||
| if (!rc) break; | |||||
| // Prior to 13 July 2006, the evaluation parameters | |||||
| // m_evp were members of ON_ObjRef. That's why the | |||||
| // m_evp fields are read directly rather than | |||||
| // using m_evp.Read(). | |||||
| rc = archive.ReadInt(&m_evp.m_t_type); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadComponentIndex(m_evp.m_t_ci); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadDouble(4,m_evp.m_t); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadArray(m__iref); | |||||
| if (!rc) break; | |||||
| if ( minor_version >= 1 ) | |||||
| { | |||||
| // 1.1 IO fields | |||||
| rc = archive.ReadInterval(m_evp.m_s[0]); | |||||
| if (!rc) break; | |||||
| rc = archive.ReadInterval(m_evp.m_s[1]); | |||||
| if (!rc) break; | |||||
| if ( minor_version >= 2 ) | |||||
| { | |||||
| rc = archive.ReadInterval(m_evp.m_s[2]); | |||||
| if (!rc) break; | |||||
| if (minor_version >= 3) | |||||
| { | |||||
| int osmode = 0; | |||||
| rc = archive.ReadInt(&osmode); | |||||
| if (!rc) break; | |||||
| m_osnap_mode = ON::OSnapMode(osmode); | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| if ( !archive.EndRead3dmChunk() ) | |||||
| rc = false; | |||||
| return rc; | |||||
| } | |||||
| ON_ObjRef::~ON_ObjRef() | |||||
| { | |||||
| DecrementProxyReferenceCount(); | |||||
| } | |||||
| void ON_ObjRef::RemapObjectId( const ON_SimpleArray<ON_UuidPair>& id_remap ) | |||||
| { | |||||
| // The cast is a lie but it works because ON_UuidPair::CompareFirstUuid | |||||
| // looks for an id in the first 16 bytes of the ON_UuidPair. | |||||
| int i = id_remap.BinarySearch((const ON_UuidPair*)&m_uuid,ON_UuidPair::CompareFirstUuid); | |||||
| if ( i >= 0 ) | |||||
| m_uuid = id_remap[i].m_uuid[1]; | |||||
| } | |||||
| int ON_ObjRef::ProxyReferenceCount() const | |||||
| { | |||||
| return m__proxy_ref_count ? *m__proxy_ref_count : 0; | |||||
| } | |||||
| const ON_Brep* ON_BrepParent( const ON_Geometry* geo ) | |||||
| { | |||||
| const ON_Brep* brep = 0; | |||||
| if ( geo == nullptr ) | |||||
| return nullptr; | |||||
| if ( ON::brep_object == geo->ObjectType() ) | |||||
| { | |||||
| brep = ON_Brep::Cast(geo); | |||||
| } | |||||
| else | |||||
| { | |||||
| // ComponentIndex() is the fastest way | |||||
| switch( geo->ComponentIndex().m_type ) | |||||
| { | |||||
| case ON_COMPONENT_INDEX::brep_edge: | |||||
| { | |||||
| const ON_BrepEdge* edge = ON_BrepEdge::Cast(geo); | |||||
| if ( edge ) | |||||
| brep = edge->Brep(); | |||||
| } | |||||
| break; | |||||
| case ON_COMPONENT_INDEX::brep_face: | |||||
| { | |||||
| const ON_BrepFace* face = ON_BrepFace::Cast(geo); | |||||
| if ( face ) | |||||
| brep = face->Brep(); | |||||
| } | |||||
| break; | |||||
| case ON_COMPONENT_INDEX::brep_trim: | |||||
| { | |||||
| const ON_BrepTrim* trim = ON_BrepTrim::Cast(geo); | |||||
| if ( trim ) | |||||
| brep = trim->Brep(); | |||||
| } | |||||
| break; | |||||
| case ON_COMPONENT_INDEX::brep_loop: | |||||
| { | |||||
| const ON_BrepLoop* loop = ON_BrepLoop::Cast(geo); | |||||
| if ( loop ) | |||||
| brep = loop->Brep(); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values | |||||
| break; | |||||
| } | |||||
| } | |||||
| return brep; | |||||
| } | |||||
| const ON_Mesh* ON_MeshParent( const ON_Geometry* geo ) | |||||
| { | |||||
| const ON_Mesh* mesh = 0; | |||||
| if ( geo == nullptr ) | |||||
| return nullptr; | |||||
| if ( ON::mesh_object == geo->ObjectType() ) | |||||
| { | |||||
| mesh = ON_Mesh::Cast(geo); | |||||
| } | |||||
| else if ( geo->ComponentIndex().IsMeshComponentIndex() ) | |||||
| { | |||||
| const ON_MeshComponentRef* cref = ON_MeshComponentRef::Cast(geo); | |||||
| if ( cref ) | |||||
| mesh = cref->Mesh(); | |||||
| } | |||||
| return mesh; | |||||
| } | |||||
| bool ON_ObjRef::SetParentIRef( const ON_InstanceRef& iref, | |||||
| ON_UUID iref_id, | |||||
| int idef_geometry_index | |||||
| ) | |||||
| { | |||||
| bool rc = false; | |||||
| if ( m__iref.Count() > 0 ) | |||||
| { | |||||
| // nested irefs | |||||
| if ( 0 == m__proxy2 | |||||
| || 0 == m__proxy_ref_count | |||||
| || *m__proxy_ref_count <= 0 ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| ON_Geometry* proxy_geo = ON_Geometry::Cast(m__proxy2); | |||||
| if ( !proxy_geo ) | |||||
| return false; | |||||
| if ( !proxy_geo->Transform(iref.m_xform) ) | |||||
| return false; | |||||
| rc = true; | |||||
| } | |||||
| else if ( ON_COMPONENT_INDEX::invalid_type == m_component_index.m_type ) | |||||
| { | |||||
| // handle top level objects | |||||
| while ( m__proxy1 || m__proxy2 || m__proxy_ref_count ) | |||||
| { | |||||
| // It it's an brep proxy for an extrusion object, then keep going. | |||||
| if ( 0 != m__proxy1 | |||||
| && 0 == m__proxy2 | |||||
| && 0 != m__proxy_ref_count | |||||
| && 1 == *m__proxy_ref_count | |||||
| && m__proxy1 != m_geometry | |||||
| && 0 != ON_Brep::Cast(m_geometry) | |||||
| ) | |||||
| { | |||||
| // 13 July 2011 - Part of the fix for bug 87827 | |||||
| // is to break here instead of returning false | |||||
| // because we have something like a brep proxy | |||||
| // of an extrusion. | |||||
| break; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| if ( !m_geometry ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| if ( m_geometry->ComponentIndex().m_type != ON_COMPONENT_INDEX::invalid_type ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| if ( m_parent_geometry && m_geometry != m_parent_geometry ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| ON_Geometry* proxy_geo = m_geometry->Duplicate(); | |||||
| if ( !proxy_geo->Transform(iref.m_xform) ) | |||||
| { | |||||
| delete proxy_geo; | |||||
| return false; | |||||
| } | |||||
| // 13 July 2011 - Part of the fix for bug 87827 | |||||
| // was to put the m_geometry and m_parent_geometry | |||||
| // assignments after the call to SetProxy() which | |||||
| // was zeroing m_geometry and m_parent_geometry. | |||||
| SetProxy(0,proxy_geo,true); | |||||
| m_geometry = proxy_geo; | |||||
| m_parent_geometry = proxy_geo; | |||||
| rc = true; | |||||
| } | |||||
| else | |||||
| { | |||||
| // handle brep and mesh subobjects | |||||
| // create proxy object | |||||
| if ( m__proxy2 ) | |||||
| return false; | |||||
| const ON_Brep* parent_brep = ON_BrepParent(m_parent_geometry); | |||||
| if ( !parent_brep) | |||||
| parent_brep = ON_BrepParent(m_geometry); | |||||
| if ( parent_brep ) | |||||
| { | |||||
| // handle breps and their parts | |||||
| // 6 June 2013, Mikko, RH-9846: | |||||
| // This is a near facsimile of the 87827 fix above. | |||||
| // If it's a brep proxy component for an extrusion object, then keep going. | |||||
| if ( 0 != m__proxy1 | |||||
| && 0 == m__proxy2 | |||||
| && 0 != m__proxy_ref_count | |||||
| && 1 == *m__proxy_ref_count | |||||
| && m__proxy1 != m_geometry | |||||
| && m_geometry->ComponentIndex().IsBrepComponentIndex() | |||||
| ) | |||||
| { | |||||
| // brep proxy component for an extrusion object, keep going | |||||
| } | |||||
| else | |||||
| if ( m__proxy1 || m__proxy_ref_count ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| if ( m_parent_geometry != parent_brep && 0 != m_parent_geometry ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| if ( m_geometry != parent_brep->BrepComponent(m_component_index) ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| ON_Brep* proxy_brep = parent_brep->Duplicate(); | |||||
| if ( !proxy_brep->Transform(iref.m_xform) ) | |||||
| { | |||||
| delete proxy_brep; | |||||
| return false; | |||||
| } | |||||
| const ON_Geometry* brep_component = proxy_brep->BrepComponent(m_component_index); | |||||
| if ( !brep_component ) | |||||
| { | |||||
| delete brep_component; | |||||
| return false; | |||||
| } | |||||
| SetProxy(0,proxy_brep,true); | |||||
| m_geometry = brep_component; | |||||
| m_parent_geometry = proxy_brep; | |||||
| rc = true; | |||||
| } | |||||
| else | |||||
| { | |||||
| const ON_Mesh* parent_mesh = ON_MeshParent(m_parent_geometry); | |||||
| if ( !parent_mesh) | |||||
| parent_mesh = ON_MeshParent(m_geometry); | |||||
| if ( parent_mesh ) | |||||
| { | |||||
| // handle meshes and their parts | |||||
| if ( m_component_index.IsMeshComponentIndex() ) | |||||
| { | |||||
| if ( m_geometry->ComponentIndex() != m_component_index ) | |||||
| return false; | |||||
| ON_Mesh* proxy_mesh = parent_mesh->Duplicate(); | |||||
| if ( !proxy_mesh->Transform(iref.m_xform) ) | |||||
| { | |||||
| delete proxy_mesh; | |||||
| return false; | |||||
| } | |||||
| ON_Geometry* proxy_component = proxy_mesh->MeshComponent(m_component_index); | |||||
| if( !proxy_component ) | |||||
| { | |||||
| delete proxy_mesh; | |||||
| return false; | |||||
| } | |||||
| m_geometry = proxy_component; | |||||
| m_parent_geometry = proxy_mesh; | |||||
| SetProxy(proxy_component,proxy_mesh,true); | |||||
| rc = true; | |||||
| } | |||||
| else | |||||
| { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| if ( rc ) | |||||
| { | |||||
| // This is a valid reference to a piece of geometry | |||||
| // in an instance definition. | |||||
| ON_Xform geometry_xform(ON_Xform::IdentityTransformation); | |||||
| if ( m__iref.Count() > 0 ) | |||||
| geometry_xform = m__iref.Last()->m_geometry_xform; | |||||
| ON_ObjRef_IRefID& this_ref = m__iref.AppendNew(); | |||||
| this_ref.m_iref_uuid = iref_id; | |||||
| this_ref.m_iref_xform = iref.m_xform; | |||||
| this_ref.m_idef_uuid = iref.m_instance_definition_uuid; | |||||
| this_ref.m_idef_geometry_index = idef_geometry_index; | |||||
| this_ref.m_geometry_xform = iref.m_xform*geometry_xform; | |||||
| m_uuid = this_ref.m_iref_uuid; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| const ON_Object* ON_ObjRef::ProxyObject(int proxy_object_index) const | |||||
| { | |||||
| return ( (1 == proxy_object_index) | |||||
| ? m__proxy1 | |||||
| : ((2==proxy_object_index) ? m__proxy2 : 0) | |||||
| ); | |||||
| } | |||||
| void ON_ObjRef::SetProxy( | |||||
| ON_Object* proxy1, | |||||
| ON_Object* proxy2, | |||||
| bool bCountReferences | |||||
| ) | |||||
| { | |||||
| if ( m__proxy1 || m__proxy2 || m__proxy_ref_count ) | |||||
| { | |||||
| // Remove any reference this ON_ObjRef class | |||||
| // may currently have. | |||||
| DecrementProxyReferenceCount(); | |||||
| } | |||||
| m__proxy1 = proxy1; | |||||
| m__proxy2 = proxy2; | |||||
| if ( bCountReferences && (m__proxy1 || m__proxy2) ) | |||||
| { | |||||
| m__proxy_ref_count = (int*)onmalloc( sizeof(*m__proxy_ref_count) ); | |||||
| *m__proxy_ref_count = 1; | |||||
| } | |||||
| } | |||||
| void ON_ObjRef::DecrementProxyReferenceCount() | |||||
| { | |||||
| if ( 0 != m__proxy_ref_count ) | |||||
| { | |||||
| if (*m__proxy_ref_count > 1) | |||||
| { | |||||
| // Including this class, there are *m__proxy_ref_count | |||||
| // ON_ObjRef classes using m__proxy and m_geometry. | |||||
| // Decrement the reference counter and set the | |||||
| // pointers to zero. | |||||
| *m__proxy_ref_count = *m__proxy_ref_count - 1; | |||||
| } | |||||
| else if ( 1 == *m__proxy_ref_count ) | |||||
| { | |||||
| // This is the only ON_ObjRef class using | |||||
| // m__proxy and m_geometry. Set *m__proxy_ref_count | |||||
| // to zero (in case some rogue reference still exists), | |||||
| // delete m__proxy and m__proxy_ref_count, and | |||||
| // set m_geometry (which points to some part of m__proxy) | |||||
| // to nullptr. | |||||
| // Setting *m__proxy_ref_count to zero, prevents crashes | |||||
| // if somebody incorrectly uses memcpy() instead of the | |||||
| // copy constructor or operator= to duplicate this class. | |||||
| *m__proxy_ref_count = 0; | |||||
| if ( m__proxy1 ) | |||||
| { | |||||
| // delete proxy geometry | |||||
| delete m__proxy1; | |||||
| } | |||||
| if ( m__proxy2 ) | |||||
| { | |||||
| // delete proxy geometry | |||||
| delete m__proxy2; | |||||
| } | |||||
| onfree(m__proxy_ref_count); | |||||
| } | |||||
| else | |||||
| { | |||||
| // Somebody did something along the lines of using | |||||
| // memcpy() instead of the copy constructor or operator= | |||||
| // to duplicate this class. | |||||
| ON_ERROR("ON_ObjRef::DecrementReferenceCount() *m__proxy_ref_count <= 0"); | |||||
| } | |||||
| } | |||||
| // In all cases, setting these pointers to zero indicates this | |||||
| // ON_ObjRef is no longer referencing any runtime geometry. | |||||
| m__proxy_ref_count = 0; | |||||
| m__proxy1 = 0; | |||||
| m__proxy2 = 0; | |||||
| m_geometry = 0; | |||||
| } | |||||
| void ON_ObjRef_IRefID::Default() | |||||
| { | |||||
| ON_ObjRef_IRefID d; | |||||
| *this = d; | |||||
| } | |||||