/* // // 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 . // //////////////////////////////////////////////////////////////// */ #if !defined(ON_MODEL_COMPONENT_INC_) #define ON_MODEL_COMPONENT_INC_ /* Description: The ON_ModelComponent class is a base class for all components in a model and manages the index, id and other information common to all components in a model. */ class ON_CLASS ON_ModelComponent : public ON_Object { ON_OBJECT_DECLARE(ON_ModelComponent); public: bool IsValid( class ON_TextLog* text_log = nullptr ) const override; void Dump( ON_TextLog& ) const override; unsigned int SizeOf() const override; ON__UINT32 DataCRC( ON__UINT32 current_remainder ) const override; ON_UUID ModelObjectId() const override; public: #pragma region RH_C_SHARED_ENUM [ON_ModelComponent::Type] [Rhino.DocObjects.ModelComponentType] [public:byte] /// ///The ON_ModelComponent::Type enum has a value for each explicit component type ///and two special values, Unset and Mixed. Use an ON_ModelComponentTypeIterator ///instance to iterate over the ON_ModelComponent::Type values. /// enum class Type : unsigned char { ///No value set. Unset = 0, ///Embedded image (bitmap) components. Image = 1, ///Texture mapping. TextureMapping = 2, ///Render material. RenderMaterial = 3, ///Line pattern (linetype). LinePattern = 4, ///Layer. Layer = 5, ///Group. Group = 6, ///Text style. TextStyle = 7, ///AnnotationDimension style. DimStyle = 8, ///Render light. RenderLight = 9, ///Hatch pattern. HatchPattern = 10, ///Instance definition. InstanceDefinition = 11, ///Model objects (points, curves, surfaces, ..., annotation, page details, ...), including objects referenced by instance definitions. ModelGeometry = 12, ///History record. HistoryRecord = 13, ///Multiple component types. /// Used when a component type filter must include all explicit component types. /// Mixed = 0xFE }; #pragma endregion static ON_ModelComponent::Type ComponentTypeFromUnsigned( unsigned int component_type_as_unsigned ); static const ON_wString ComponentTypeToString( ON_ModelComponent::Type ); /* Parameters: component_type - [in] Returns: True if component_type is a valid enum value, and not equal to ON_ModelComponent::Type::Unset. */ static bool ComponentTypeIsValid( ON_ModelComponent::Type component_type ); /* Parameters: component_type - [in] Returns: True if component_type is a valid enum value, and not equal to ON_ModelComponent::Type::Unset, and not equal to ON_ModelComponent::Type::Mixed. */ static bool ComponentTypeIsValidAndNotMixed( ON_ModelComponent::Type component_type ); /* Parameters: component_type - [in] Returns: True if component's of the specified type require uniquen names. Remarks: In general, component names ignore case and parent when testing for equality. However, there are exceptions. Use ON_ModelComponent::UniqueNameIncludesParent() and ON_ModelComponent::UniqueNameIgnoresCase() to test for exceptions. */ static bool UniqueNameRequired( ON_ModelComponent::Type component_type ); /* Parameters: component_type - [in] Returns: True if objects with the same name and different parents are considered to have a unique name. This typically means the user interface for the object names is some type of tree. Remarks: Currently, layers are the only object type where this property is true. */ static bool UniqueNameIncludesParent( ON_ModelComponent::Type component_type ); /* Parameters: component_type - [in] Returns: True if component names ignore case when testing for equality. Remarks: Currently all other component types except for groups ignore case when testing for equality. */ static bool UniqueNameIgnoresCase( ON_ModelComponent::Type component_type ); static bool IndexRequired( ON_ModelComponent::Type component_type ); /* Returns: True if a componenent name can begin with the first code point. Remarks: Component names cannot begin with a (, ), [, ], {, }, or space. These brackets can be the second or later code points. A space can be an interior code point. */ static bool IsValidComponentNameFirstCodePoint( ON__UINT32 unicode_code_point ); /* Parameters: length - [in] number of wchar_t elements in candidate_component_name[] or -1 if it is a null terminated string. candidate_component_name - [in] The first code point is decoded from this string and passed to ON_ModelComponent::IsValidComponentNameFirstCodePoint(). Returns: True if a componenent name can begin with the first code point. Remarks: Component names cannot begin with a (, ), [, ], {, }, or space. These brackets can be the second or later code points. A space can be an interior code point. */ static bool IsValidComponentNameFirstCodePoint( int length, const wchar_t* candidate_component_name ); static bool IsValidComponentName( const wchar_t* candidate_component_name ); static bool IsValidComponentName( const ON_wString& candidate_component_name ); static bool IsValidComponentName( size_t length, const wchar_t* candidate_component_name ); /* Parameters: model_component - [in] model_manfest - [in] current model contents valid_name - [in] Valid name for this component in a model with the specified manifest. Returns: true: model_component.Name() is valid false: model_component.Name() is not valid */ static bool IsValidComponentName( const class ON_ComponentManifest& model_manfest, const ON_ModelComponent& model_component, bool bPermitReferencePrefix, ON_wString& valid_name ); public: static const ON_ModelComponent Unset; ON_ModelComponent() ON_NOEXCEPT; ~ON_ModelComponent() = default; // Locked status of source attributes is not copied to permit copy and modify operations. // Runtime serial number and content version number are not copied. ON_ModelComponent( const ON_ModelComponent& source ); /* Description: Sets and locks the component type attribute. Parameters: component_type - [in] */ ON_ModelComponent( ON_ModelComponent::Type component_type ) ON_NOEXCEPT; // Locked status of source attributes is not copied to permit copy and modify operations. ON_ModelComponent( ON_ModelComponent::Type component_type, const ON_ModelComponent& source ) ON_NOEXCEPT; /* Remarks: operator= will not change locked destination attributes. Locked status of source attributes is not copied to permit copy and modify operations. */ ON_ModelComponent& operator=(const ON_ModelComponent& source); /* The ON_ModelComponent::Attributes enum is used to set bits that identify model component attributes. */ enum Attributes : unsigned int { NoAttributes = 0U, ComponentSerialNumberAttribute = 0x0001U, TypeAttribute = 0x0002U, ModelSerialNumberAttribute = 0x0004U, IdAttribute = 0x0008U, IndexAttribute = 0x0010U, NameAttribute = 0x0020U, ParentIdAttribute = 0x0040U, DeletedNameAttribute = 0x0080U, ComponentStatusAttribute = 0x0100U, // Default model attributes saved in binary archives. // Id, ParentId, Name, Index // Do not include SystemComponentAttribute in BinaryArchiveAttributes BinaryArchiveAttributes = 0x78U, // Do not include SystemComponentAttribute in AllAttributes AllAttributes = 0x1FFU, SystemComponentAttribute = 0x8000U }; unsigned int CopyFrom( const ON_ModelComponent& src, unsigned int attributes_filter ); bool WriteModelComponentAttributes( class ON_BinaryArchive& archive, unsigned int attributes_filter ) const; bool ReadModelComponentAttributes( class ON_BinaryArchive& archive ); /////////////////////////////////////////////////////////////////////////////// // // Model Serial Number interface // // The ModelSerialNumber() identifies the model that manages the component. // If the component is from some type of reference model, then one or both of // the reference model serial number and InstanceDefinitionModelSerialNumber() // identify the source model. // /* Description: Specify the model that is managing this component. Parameters: model_serial_number - [in] In Rhino, this is the document runtime serial number. Returns: true if the model_serial_number value was changed to component_model_serial_number or is already equal to component_model_serial_number. false if the model_serial_number value is locked and component_model_serial_number != locked value. */ bool SetModelSerialNumber( unsigned int model_serial_number ); /* Description: Specify the model that is managing this component. Parameters: model_serial_number - [in] In Rhino, this is the document runtime serial number. reference_model_serial_number - [in] In Rhino, this is the worksession reference model serial number. instance_definition_model_serial_number - [in] In Rhino, this is the linked instance definition model serial number. Returns: true if the model_serial_number value was changed to component_model_serial_number or is already equal to component_model_serial_number. false if the model_serial_number value is locked and component_model_serial_number != locked value. */ bool SetModelSerialNumber( unsigned int model_serial_number, unsigned int reference_model_serial_number, unsigned int instance_definition_model_serial_number ); /* Returns: A value identifing the model that manages this component. Remarks: If the component is being managed by a model, this value identifies the model. In Rhino, this value is the document runtime serial number. Typically this value is set and locked by the code that adds a component to a model. This value is copied by the copy constructor and operator=. This value is not saved in .3dm archives. */ unsigned int ModelSerialNumber() const; /* Returns: When a compoent is in a model for reference, this value identifies the reference model. Remarks: Reference components are not saved in .3dm archives. Typically this value is set and locked by the code that adds a component to a model. This value is copied by the copy constructor and operator=. This value is not saved in .3dm archives. In Rhino, this value is a worksession model runtime serial number and these values are used. 0: not from a worksession reference model 1: from an unidentified reference model 2-1000: reserved for future use >1000: worksession reference model serial number */ unsigned int ReferenceModelSerialNumber() const; /* Returns: When a component is in a model as part of the information required for a linked instance definition, this value identifies the the linked instance definition reference model. Remarks: Reference components are not saved in .3dm archives. Typically this value is set and locked by the code that adds a component to a model. This value is copied by the copy constructor and operator=. This value is not saved in .3dm archives. In Rhino, this value is a linked instance definition runtime serial number and these values are used.. 0: Active model component. 1-1000: reserved for future use >1000: linked instance defintion serial number */ unsigned int InstanceDefinitionModelSerialNumber() const; /* Description: Sets the model serial number, reference model serial number and instance definition model serial number values to 0 and flags these values as unset. */ bool ClearModelSerialNumber(); /* Description: Calling LockModelSerialNumber() will prohibit future changes to the ModelSerialNumber(), ReferenceModelSerialNumber(), and InstanceDefinitionModelSerialNumber() attributes. */ void LockModelSerialNumber(); /* Returns: True if the ModelSerialNumber(), ReferenceModelSerialNumber(), and InstanceDefinitionModelSerialNumber() attributes are locked. */ bool ModelSerialNumberIsLocked() const; /* Returns: True if the ModelSerialNumber(), ReferenceModelSerialNumber(), and InstanceDefinitionModelSerialNumber() attributes are set. */ bool ModelSerialNumberIsSet() const; /* Returns True if ReferenceModelSerialNumber() or InstanceDefinitionModelSerialNumber() are not zero. */ bool IsReferenceComponent() const; /////////////////////////////////////////////////////////////////////////////// // // Type interface // /* Returns: Value of the Type attribute. Remarks: If the component is in a model, then the component_type is unique for all components of identical type in the model and is locked. */ ON_ModelComponent::Type ComponentType() const; /* Parameters: component_component_type - [in] Returns: true if the component_type value was changed to component_component_type or is already equal to component_component_type. false if the component_type value is locked and component_component_type != locked value. */ bool SetComponentType( ON_ModelComponent::Type component_component_type ); /* Description: Set the model serial number value to the ON_ModelComponent::Unset.Type() and change the state so TypeIsSet() returns false. */ bool ClearComponentType(); /* Description: Calling LockType() will prhibit future changes to the Type attribute. */ void LockComponentType(); /* Returns: True if the Type attribute is locked. */ bool ComponentTypeIsLocked() const; /* Returns: True if the Type attribute is set. */ bool ComponentTypeIsSet() const; /////////////////////////////////////////////////////////////////////////////// // // Id interface // // The component id is intended to be unique in the context of a model. // /* Returns: Value of the Id attribute. Remarks: If the component is in a model, then the id is unique for all components in the model and is locked. */ const ON_UUID& Id() const; bool IdIsNil() const; bool IdIsNotNil() const; /* Parameters: component_id - [in] Returns: true if the id value was changed to component_id or is already equal to component_id. false if the id value is locked and component_id != locked value. */ bool SetId( const ON_UUID& component_id ); /* Description: Sets the id to a new value created by ON_CreateUuid(). Returns: ON_nil_uuid: Id is locked. Otherwise the value of the new id. */ const ON_UUID& SetId(); /* Description: If the it is nil, call SetId(). */ const ON_UUID& IfIdIsNilSetId(); /* Description: Sets the id to a new value created by ON_CreateUuid() and locks the id attribute so it cannot be changed. Returns: ON_nil_uuid: Id is locked. Otherwise the value of the new id. */ const ON_UUID& SetAndLockId(); /* Description: Set the component id value to the ON_ModelComponent::Unset.ModelComponentId() and change the state so ModelComponentIdIsSet() returns false. */ bool ClearId(); /* Description: Calling LockModelComponentId() will prhibit future changes to the ModelComponentId attribute. */ void LockId(); /* Returns: True if the ModelComponentId attribute is locked. */ bool IdIsLocked() const; /* Returns: True if the ModelComponentId attribute is set. */ bool IdIsSet() const; /////////////////////////////////////////////////////////////////////////////// // // Index interface // // When a component is managed by a model, the component index is identifies // the component within the context of that model. // /* Returns: Value of the runtime model component index attribute. Remarks: If the component is in a model, then the index is unique for all components of identical type in the model and is locked. If the index has not been set, ON_UNSET_INT_INDEX is returned. The Index() value can change when saved in an archive (.3dm file). Use the Id() when you need to reference model compoenents in an archive. */ int Index() const; /* Returns: Value of the model component index attribute. Parameters: unset_index_value - [in] Value to return if the index has not been set. ON_UNSET_INT_INDEX or indices of default components are often used for this parameter. Returns: IndexIsSet() ? Index() : unset_index_value; Remarks: If the component is in a model, then the index is unique for all components of identical type in the model and is locked. */ int Index( int unset_index_value ) const; /* Parameters: component_index - [in] Returns: true if the index value was changed to component_index or is already equal to component_index. false if the index value is locked and component_index != locked value. */ bool SetIndex( int component_index ); /* Description: Set the component index value to the ON_ModelComponent::Unset.ModelComponentIndex() and change the state so ModelComponentIndexIsSet() returns false. */ bool ClearIndex(); /* Description: Calling LockModelComponentIndex() will prhibit future changes to the ModelComponentIndex attribute. */ void LockIndex(); /* Returns: True if the ModelComponentIndex attribute is locked. */ bool IndexIsLocked() const; /* Returns: True if the ModelComponentIndex attribute is set. */ bool IndexIsSet() const; /////////////////////////////////////////////////////////////////////////////// // // Parent object interface // // const ON_UUID& ParentId() const; bool ParentIdIsNil() const; bool ParentIdIsNotNil() const; bool SetParentId( const ON_UUID& parent_id ); bool ClearParentId(); void LockParentId(); bool ParentIdIsLocked() const; bool ParentIdIsSet() const; /////////////////////////////////////////////////////////////////////////////// // // Model component locked, hidden, deleted, selected, highlights, damaged, ... status interface // // ON_ComponentStatus ModelComponentStatus() const; bool SetModelComponentStatus( ON_ComponentStatus component_status ); bool ClearModelComponentStatus(); void LockModelComponentStatus(); bool ModelComponentStatusIsLocked() const; bool ModelComponentStatusIsSet() const; /* Returns: The component's deleted state. Remarks: Deleted components can be undeleted. */ bool IsDeleted() const; /* Parameters: bDeleted - [in] manifest - [in/out] optional manifest to update Returns: True if the component's deleted state was changed from !bDeleted to bDeleted and all other name and manifest information was updated as expected. */ bool SetDeletedModelComponentState( bool bDeleted, class ON_ComponentManifest* manifest ); /* Returns: The component's user interface locked state. Remarks: This is a user interface locked state and does not effect changing the component values. */ bool IsLocked() const; void SetLockedModelComponentState( bool bLocked ); /* Returns: The component's user interface hidden state. Remarks: This is a user interface hidden state and does not effect changing the component values. */ bool IsHidden() const; void SetHiddenModelComponentState( bool bHidden ); /////////////////////////////////////////////////////////////////////////////// // // Name interface // // /* Returns: Value of the Name attribute. Remarks: If the component is in a model, then the name is unique among all components in the model. Names are formatted as reference : parent::leaf. For example in "A.3dm : Z", "A.3dm" is the reference and "Z" is the leaf. For a layer full path "X::Y::Z", "X::Y" is the parent and "Z" is the leaf. For most models, only the leaf is present in the name. The reference portion appears when a model component originates in a reference file (a linked instance definition with reference component names or a worksession reference). Components with a tree hierarchy, like layers, can have a parent and leaf. */ const ON_wString Name() const; const ON_wString DeletedName() const; /* Parameters: component_name - [out] Returns: A pointer to the string in component_name. */ const wchar_t* GetName( ON_wString& component_name ) const; /* Description: Get a platform independent hash of the name suitable for equality testing and binary searching. When testing for equality or doing binary searches, using ON_NameHash values is faster than using the CompareName or ON_wString::CompareAttributeName. */ const ON_NameHash& NameHash() const; const ON_NameHash& DeletedNameHash() const; /* Parameters: new_name - [in] Returns: If new_name is empty or a valid component name, then name hash this component would have if SetName(new_name) were called. If new_name is not valid, then ON_NameHash::UnsetNameHash is returned. Remarks: This function trims leading and trailing white space, includes the parent id when ON_ModelComponent::UniqueNameIncludesParent(ComponentType()) is true, and uses ON_ModelComponent::IsValidComponentName() to determine if a non-empty name is valid. */ const ON_NameHash NewNameHash( const wchar_t* new_name ) const; /* Description: Returns the string " : ". This is the string Rhino uses to separate the reference file names from and model component names read from those files. Example: File A.3dm contains a layer "alpha", dimstyle "a1", an embedded block "A_blk", and a linked block "X" referencing B.3dm with reference component names. File B.3dm contains a layer "beta", dimstyle "b1", an embedded block "B_blk", and linked block "Y" referencing C.3dm. File C.3dm contains a layer gamma, dimstyle "c1", an embedded block "C_blk", and linked block "Z" referencing D.3dm. File D.3dm contains a layer "delta", dimstyle "d1", and an embedded block "D_blk". Reading file A.3dm will craete the following components: Layers: alpha X>B.3dm beta (full layer path "X>B.3dm::beta") Y>C.3dm gamma (full layer path "Y>C.3dm::gamma") Z>D.3dm delta (full layer path "Z>D.3dm::delta") Blocks: X A_blk Y B.3dm : B_blk Z C.3dm : C_blk D.3dm : D_blk Annotation styles a1 B.3dm : b1 C.3dm : c1 D.3dm : d1 See Also: ON_ModelComponent::ReferencePrefixDelimiter = " : " ON_ModelComponent::ReferencePrefixSeparator = ">" ON_ModelComponent::NamePathSeparator = "::" */ static const ON_wString ReferencePrefixDelimiter; /* Description: Returns the string ">". This is the string Rhino uses to separate the block definition name and linked file name in grandparent layers. Example: File A.3dm contains a layer "alpha", dimstyle "a1", an embedded block "A_blk", and a linked block "X" referencing B.3dm with reference component names. File B.3dm contains a layer "beta", dimstyle "b1", an embedded block "B_blk", and linked block "Y" referencing C.3dm. File C.3dm contains a layer gamma, dimstyle "c1", an embedded block "C_blk", and linked block "Z" referencing D.3dm. File D.3dm contains a layer "delta", dimstyle "d1", and an embedded block "D_blk". Reading file A.3dm will craete the following components: Layers: alpha X>B.3dm beta (full layer path "X>B.3dm::beta") Y>C.3dm gamma (full layer path "Y>C.3dm::gamma") Z>D.3dm delta (full layer path "Z>D.3dm::delta") Blocks: X A_blk Y B.3dm : B_blk Z C.3dm : C_blk D.3dm : D_blk Annotation styles a1 B.3dm : b1 C.3dm : c1 D.3dm : d1 See Also: ON_ModelComponent::ReferencePrefixDelimiter = " : " ON_ModelComponent::ReferencePrefixSeparator = ">" ON_ModelComponent::NamePathSeparator = "::" */ static const ON_wString ReferencePrefixSeparator; /* Description: Returns the string "::". This is the string Rhino uses in layer full path names to separate the names of individual layers. Example: If a model has layers A B C then the full path names are "A", "A::B", "A::B::C". See Also: ON_ModelComponent::ReferencePrefixDelimiter = " : " ON_ModelComponent::ReferencePrefixSeparator = ">" ON_ModelComponent::NamePathSeparator = "::" */ static const ON_wString NamePathSeparator; ///* //Description: //Parameters: // reference_prefix - [in] //Returns: // The worksession component name reference prefix. //Example: // "[ A.3dm ]" = ON_ModelComponent::WorksessionReferencePrefix("A.3dm") //*/ //static const ON_wString WorksessionReferencePrefix( // const wchar_t* reference_prefix, // bool bAppendReferencePrefixDelimiter //); /* Description: Test a string to see if its beginning matches the string returned by ON_ModelComponent::NameReferenceDelimiter. Parameters: s - [in]; string to test. Returns: null: The beginning of the string does not match ON_ModelComponent::NameReferenceDelimiter. non-null: The beginning of the string matches ON_ModelComponent::NameReferenceDelimiter. The returned pointer is the first character in s after the last character of the delimiter. Put another way, if the beginning of s matches the string ON_ModelComponent::NameReferenceDelimiter, then the returned pointer is s + ON_ModelComponent::NameReferenceDelimiter.Length(). */ static const wchar_t* IsReferencePrefixDelimiter( const wchar_t* s ); /* Description: Test a string to see if its beginning matches the string returned by ON_ModelComponent::NameReferenceSeparator. Parameters: s - [in]; string to test. Returns: null: The beginning of the string does not match ON_ModelComponent::NameReferenceSeparator. non-null: The beginning of the string matches ON_ModelComponent::NameReferenceSeparator. The returned pointer is the first character in s after the last character of the delimiter. Put another way, if the beginning of s matches the string ON_ModelComponent::NameReferenceSeparator, then the returned pointer is s + ON_ModelComponent::NameReferenceSeparator.Length(). */ static const wchar_t* IsReferencePrefixSeparator( const wchar_t* s ); /* Description: Test a string to see if its beginning matches the string returned by ON_ModelComponent::NamePathSeparator. Parameters: s - [in]; string to test. Returns: null: The beginning of the string does not match ON_ModelComponent::NamePathSeparator. non-null: The beginning of the string matches ON_ModelComponent::NamePathSeparator. The returned pointer is the first character in s after the last character of the delimiter. Put another way, if the beginning of s matches the string ON_ModelComponent::NamePathSeparator, then the returned pointer is s + ON_ModelComponent::NamePathSeparator.Length(). */ static const wchar_t* IsNamePathSeparator( const wchar_t* s ); /* Example: If a full layer name is "A.3dm : X::Y::Z", then reference_prefix = "A.3dm" name_parent = "X::Y" name_leaf = "Z" */ static void SplitName( const wchar_t* name, ON_wString& reference_prefix, ON_wString& name_parent, ON_wString& name_leaf ); /* Parameters: name - [in] Example: If the name is "A.3dm : X", then "A.3dm" is returned. */ static const ON_wString NameReferencePrefix( const wchar_t* name ); /* Parameters: name - [in] bIncludeReference - [in] Example: If the name is "A.3dm>B.3dm : X::Y::Z" and bIncludeReference is true, then "A.3dm>B.3dm : X::Y" is returned. If the name is "A.3dm>B.3dm : X::Y::Z" and bIncludeReference is false, then "X::Y" is returned. */ static const ON_wString NameParent( const wchar_t* name, bool bIncludeReference ); /* Example: If the name is "A.3dm>B.3dm : X::Y::Z", then name_leaf = "Z" is returned. */ static const ON_wString NameLeaf( const wchar_t* name ); /* Parameters: name - [in] Example: If the name is "A.3dm : X", then "X" is returned. */ static const ON_wString RemoveReferencePrefix( const wchar_t* name ); /* Description: Remove all occurances of ON::NameReferenceDelimiter() from name. */ static const ON_wString RemoveAllReferencePrefixDelimiters( const wchar_t* name ); /* Description: Remove any trailing occurance of ON_ModelComponent::NameReferenceDelimiter from name. Example: "A.3dm" = ON_ModelComponent::RemoveTrailingRemoveReferencePrefixDelimiter("A.3dm : "); */ static const ON_wString RemoveTrailingReferencePrefixDelimiter( const wchar_t* name ); /* Description: Remove any trailing occurance of ON_ModelComponent::NameReferenceSeparator from name. */ static const ON_wString RemoveTrailingReferencePrefixSeparator( const wchar_t* name ); /* Description: Remove any trailing occurance of ON_ModelComponent::NamePathSeparator from name. */ static const ON_wString RemoveTrailingNamePathSeparator( const wchar_t* name ); private: const ON_NameHash& Internal_NameHash() const; public: /* Description: Expert user function that gets a pointer to the name. Returns: A pointer to the string that contains the name. This pointer must be used immediately and then discarded before any code can possibly call SetName() or the ON_ModelComponent destructor could be called. Remarks: About the only good use for this function is when a model compoenent is peristent and the name is needed for a formatted string. For any other use, call the Name() function and store the result in an ON_wString. This function is dangerous because the returned pointer will be invalid if SetName() is called. */ const wchar_t* NameAsPointer() const; /* Returns: true if the name is unset or is set to the empty string. */ bool NameIsEmpty() const; /* Returns: true if the name is set and the value is not the empty string. */ bool NameIsNotEmpty() const; /* Parameters: component_name - [in] Leading and trailing nonzero unicode code points with values <= ON_wString::Space are ignored. Returns: true if the name attribute was changed to component_name or is already equal to component_name. false False is returned and no changes are made if the name attribute is locked and component_name != locked value or component_name is not empty and ON_ModelComponent::IsValidComponentName(component_name) is false. Remarks: If component_name is nullptr or the emtpy string, the NameIsSet() state will still be true. */ bool SetName( const wchar_t* component_name ); /* Description: Change the name of a component and optionally update a manifest. Parameters: new_name - [in] New name for the component. manifest - [in] nullptr or a manifest with an item for the component. */ bool ChangeName( const wchar_t* new_name, class ON_ComponentManifest* manifest ); /* Description: Set the component name value to the ON_ModelComponent::Unset.Name() and change the state so NameIsSet() and DeletedNameIsSet() both return false. */ bool ClearName(); /* Description: Calling LockName() will prohibit future changes to the Name attribute. */ void LockName(); /* Returns: True if the Name attribute is locked. */ bool NameIsLocked() const; /* Returns: True if the name attribute is set. Remarks: At most one of NameIsSet() and DeletedNameIsSet() is true. A name can be set to the empty string. */ bool NameIsSet() const; /* Returns: True if the deleted name attribute is set. Remarks: At most one of NameIsSet() and DeletedNameIsSet() is true. */ bool DeletedNameIsSet() const; /* Description: If NameIsSet() is true, then the name is deleted in a waty that can be undone by calling UndeleteName() and the DeletedNameIsSet() property is changed to true. If NameIsSet() is false or NameIsLocked() is true, then nothing is changed. Note that a name can be set to the empty string and there is a difference between a name being set to the empty string and a name being unset. If you want to make the name attribute unset, call ClearName(). */ bool DeleteName(); bool UndeleteName(); void LockAllSettingsExceptName(); bool SetLocalizedSystemComponentName( const wchar_t* system_component_localized_name ); /* Parameters: other_name -[in] Returns: ON_wString::CompareAttributeName(this->Name(), other_name) Remarks: CompareName() is the correct tool to use when looking up objects by name. */ int CompareName( const ON_UUID& other_parent_id, const wchar_t* other_name ) const; int CompareName( const wchar_t* other_name ) const; /* Parameters: other_name -[in] Returns: int rc = ON_wString::CompareAttributeName(this->Name(), other_name); return (0 != rc) ? rc : ON_wString::CompareOrdinal(this->Name(), other_name, false); Remarks: CompareNameExact() is the correct tool to use when detecting changes in case are important. Use CompareName() when searching for components by name. */ int CompareNameExact( const ON_UUID& other_parent_id, const wchar_t* other_name ) const; int CompareNameExact( const wchar_t* other_name ) const; /* Parameters: a -[in] b -[in] Returns: ON_wString::CompareAttributeName(a.Name(), b.Name() ) Remarks: CompareName() is the correct tool to use when looking up objects by name. */ static int CompareName( const ON_ModelComponent& a, const ON_ModelComponent& b ); /* Parameters: a -[in] b -[in] Returns: int rc = ON_wString::CompareAttributeName(a.Name(), b.Name()); return (0 != rc) ? rc : ON_wString::CompareOrdinal(a.Name(), b.Name(), false); Remarks: CompareNameExact() is the correct tool to use when detecting changes in case are important. Use CompareName() when searching for components by name. */ static int CompareNameExact( const ON_ModelComponent& a, const ON_ModelComponent& b ); static int CompareId( const ON_ModelComponent& a, const ON_ModelComponent& b ); /* Description Call ON_ModelComponent::CompareName() and then ON_ModelComponent::CompareId(). When used for sorting, will be sorted by name and then by id. */ static int CompareNameAndId( const ON_ModelComponent& a, const ON_ModelComponent& b ); /* Description Call ON_ModelComponent::Id()and then ON_ModelComponent::CompareName(). When used for sorting, will be sorted by id and then by name. */ static int CompareIdAndName( const ON_ModelComponent& a, const ON_ModelComponent& b ); /* Description: Set a component's id, name and index to the manifest_item values. Parameters: manifest_item - [in] manifest_name - [in] bSetId - [in] Set the component id to manifest_item.m_manifest_id. bSetParentId - [in] Use manifest_item.NameHash().ParentId() bSetName - [in] Set the component name to manifest_name. bSetIndex - [in] Set the component index to manifest_item.m_manifest_index. */ bool SetIdentification( const class ON_ComponentManifestItem& manifest_item, const wchar_t* manifest_name, bool bSetId, bool bParentId, bool bSetName, bool bSetIndex ); /////////////////////////////////////////////////////////////////////////////// // // General attributes interface // // /* Description: Writes the attributes identified by the component_filter parameter. Parameters: attributes_filter - [in] A bitfield that determines which attributes will be cleared. Returns: a bitfield indicating which attributes were cleared. (Locked attributes cannot be cleared.) */ unsigned int ClearModelComponentAttributes( unsigned int attributes_filter ); /* Returns: The runtime serial number. This value is unique for every instance of an ON_ModelComponent class. This value is never saved in .3dm archives. */ ON__UINT64 RuntimeSerialNumber() const; /* Description: Whenever an attribute is changed, the content version number is incremented. The ContentVersionNumber() is commonly used by consumers of the model component attributes to trigger updates when needed. Remarks: The ContentVersionNumber value is copied by the copy constructor and operator=. The value is not saved in .3dm archives. */ ON__UINT64 ContentVersionNumber() const; /* Returns: True if this model component is a system constant. Remarks: An incomplete list of system constant model compoenents is below: ON_ModelComponent::Unset ON_InstanceDefinition::Empty ON_Linetype::Unset ON_Linetype::Continuous ON_Linetype::ByLayer ON_Linetype::ByParent ON_Layer::Unset ON_Layer::Default ON_TextStyle::Unset ON_TextStyle::Default ON_TextStyle::ByLayer ON_TextStyle::ByParent ON_DimStyle::Unset ON_DimStyle::Default ON_DimStyle::DefaultInchDecimal ON_DimStyle::DefaultInchFractional ON_DimStyle::DefaultFootInchArchitecture ON_DimStyle::DefaultMillimeterSmall ON_DimStyle::DefaultMillimeterLarge ON_DimStyle::DefaultMillimeterArchitecture */ bool IsSystemComponent() const; bool EraseIdentification( bool bIgnoreLocks ); bool SetAsSystemComponent(); bool SetAsUnsetSystemComponent(); private: bool Internal_SetAsSystemComponent( bool bUnsetSystemComponent ); protected: /* Classes derived from ON_ModelComponent should have private data members and call IncrementContentVersionNumber() when the data member value changes. */ void IncrementContentVersionNumber() const; private: const ON__UINT64 m_runtime_serial_number; mutable ON__UINT64 m_content_version_number = 0; ON__UINT32 m_model_serial_number = 0; ON__UINT32 m_reference_model_serial_number = 0; ON__UINT32 m_linked_idef_serial_number = 0; ON_ModelComponent::Type m_component_type = ON_ModelComponent::Type::Unset; ON__UINT16 m_locked_status = 0; ON__UINT16 m_set_status = 0; ON_ComponentStatus m_component_status = ON_ComponentStatus::NoneSet; ON__UINT8 m_reserved1 = 0; ON__UINT16 m_reserved2 = 0; // m_component_index is the index of the component in the model identified // by m_model_serial_number. // // Some components use small negative indices (-1,-2,-3,...) to identify // default or constant components. An incomplete list includes these: // ON_TextStyle::Default, (index = -1) // ON_TextStyle::ByLayer, (index = -2) // ON_TextStyle::ByParent, (index = -3) // ON_Linetype::Continuous, (index = -1) // ON_Linetype::ByLayer, (index = -2) // ON_Linetype::ByParent, (index = -3) // // ON_UNSET_INT_INDEX is a large negative number. ON__INT32 m_component_index = ON_UNSET_INT_INDEX; ON__UINT32 m_reserved3 = 0; ON_UUID m_component_id = ON_nil_uuid; ON_UUID m_component_parent_id = ON_nil_uuid; // lazy evaluation is used top initialize m_component_name_hash mutable ON_NameHash m_component_name_hash; ON_wString m_component_name; public: // For internal use. Never call this function. static unsigned int Internal_SystemComponentHelper(); }; class ON_CLASS ON_ModelComponentContentMark { public: static const ON_ModelComponentContentMark Unset; public: ON_ModelComponentContentMark() = default; ~ON_ModelComponentContentMark() = default; ON_ModelComponentContentMark(const ON_ModelComponentContentMark&) = default; ON_ModelComponentContentMark& operator=(const ON_ModelComponentContentMark&) = default; /* Description: Save the current content state of model_component. Parameters: model_component - [in] */ ON_ModelComponentContentMark( const class ON_ModelComponent& model_component ); /* Description: Save the current content state of model_component. Parameters: model_component - [in] */ ON_ModelComponentContentMark( const class ON_ModelComponent* model_component ); /* Description: Save the current content state of model_component. Parameters: model_component - [in] */ void Set( const class ON_ModelComponent& model_component ); /* Description: Save the current content state of model_component. Parameters: model_component - [in] */ void Set( const class ON_ModelComponent* model_component ); /* Parameters: model_component - [in] Returns: true if the content of model_component is identical to the content state saved in this ON_ModelComponentContentMark. false otherwise. */ bool EqualContent( const class ON_ModelComponent& model_component ) const; /* Parameters: model_component - [in] Returns: true if the content of model_component is identical to the content state saved in this ON_ModelComponentContentMark. false otherwise. */ bool EqualContent( const class ON_ModelComponent* model_component ) const; /* Parameters: lhs - [in] rhs - [in] Returns: true if lhs and rhs are identical. false otherwise. */ static bool EqualContent( const ON_ModelComponentContentMark& lhs, const ON_ModelComponentContentMark& rhs ); /* Returns: Saved model component id. */ ON_UUID ComponentId() const; /* Returns: Saved model component runtime serial number. */ ON__UINT64 ComponentRuntimeSerialNumber() const; /* Returns: Saved model component content version number. */ ON__UINT64 ComponentContentVersionNumber() const; /* Returns: Saved model component type. */ ON_ModelComponent::Type ComponentType() const; /* Returns: True if a model component content state is saved in this ON_ModelComponentContentMark. False otherwise. */ bool IsSet() const; /* Returns: True if a model component content state is saved in this ON_ModelComponentContentMark. False otherwise. */ bool IsUnset() const; private: ON_UUID m_component_id = ON_nil_uuid; ON__UINT64 m_component_serial_number = 0; ON__UINT64 m_component_content_version_number = 0; ON_ModelComponent::Type m_component_type = ON_ModelComponent::Type::Unset; private: unsigned char m_reserved1 = 0; unsigned char m_reserved2 = 0; unsigned char m_reserved3 = 0; unsigned int m_reserved4 = 0; }; bool operator==( const ON_ModelComponentContentMark& lhs, const ON_ModelComponentContentMark& rhs ); bool operator!=( const ON_ModelComponentContentMark& lhs, const ON_ModelComponentContentMark& rhs ); class ON_CLASS ON_ModelComponentTypeIterator { public: // Default constructor creates ON_ModelComponentTypeIterator::Empty ON_ModelComponentTypeIterator() ON_NOEXCEPT; ~ON_ModelComponentTypeIterator() = default; ON_ModelComponentTypeIterator(const ON_ModelComponentTypeIterator&) = default; ON_ModelComponentTypeIterator& operator=(const ON_ModelComponentTypeIterator&) = default; /* Paramters: type_count - [in] number of types types - [in] list of types to iterate over */ ON_ModelComponentTypeIterator( size_t type_count, const ON_ModelComponent::Type* types ) ON_NOEXCEPT; // Contains no types static const ON_ModelComponentTypeIterator Empty; // Contains all explicit component types (excludes Unset and Mixed). static const ON_ModelComponentTypeIterator ExplicitComponentTypes; // Every type in ON_ModelComponentTypeIterator::ExplicitComponents // except Image, RenderLight, ModelGeometry, and HistoryRecord // The types in ON_ModelComponentTypeIterator::Tables // identify the most commonly used "table" component types. static const ON_ModelComponentTypeIterator TableComponentTypes; // Number of types in the iterator unsigned int TypeCount() const; /* Description: Sets the iterator to point to the first available type. Returns: The first available type. */ ON_ModelComponent::Type FirstType(); /* Description: Sets the iterator to point to the last available type. Returns: The last available type. */ ON_ModelComponent::Type LastType(); /* Description: Increments the iterator and returns the new type. Returns: The new type. ON_ModelComponent::Type::Unset if the iterator is incremented the last type. */ ON_ModelComponent::Type NextType(); /* Description: Decrements the iterator and returns the new type. Returns: The new type ON_ModelComponent::Type::Unset if the iterator is decrented the first type. */ ON_ModelComponent::Type PreviousType(); /* Description: Decrements the iterator and returns the new type. Returns: The current type. */ ON_ModelComponent::Type CurrentType() const; private: ON__INT32 m_type_count = 0; // -1 iterated before first, m_type_count = iteratated past last ON__INT32 m_current_index = ON_UNSET_UINT_INDEX; ON_ModelComponent::Type m_types[32]; }; class ON_CLASS ON_ModelComponentReference { public: static const ON_ModelComponentReference Empty; // No = default to insure m_sp is completely managed in the openurbs DLL. ON_ModelComponentReference() ON_NOEXCEPT; // No = default to insure m_sp is completely managed in the openurbs DLL. ~ON_ModelComponentReference(); // No = default to insure m_sp is completely managed in the openurbs DLL. ON_ModelComponentReference(const ON_ModelComponentReference&) ON_NOEXCEPT; // No = default to insure m_sp is completely managed in the openurbs DLL. ON_ModelComponentReference& operator=(const ON_ModelComponentReference&); // No = default to insure m_sp is completely managed in the openurbs DLL. #if defined(ON_HAS_RVALUEREF) ON_ModelComponentReference( ON_ModelComponentReference&& ) ON_NOEXCEPT; ON_ModelComponentReference& operator=( ON_ModelComponentReference&& ); #endif ON_ModelComponentReference( std::shared_ptr& sp ) ON_NOEXCEPT; ON_ModelComponentReference& operator=( std::shared_ptr& sp ); /* Parameters: constant_system_component - [in] A constant system component that exists for the duration of the application. Remarks: See ON_ModelComponent::CreateConstantSystemComponentReference() for more information about constant system components. */ static ON_ModelComponentReference CreateConstantSystemComponentReference( const class ON_ModelComponent& constant_system_component ) ON_NOEXCEPT; /* Parameters: model_component - [in] bManagedComponentReference - [in] true model_component will be deleted by the last ON_ModelComponentReference and must have been created by call to operator new() with heap allocation. false model_component must remain in scope until the last ON_ModelComponentReference is destroyed. Remarks: The input pointer will be managed and deleted by the returned by ON_ModelComponentReference. */ static ON_ModelComponentReference CreateForExperts( class ON_ModelComponent* model_component, bool bManagedComponentReference ) ON_NOEXCEPT; /* Return: A pointer to the managed model component or nullptr. */ const class ON_ModelComponent* ModelComponent() const ON_NOEXCEPT; ON__UINT64 ModelComponentRuntimeSerialNumber() const ON_NOEXCEPT; const ON_UUID ModelComponentId() const ON_NOEXCEPT; const ON_NameHash ModelComponentNameHash() const ON_NOEXCEPT; int ModelComponentIndex() const ON_NOEXCEPT; unsigned int ReferenceCount() const ON_NOEXCEPT; bool IsEmpty() const ON_NOEXCEPT; void Dump( ON_TextLog& text_log ) const; private: #pragma ON_PRAGMA_WARNING_PUSH #pragma ON_PRAGMA_WARNING_DISABLE_MSC( 4251 ) // C4251: ... needs to have dll-interface to be used by clients of class ... // m_sp is private and all code that manages m_sp is explicitly implemented in the DLL. std::shared_ptr m_sp; #pragma ON_PRAGMA_WARNING_POP }; #if defined(ON_DLL_TEMPLATE) ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray; #endif #endif