mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-02 12:37:02 +08:00
1203 lines
40 KiB
C++
1203 lines
40 KiB
C++
//
|
|
// Copyright (c) 1993-2022 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>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// virtual base class for all openNURBS objects
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(OPENNURBS_OBJECT_INC_)
|
|
#define OPENNURBS_OBJECT_INC_
|
|
|
|
|
|
class ON_ClassId; // used for runtime class identification
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
/*
|
|
Description:
|
|
OpenNURBS classes derived from ON_Object use ON_ClassId to
|
|
store run-time type information
|
|
|
|
The ON_OBJECT_DECLARE and ON_OBJECT_IMPLEMENT macros generate
|
|
the code that creates and initializes the ON_ClassId for each
|
|
class.
|
|
|
|
The ON_Object::IsKindOf() and ON_Object::Cast() functions
|
|
use this run-time type information.
|
|
*/
|
|
class ON_CLASS ON_ClassId
|
|
{
|
|
public:
|
|
|
|
// Description:
|
|
// This constructor is called to initialize each class id.
|
|
// The call is generated by the ON_OBJECT_IMPLEMENT macro.
|
|
//
|
|
// Parameters:
|
|
// sClassName - [in] name of the class (like ON_Geometry)
|
|
// sBaseClassName - [in] name of baseclass (like ON_Object)
|
|
// create - [in] function to create a new object(like CreateNewON_Geometry())
|
|
// sUUID - [in] UUID in registry format from Windows guidgen.exe
|
|
ON_ClassId(
|
|
const char* sClassName,
|
|
const char* sBaseClassName,
|
|
class ON_Object* (*create)(),
|
|
const char* sUUID
|
|
);
|
|
|
|
~ON_ClassId();
|
|
|
|
// Description:
|
|
// Gets a class's ON_ClassId from the class's name.
|
|
// Parameters:
|
|
// sClassName - [in] name of class
|
|
// Returns:
|
|
// Pointer to the class's ON_ClassId.
|
|
// Example:
|
|
// const ON_ClassId* brep_id = ON_CLassId::ClassId("ON_Brep");
|
|
static const ON_ClassId* ClassId(
|
|
const char* sClassName
|
|
);
|
|
|
|
// Description:
|
|
// Gets a class's ON_ClassId from the class's uuid.
|
|
// Parameters:
|
|
// class_uuid - [in] uuid for the class
|
|
// Returns:
|
|
// Pointer to the class's ON_ClassId.
|
|
// Example:
|
|
// ON_UUID brep_uuid = ON_UuidFromString("60B5DBC5-E660-11d3-BFE4-0010830122F0");
|
|
// const ON_ClassId* brep_id = ON_ClassId::ClassId(brep_uuid);
|
|
static const ON_ClassId* ClassId(
|
|
ON_UUID class_uuid
|
|
);
|
|
|
|
// Description:
|
|
// Each class derived from ON_Object has a corresponding ON_ClassId
|
|
// stored in a linked list and the class is marked with an integer
|
|
// value. ON_ClassId::IncrementMark() increments the value used to
|
|
// mark new classes and returns the new marking value.
|
|
// Returns:
|
|
// Value that will be used to mark all future ON_ClassIds.
|
|
static int IncrementMark();
|
|
static int CurrentMark();
|
|
static const ON_ClassId* LastClassId();
|
|
|
|
// Description:
|
|
// Each class derived from ON_Object has a corresponding
|
|
// ON_ClassId stored in a linked list. If a class definition
|
|
// is going to disappear (which happens when the derived object
|
|
// definition is in a DLL that uses openNURBS as a DLL and the
|
|
// DLL containing the derived object's definition is unloaded),
|
|
// then the class's ON_ClassId needs to be removed from the class
|
|
// list. ON_ClassId::Purge( mark ) removes all ON_ClassIds with a
|
|
// a prescribed mark and returns the number of classes that
|
|
// were purged.
|
|
// Parameters:
|
|
// mark - [in] All ON_ClassIds with this mark will be purged.
|
|
// Returns:
|
|
// Number of classes that were purged.
|
|
// Example:
|
|
// // Call ON_ClassId::IncrementMark() BEFORE loading MY.DLL.
|
|
// int my_dll_classid_mark = ON_ClassId::IncrementMark();
|
|
// load MY.DLL with classes derived from ON_Object
|
|
// ...
|
|
// // Call ON_ClassId::Purge() BEFORE unloading MY.DLL.
|
|
// ON_ClassId::Purge( my_dll_classid_mark );
|
|
// unload MY.DLL
|
|
static int Purge(int mark);
|
|
static bool PurgeAfter(const ON_ClassId* pClassId);
|
|
|
|
// Description:
|
|
// Dumps the ON_ClassId list
|
|
// Parameters:
|
|
// dump - [in] destination for the text dump.
|
|
static void Dump(
|
|
ON_TextLog& dump
|
|
);
|
|
|
|
// Returns:
|
|
// class name
|
|
const char* ClassName() const;
|
|
|
|
// Returns:
|
|
// base class name
|
|
const char* BaseClassName() const;
|
|
|
|
// Returns:
|
|
// base class id
|
|
const ON_ClassId* BaseClass() const;
|
|
|
|
// Description:
|
|
// Determine if the class associated with this ON_ClassId
|
|
// is derived from another class.
|
|
// Parameters:
|
|
// potential_parent - [in] Class to test as parent.
|
|
// Returns:
|
|
// true if this is derived from potential_parent.
|
|
bool IsDerivedFrom(
|
|
const ON_ClassId* potential_parent
|
|
) const;
|
|
|
|
// Description:
|
|
// Use the default constructor to create an instance of the
|
|
// class on the heap.
|
|
// Returns:
|
|
// Null or a pointer to an instance of the class created
|
|
// using new and the class's default constructor.
|
|
ON_Object* Create() const;
|
|
|
|
// Returns:
|
|
// class uuid
|
|
ON_UUID Uuid() const;
|
|
|
|
/*
|
|
Description:
|
|
Opennurbs classes have a mark value of 0. Core Rhino
|
|
classes have a mark value of 1. Rhino plug-in classes
|
|
have a mark value of > 1.
|
|
Returns:
|
|
Class mark value
|
|
*/
|
|
int Mark() const;
|
|
|
|
unsigned int ClassIdVersion() const;
|
|
|
|
private:
|
|
static ON_ClassId* m_p0; // first id in the linked list of class ids
|
|
static ON_ClassId* m_p1; // last id in the linked list of class ids
|
|
static int m_mark0; // current mark value
|
|
ON_ClassId* m_pNext; // next in the linked list of class ids
|
|
const ON_ClassId* m_pBaseClassId; // base class id
|
|
char m_sClassName[80];
|
|
char m_sBaseClassName[80];
|
|
// m_create points to a function that calls the default constructor.
|
|
// m_create() is used to create classes from uuids when reading files.
|
|
ON_Object* (*m_create)();
|
|
ON_UUID m_uuid;
|
|
int m_mark; // bit 0x80000000 is used to indicate new extensions
|
|
|
|
private:
|
|
// There are no implementations of the default constructor, copy constructor
|
|
// or operator=() to prohibit use.
|
|
ON_ClassId();
|
|
ON_ClassId( const ON_ClassId&);
|
|
ON_ClassId& operator=( const ON_ClassId&);
|
|
|
|
private:
|
|
void ConstructorHelper(
|
|
const char* sClassName,
|
|
const char* sBaseClassName,
|
|
const char* sUUID
|
|
);
|
|
|
|
// The m_f[] pointers provide a way add a "virtual" function to
|
|
// a class derived from ON_Object without breaking the SDK.
|
|
// At each SDK breaking release, any functions that use this
|
|
// mechanism are made into C++ virtual functions on the appropriate
|
|
// classes. Currently, none of these are in use.
|
|
unsigned int m_class_id_version;
|
|
void* m_f1;
|
|
void* m_f2;
|
|
void* m_f3;
|
|
void* m_f4;
|
|
void* m_f5;
|
|
void* m_f6;
|
|
void* m_f7;
|
|
void* m_f8;
|
|
};
|
|
|
|
/*
|
|
Description:
|
|
ON_CLASS_RTTI is a macro to get the class's run-time type
|
|
information from class name.
|
|
Example:
|
|
// Get the ON_Brep class's run-time type information.
|
|
const ON_ClassId& brep_rtti = ON_CLASS_RTTI(ON_Brep);
|
|
*/
|
|
#define ON_CLASS_RTTI( cls ) cls::m_##cls##_class_rtti
|
|
|
|
/*
|
|
Description:
|
|
ON_CLASS_ID is a macro to get the class's uuid from
|
|
a class name.
|
|
Example:
|
|
// Get the class id for ON_Brep.
|
|
ON_UUID brep_class_id = ON_CLASS_ID(ON_Brep);
|
|
*/
|
|
#define ON_CLASS_ID( cls ) ON_CLASS_RTTI( cls ).Uuid()
|
|
|
|
/*
|
|
Description:
|
|
Expert user function to get the value of ON_ClassId::m_uuid
|
|
of the last instance of ON_ClassId to call ON_ClassId::Create().
|
|
This function was created to support Rhino's .NET SDK.
|
|
This function returns the value of a static id in
|
|
opennurbs_object.cpp and is NOT thread safe.
|
|
Returns:
|
|
Value of ON_ClassId::m_uuid of the instance of ON_ClassId that
|
|
most recently called ON_ClassId::Create().
|
|
*/
|
|
ON_DECL
|
|
ON_UUID ON_GetMostRecentClassIdCreateUuid();
|
|
|
|
|
|
#define ON_OBJECT_DECLARE_VIRTUAL
|
|
#define ON_OBJECT_DECLARE_OVERRIDE override
|
|
|
|
/*
|
|
All classes derived from ON_Object must have the declaration macro
|
|
ON_OBJECT_DECLARE( <classname> );
|
|
as the first line in their class definition, must have a robust
|
|
operator=(), should have a robust copy constructor, and must
|
|
have exactly one of the following implementation macros in
|
|
a .cpp file.
|
|
Classes with a pure virtual function:
|
|
ON_VIRTUAL_OBJECT_IMPLEMENT( <classname>, <basclassname>, <classuuid> )
|
|
Classes with an operator= and copy constructor.
|
|
ON_OBJECT_IMPLEMENT( <classname>, <basclassname>, <classuuid> )
|
|
Classes with an operator=, but no copy constructor.
|
|
ON_OBJECT_IMPLEMENT_NO_COPYCTOR( <classname>, <basclassname>, <classuuid> )
|
|
*/
|
|
#define ON_OBJECT_DECLARE( cls ) \
|
|
protected: \
|
|
static void* m_s_##cls##_ptr; \
|
|
\
|
|
public: \
|
|
/* OpenNURBS class run-time type information */ \
|
|
static const ON_ClassId m_##cls##_class_rtti; \
|
|
\
|
|
/*OpenNURBS platform independent dynamic cast*/ \
|
|
static cls * Cast( ON_Object* ); \
|
|
\
|
|
/*OpenNURBS platform independent dynamic cast*/ \
|
|
static const cls * Cast( const ON_Object* ); \
|
|
\
|
|
/*Returns: OpenNURBS run-time type information.*/ \
|
|
ON_OBJECT_DECLARE_VIRTUAL const ON_ClassId* ClassId() const ON_OBJECT_DECLARE_OVERRIDE; \
|
|
\
|
|
public: \
|
|
/*Description: */ \
|
|
/* Uses a virtual function to create a deep copy. */ \
|
|
/*Returns: */ \
|
|
/* null or a deep copy with type this->ClassId(). */ \
|
|
/*See Also: */ \
|
|
/* ON_Curve::DuplicateCurve() */ \
|
|
/* ON_Surface::DuplicateSurface() */ \
|
|
/* CRhinoObject::DuplicateRhinoObject() */ \
|
|
cls * Duplicate() const; \
|
|
\
|
|
/*Description: */ \
|
|
/* Uses operator= to copy src to this. */ \
|
|
/*Returns: */ \
|
|
/* True if successful. */ \
|
|
/* False if src is null or an incompatible type. */ \
|
|
ON_OBJECT_DECLARE_VIRTUAL bool CopyFrom(const ON_Object*) ON_OBJECT_DECLARE_OVERRIDE; \
|
|
\
|
|
private: \
|
|
/* Duplicate() uses this virtual helper function. */ \
|
|
ON_OBJECT_DECLARE_VIRTUAL ON_Object* Internal_DeepCopy() const ON_OBJECT_DECLARE_OVERRIDE \
|
|
|
|
|
|
/*
|
|
Classes derived from ON_Object that are pure virtual classes,
|
|
or do not have a valid default constructor, valid operator new
|
|
or valid operator= must use ON_VIRTUAL_OBJECT_IMPLEMENT in their
|
|
implementation. Classes implemented with ON_VIRTUAL_OBJECT_IMPLEMENT
|
|
cannot be serialized using ON_BinaryArchive::ReadObject()/WriteObject()
|
|
or duplicated using ON_Object::Duplicate().
|
|
The Cast() and ClassId() members work on classes implemented with
|
|
ON_VIRTUAL_OBJECT_IMPLEMENT, ON_OBJECT_IMPLEMENT or
|
|
ON_OBJECT_IMPLEMENT_NO_COPYCTOR
|
|
*/
|
|
#define ON_VIRTUAL_OBJECT_IMPLEMENT( cls, basecls, uuid ) \
|
|
void* cls::m_s_##cls##_ptr = nullptr; \
|
|
const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,0,uuid);\
|
|
cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
|
|
const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
|
|
const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
|
|
bool cls::CopyFrom(const ON_Object*) {return false;} \
|
|
cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
|
|
ON_Object* cls::Internal_DeepCopy() const {return nullptr;}
|
|
|
|
/*
|
|
Classes derived from ON_Object that have a valid default constructor,
|
|
valid copy constructor, operator new and operator= can use
|
|
ON_OBJECT_IMPLEMENT in their implementation. Classes implemented
|
|
with ON_OBJECT_IMPLEMENT can be created from their run-time type
|
|
information id and their Duplicate() function will use the class's
|
|
copy constructor to create a deep copy.
|
|
*/
|
|
#define ON_OBJECT_IMPLEMENT( cls, basecls, uuid ) \
|
|
void* cls::m_s_##cls##_ptr = nullptr; \
|
|
static ON_Object* CreateNew##cls() {return new cls();} \
|
|
const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
|
|
cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
|
|
const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
|
|
const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
|
|
bool cls::CopyFrom( const ON_Object* src){const cls * s=cls::Cast(src); if ( nullptr != this && nullptr != s) {*this = *s; return true;}return false;} \
|
|
cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
|
|
ON_Object* cls::Internal_DeepCopy() const {return new cls (*this);}
|
|
|
|
/*
|
|
Classes derived from ON_Object that have a valid default constructor,
|
|
operator new and operator=, but do not have a valid copy constructor,
|
|
can use ON_OBJECT_IMPLEMENT_NO_COPYCTOR in their implementation.
|
|
Classes implemented with ON_OBJECT_IMPLEMENT_NO_COPYCTOR can be created
|
|
from their run-time type information id and their Duplicate() function
|
|
will use the class's default constructor and operator= to create a
|
|
deep copy.
|
|
*/
|
|
#define ON_OBJECT_IMPLEMENT_NO_COPYCTOR( cls, basecls, uuid ) \
|
|
void* cls::m_s_##cls##_ptr = nullptr; \
|
|
static ON_Object* CreateNew##cls() {return new cls();} \
|
|
const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
|
|
cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
|
|
const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
|
|
const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
|
|
bool cls::CopyFrom( const ON_Object* src){const cls* s=cls::Cast(src); if ( 0 != this && 0 != s) {*this = *s; return true;}return false;} \
|
|
cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
|
|
ON_Object* cls::Internal_DeepCopy() const { cls* p = new cls();if (p) {*p = *this; return p;}return nullptr;}
|
|
|
|
/*
|
|
Classes derived from ON_Object that have a valid default constructor,
|
|
operator new and operator=, but do not have a valid copy constructor or assignment operator,
|
|
can use ON_OBJECT_IMPLEMENT_NO_COPY in their implementation.
|
|
Classes implemented with ON_OBJECT_IMPLEMENT_NO_COPY can be created
|
|
from their run-time type information id and their Duplicate() function
|
|
will silently return a nullptr. CopyFrom will return false.
|
|
*/
|
|
#define ON_OBJECT_IMPLEMENT_NO_COPY( cls, basecls, uuid ) \
|
|
void* cls::m_s_##cls##_ptr = nullptr; \
|
|
static ON_Object* CreateNew##cls() {return new cls();} \
|
|
const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
|
|
cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
|
|
const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
|
|
const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
|
|
bool cls::CopyFrom( const ON_Object* src){return false;} \
|
|
cls * cls::Duplicate() const {return nullptr;} \
|
|
ON_Object* cls::Internal_DeepCopy() const { return nullptr;}
|
|
|
|
#define ON__SET__THIS__PTR(ptr) if (ptr) *((void**)this) = ptr
|
|
|
|
class ON_CLASS ON_UserString
|
|
{
|
|
public:
|
|
ON_UserString();
|
|
~ON_UserString();
|
|
ON_wString m_key;
|
|
ON_wString m_string_value;
|
|
|
|
void Dump(ON_TextLog& text_log) const;
|
|
bool Write(ON_BinaryArchive&) const;
|
|
bool Read(ON_BinaryArchive&);
|
|
};
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_UserString>;
|
|
#endif
|
|
|
|
/*
|
|
Description:
|
|
When ON_Object::IsValid() fails and returns false, ON_IsNotValid()
|
|
is called. This way, a developer can put a breakpoint in
|
|
ON_IsNotValid() and stop execution at the exact place IsValid()
|
|
fails.
|
|
Returns:
|
|
false;
|
|
*/
|
|
ON_DECL
|
|
bool ON_IsNotValid();
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Description:
|
|
// Pure virtual base class for all classes that must provide
|
|
// runtime class id or support object level 3DM serialization
|
|
class ON_CLASS ON_Object
|
|
{
|
|
#undef ON_OBJECT_DECLARE_VIRTUAL
|
|
#undef ON_OBJECT_DECLARE_OVERRIDE
|
|
#define ON_OBJECT_DECLARE_VIRTUAL virtual
|
|
#define ON_OBJECT_DECLARE_OVERRIDE
|
|
// This is the base class
|
|
ON_OBJECT_DECLARE(ON_Object);
|
|
// Every other use of ON_OBJECT_DECLARE() is in derived class
|
|
#undef ON_OBJECT_DECLARE_VIRTUAL
|
|
#undef ON_OBJECT_DECLARE_OVERRIDE
|
|
#define ON_OBJECT_DECLARE_VIRTUAL
|
|
#define ON_OBJECT_DECLARE_OVERRIDE override
|
|
|
|
public:
|
|
ON_Object() ON_NOEXCEPT;
|
|
virtual ~ON_Object();
|
|
ON_Object( const ON_Object& );
|
|
ON_Object& operator=( const ON_Object& );
|
|
|
|
#if defined(ON_HAS_RVALUEREF)
|
|
// rvalue copy constructor
|
|
ON_Object( ON_Object&& ) ON_NOEXCEPT;
|
|
|
|
// The rvalue assignment operator calls this->PurgeUserData()
|
|
// which calls unknown destructors that could throw exceptions.
|
|
ON_Object& operator=( ON_Object&& );
|
|
#endif
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
/*
|
|
Description:
|
|
Sets m_user_data_list = 0.
|
|
*/
|
|
void EmergencyDestroy();
|
|
|
|
/*
|
|
Description:
|
|
The MemoryRelocate() function is called when an
|
|
object's location in memory is changed. For
|
|
example, if an object resides in a chunk of
|
|
memory that is grown by calling a realloc
|
|
that has to allocate a new chunk and
|
|
copy the contents of the old chunk to the
|
|
new chunk, then the location of the object's
|
|
memory changes. In practice this happens when
|
|
classes derived from ON_Object are stored
|
|
in dynamic arrays, like the default implementation
|
|
of ON_ObjectArray<>'s that use realloc to grow
|
|
the dynamic array.
|
|
*/
|
|
virtual
|
|
void MemoryRelocate();
|
|
|
|
/*
|
|
Description:
|
|
Low level tool to test if an object is derived
|
|
from a specified class.
|
|
Parameters:
|
|
pClassId - [in] use classname::ClassId()
|
|
Returns:
|
|
true if the instantiated object is derived from the
|
|
class whose id is passed as the argument.
|
|
Example:
|
|
|
|
ON_Object* p = ....;
|
|
if ( p->IsKindOf( ON_NurbsCurve::ClassId() ) )
|
|
{
|
|
it's a NURBS curve
|
|
}
|
|
|
|
Remarks:
|
|
The primary reason for IsKindOf() is to support the
|
|
static Cast() members declared in the ON_OBJECT_DECLARE
|
|
macro. If we determine that dynamic_cast is properly
|
|
supported and implemented by all supported compilers,
|
|
then IsKindOf() may disappear. If an application needs
|
|
to determine if a pointer points to a class derived from
|
|
ON_SomeClassName, then call
|
|
ON_SomeClassName::Cast(mystery pointer) and check for
|
|
a non-null return.
|
|
*/
|
|
bool IsKindOf(
|
|
const ON_ClassId* pClassId
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Tests an object to see if its data members are correctly
|
|
initialized.
|
|
Parameters:
|
|
text_log - [in] if the object is not valid and text_log
|
|
is not nullptr, then a brief english description of the
|
|
reason the object is not valid is appended to the log.
|
|
The information appended to text_log is suitable for
|
|
low-level debugging purposes by programmers and is
|
|
not intended to be useful as a high level user
|
|
interface tool.
|
|
Returns:
|
|
@untitled table
|
|
true object is valid
|
|
false object is invalid, uninitialized, etc.
|
|
*/
|
|
virtual bool IsValid( class ON_TextLog* text_log = nullptr ) const;
|
|
|
|
/*
|
|
Description:
|
|
Tests to see if this is null in ways that will prevent compilers like
|
|
CLang from thinking the test is not necessary.
|
|
The reason the runtime test is being performed is to find bugs that call
|
|
member functions on null pointers.
|
|
*/
|
|
bool ThisIsNullptr(
|
|
bool bSilentError
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Check for corrupt data values that are likely to cause crashes.
|
|
Parameters:
|
|
bRepair - [in]
|
|
If true, const_cast<> will be used to change the corrupt data
|
|
so that crashes are less likely.
|
|
bSilentError - [in]
|
|
If true, ON_ERROR will not be called when corruption is detected.
|
|
text_log - [out]
|
|
If text_log is not null, then a description of corruption
|
|
is printed using text_log.
|
|
Remarks:
|
|
Ideally, IsCorrupt() would be a virtual function on ON_Object,
|
|
but doing that at this point would break the public SDK.
|
|
*/
|
|
bool IsCorrupt(
|
|
bool bRepair,
|
|
bool bSilentError,
|
|
class ON_TextLog* text_log
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Creates a text dump of the object.
|
|
Remarks:
|
|
Dump() is intended for debugging and is not suitable
|
|
for creating high quality text descriptions of an
|
|
object.
|
|
|
|
The default implementations of this virtual function
|
|
prints the class's name.
|
|
*/
|
|
virtual
|
|
void Dump( ON_TextLog& ) const;
|
|
|
|
/// <summary>
|
|
/// Go through the linked list of ON_UserData attached to this and
|
|
/// call the virtual Dump(text_log) function on each instance.
|
|
/// </summary>
|
|
/// <param name="description">
|
|
/// General context description to print before each instance.
|
|
/// </param>
|
|
/// <param name="text_log">
|
|
/// Destination text log.
|
|
/// </param>
|
|
void DumpUserData(const wchar_t* description, ON_TextLog& text_log) const;
|
|
|
|
/*
|
|
Returns:
|
|
An estimate of the amount of memory the class uses in bytes.
|
|
*/
|
|
virtual
|
|
unsigned int SizeOf() const;
|
|
|
|
/*
|
|
Description:
|
|
Returns a CRC calculated from the information that defines
|
|
the object. This CRC can be used as a quick way to see
|
|
if two objects are not identical.
|
|
Parameters:
|
|
current_remainder - [in];
|
|
Returns:
|
|
CRC of the information the defines the object.
|
|
*/
|
|
virtual
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
|
|
/*
|
|
Description:
|
|
Low level archive writing tool used by ON_BinaryArchive::WriteObject().
|
|
Parameters:
|
|
binary_archive - archive to write to
|
|
Returns:
|
|
Returns true if the write is successful.
|
|
Remarks:
|
|
Use ON_BinaryArchive::WriteObject() to write objects.
|
|
This Write() function should just write the specific definition of
|
|
this object. It should not write and any chunk typecode or length
|
|
information.
|
|
|
|
The default implementation of this virtual function returns
|
|
false and does nothing.
|
|
*/
|
|
virtual
|
|
bool Write(
|
|
ON_BinaryArchive& binary_archive
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Low level archive writing tool used by ON_BinaryArchive::ReadObject().
|
|
Parameters:
|
|
binary_archive - archive to read from
|
|
Returns:
|
|
Returns true if the read is successful.
|
|
Remarks:
|
|
Use ON_BinaryArchive::ReadObject() to read objects.
|
|
This Read() function should read the objects definition back into
|
|
its data members.
|
|
|
|
The default implementation of this virtual function returns
|
|
false and does nothing.
|
|
*/
|
|
virtual
|
|
bool Read(
|
|
ON_BinaryArchive& binary_archive
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Useful for switch statements that need to differentiate
|
|
between basic object types like points, curves, surfaces,
|
|
and so on.
|
|
|
|
Returns:
|
|
ON::object_type enum value.
|
|
|
|
Remarks:
|
|
The default implementation of this virtual function returns
|
|
ON::unknown_object_type
|
|
*/
|
|
virtual
|
|
ON::object_type ObjectType() const;
|
|
|
|
|
|
|
|
/*
|
|
Description:
|
|
All objects in an opennurbs model have an id
|
|
( ON_Layer.m_layer_id, ON_Font.m_font_id,
|
|
ON_Material.m_material_id, ON_3dmObjectAttributes.m_uuid
|
|
).
|
|
Returns:
|
|
The id used to identify the object in the opennurbs model.
|
|
*/
|
|
virtual
|
|
ON_UUID ModelObjectId() const;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// BEGIN: User string support
|
|
//
|
|
|
|
/*
|
|
Description:
|
|
Attach a user string to the object. This information will
|
|
persist through copy construction, operator=, and file IO.
|
|
Parameters:
|
|
key - [in] id used to retrieve this string.
|
|
string_value - [in]
|
|
If nullptr, the string with this id will be removed.
|
|
Returns:
|
|
True if successful.
|
|
*/
|
|
bool SetUserString(
|
|
const wchar_t* key,
|
|
const wchar_t* string_value
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Append entries to the user string list
|
|
Parameters:
|
|
count - [in]
|
|
number of element in us[] array
|
|
user_strings - [in]
|
|
entries to append.
|
|
bReplace - [in]
|
|
If bReplace is true, then existing entries with the same key are
|
|
updated with the new entry's value. If bReplace is false, then
|
|
existing entries are not updated.
|
|
Returns:
|
|
Number of entries added, deleted, or modified.
|
|
*/
|
|
int SetUserStrings( int count, const ON_UserString* user_strings, bool bReplace );
|
|
|
|
/*
|
|
Description:
|
|
Get user string from the object.
|
|
Parameters:
|
|
key - [in] id used to retrieve the string.
|
|
string_value - [out]
|
|
Returns:
|
|
True if a string with id was found.
|
|
*/
|
|
bool GetUserString(
|
|
const wchar_t* key,
|
|
ON_wString& string_value
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get a list of all user strings on the object.
|
|
Parameters:
|
|
user_strings - [out]
|
|
user strings are appended to this list.
|
|
Returns:
|
|
Number of elements appended to the user_strings list.
|
|
*/
|
|
int GetUserStrings(
|
|
ON_ClassArray<ON_UserString>& user_strings
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get a list of all user string keys on the object.
|
|
Parameters:
|
|
user_string_keys - [out]
|
|
user string keys are appended to this list.
|
|
Returns:
|
|
Number of elements appended to the user_strings list.
|
|
*/
|
|
int GetUserStringKeys(
|
|
ON_ClassArray<ON_wString>& user_string_keys
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of user strings on the object.
|
|
*/
|
|
int UserStringCount() const;
|
|
|
|
//
|
|
// END: User string support
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
// User data provides a standard way for extra information to
|
|
// be attached to any class derived from ON_Object. The attached
|
|
// information can persist and be transformed. If you use user
|
|
// data, please carefully read all the comments from here to the
|
|
// end of the file.
|
|
//
|
|
|
|
/*
|
|
Description:
|
|
Attach user data to an object.
|
|
Parameters:
|
|
pUserData - [in] user data to attach to object.
|
|
The ON_UserData pointer passed to AttachUserData()
|
|
must be created with new.
|
|
Returns:
|
|
If true is returned, then ON_Object will delete the user
|
|
data when appropriate. If false is returned, then data
|
|
could not be attached and caller must delete.
|
|
Remarks:
|
|
AttachUserData() will fail if the user data's m_userdata_uuid
|
|
field is nil or not unique.
|
|
*/
|
|
bool AttachUserData(
|
|
class ON_UserData* pUserData
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Remove user data from an object.
|
|
Parameters:
|
|
pUserData - [in] user data to attach to object.
|
|
The ON_UserData pointer passed to DetachUserData()
|
|
must have been previously attached using
|
|
AttachUserData().
|
|
Returns:
|
|
If true is returned, then the user data was
|
|
attached to this object and it was detached. If false
|
|
is returned, then the user data was not attached to this
|
|
object to begin with. In all cases, you can be assured
|
|
that the user data is no longer attached to "this".
|
|
Remarks:
|
|
Call delete pUserData if you want to destroy the user data.
|
|
*/
|
|
bool DetachUserData(
|
|
class ON_UserData* pUserData
|
|
);
|
|
|
|
|
|
/*
|
|
Description:
|
|
Get a pointer to user data.
|
|
Parameters:
|
|
userdata_uuid - [in] value of the user data's
|
|
m_userdata_uuid field.
|
|
Remarks:
|
|
The returned user data is still attached to the object.
|
|
Deleting the returned user data will automatically remove
|
|
the user data from the object.
|
|
*/
|
|
class ON_UserData* GetUserData(
|
|
const ON_UUID& userdata_uuid
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
PurgeUserData() removes all user data from object.
|
|
Remarks:
|
|
Use delete GetUserData(...) to destroy a single piece
|
|
of user data.
|
|
*/
|
|
void PurgeUserData();
|
|
|
|
/*
|
|
Description:
|
|
User data is stored as a linked list of ON_UserData
|
|
classes. FirstUserData gets the first item in the
|
|
linked list. This is the most recent item attached
|
|
using AttachUserData().
|
|
Remark:
|
|
To iterate through all the user data on an object,
|
|
call FirstUserData() and then use ON_UserData::Next()
|
|
to traverse the list.
|
|
*/
|
|
class ON_UserData* FirstUserData() const;
|
|
|
|
/*
|
|
Description:
|
|
Objects derived from ON_Geometry must call
|
|
TransformUserData() in their Transform() member function.
|
|
Parameters:
|
|
xform - [in] transformation to apply to user data
|
|
*/
|
|
void TransformUserData(
|
|
const class ON_Xform& xform
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
When a userdata item is copied or moved from a source object to
|
|
a destination object, the ON_Object::UserDataConflictResolution
|
|
enum values specify how conflicts are resolved.
|
|
Remark:
|
|
A userdata item "conflict" occurs when both the destination
|
|
and source object have a user data item with the same
|
|
value of ON_UserData::m_userdata_uuid.
|
|
*/
|
|
enum class UserDataConflictResolution : unsigned char
|
|
{
|
|
destination_object = 0, // use destination item
|
|
source_object = 1, // use source item
|
|
source_copycount_gt = 2, // use source item if source copycount > destination copy count
|
|
source_copycount_ge = 3, // use source item if source copycount >= destination copy count
|
|
destination_copycount_gt = 4, // use destination item if destination copycount > source copy count
|
|
destination_copycount_ge = 5, // use destination item if destination copycount >= source copy count
|
|
delete_item = 6 // delete item from the destination object
|
|
};
|
|
|
|
/*
|
|
Description:
|
|
Expert user tool that copies user data items with positive values of
|
|
ON_UserData.m_userdata_copycount from source_object to "this.
|
|
Parameters:
|
|
source_object - [in]
|
|
source of user data to copy
|
|
source_userdata_item_id - [in]
|
|
If source_userdata_item_id is not nil, then only the user data item
|
|
with a matching ON_UserData.m_userdata_uuid value will be copied.
|
|
userdata_conflict_resolution - [in]
|
|
method to resolve userdata item conflicts.
|
|
Remarks:
|
|
Generally speaking you don't need to use CopyUserData().
|
|
Simply rely on ON_Object::operator=() or the copy constructor
|
|
to do the right thing.
|
|
Returns:
|
|
Number of user data items that were copied.
|
|
*/
|
|
unsigned int CopyUserData(
|
|
const ON_Object& source_object,
|
|
ON_UUID source_userdata_item_id,
|
|
ON_Object::UserDataConflictResolution userdata_conflict_resolution
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Expert user tool that moves user data items from source_object to "this.
|
|
Parameters:
|
|
source_object - [in]
|
|
source of user data to copy
|
|
source_userdata_item_id - [in]
|
|
If source_userdata_item_id is not nil, then only the user data item
|
|
with a matching ON_UserData.m_userdata_uuid value will be moved.
|
|
userdata_conflict_resolution - [in]
|
|
method to resolve userdata item conflicts.
|
|
bDeleteAllSourceItems - [in]
|
|
If bDeleteAllSourceItems is true, then any userdata items
|
|
that are not copied from source_object are deleted.
|
|
Remarks:
|
|
Generally speaking you don't need to use MoveUserData().
|
|
Simply rely on ON_Object::operator=() or the copy constructor
|
|
to do the right thing.
|
|
Returns:
|
|
Number of user data items that were moved.
|
|
*/
|
|
unsigned int MoveUserData(
|
|
ON_Object& source_object,
|
|
ON_UUID source_userdata_item_id,
|
|
ON_Object::UserDataConflictResolution userdata_conflict_resolution,
|
|
bool bDeleteAllSourceItems
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Calls CopyUserData(source_object,ON_Object::UserDataConflictResolution::source_object).
|
|
Parameters:
|
|
source_object - [in]
|
|
*/
|
|
void CopyUserData(
|
|
const ON_Object& source_object
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Calls MoveUserData(source_object,ON_Object::UserDataConflictResolution::source_object,true).
|
|
Parameters:
|
|
source_object - [in]
|
|
*/
|
|
void MoveUserData(
|
|
ON_Object& source_object
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Uses the destination_manifest to update references to other components.
|
|
This is typically done when a component's references came from a "source"
|
|
context and are being updated to the "destination" context. For example,
|
|
inserting one model into another when index, id, and name conflicts
|
|
need to be resolved at the time of insertion.
|
|
Parameters:
|
|
source_manifest - [in]
|
|
A manifest of the source context with indices and ids
|
|
corresponding to the current component references.
|
|
If this manifest is not available, pass ON_ComponentManifest::Empty.
|
|
destination_manifest - [in]
|
|
A manifest of the destination context with indices and ids
|
|
corresponding to the desired component references.
|
|
If this manifest is not available, pass ON_ComponentManifest::Empty.
|
|
manifest_map - [in]
|
|
A map from the source (current) referenced component index/id values
|
|
to the destination (desired) component index/id values.
|
|
Returns:
|
|
True if successful.
|
|
False indicates a referenced component was not found in the manifest
|
|
and the reference was changed to a default value.
|
|
Example:
|
|
If this object is an ON_Layer, the line pattern and render material references
|
|
are updated.
|
|
If this object is an ON_DimStyle, the text style reference is updated.
|
|
If this object is an ON_3dmObjectAttributes, the layer,
|
|
material, line pattern, and group references are updated.
|
|
*/
|
|
virtual bool UpdateReferencedComponents(
|
|
const class ON_ComponentManifest& source_manifest,
|
|
const class ON_ComponentManifest& destination_manifest,
|
|
const class ON_ManifestMap& manifest_map
|
|
);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
// Component status interface
|
|
//
|
|
// Currently implemented on ON_SubD and ON_Brep
|
|
//
|
|
|
|
/*
|
|
Description:
|
|
Set all active level component states to ON_ComponentStatus::NoneSet.
|
|
Returns:
|
|
Number of components where a state setting changed.
|
|
*/
|
|
unsigned int ClearAllComponentStates() const;
|
|
|
|
/*
|
|
Description:
|
|
Clear the specified states on every component.
|
|
Parameters:
|
|
states_to_clear - [in]
|
|
States to clear.
|
|
Returns:
|
|
Number of components where a state setting changed.
|
|
*/
|
|
virtual
|
|
unsigned int ClearComponentStates(
|
|
ON_ComponentStatus states_to_clear
|
|
) const;
|
|
|
|
/*
|
|
Parameters:
|
|
states_filter - [in]
|
|
|
|
bAllEqualStates - [in]
|
|
If a state is set in states_filter, all active level components
|
|
with the same state set will be included in the
|
|
components_with_set_states[] array.
|
|
|
|
If bAllEqualStates is true, then ON_ComponentStatus::AllEqualStates()
|
|
is used to test for inclusion.
|
|
|
|
If bAllEqualStates is false, then ON_ComponentStatus::SomeEqualStates()
|
|
is used to test for inclusion.
|
|
|
|
components_with_set_states - [out]
|
|
Returns:
|
|
Number of returned components.
|
|
*/
|
|
virtual
|
|
unsigned int GetComponentsWithSetStates(
|
|
ON_ComponentStatus states_filter,
|
|
bool bAllEqualStates,
|
|
ON_SimpleArray< ON_COMPONENT_INDEX >& components
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Set states on an individual component.
|
|
Parameters:
|
|
component_index - [in]
|
|
The states will be set on this component.
|
|
states_to_set - [in]
|
|
If a state is set in the states_to_set parameter, the same
|
|
state will be set on the component.
|
|
Returns:
|
|
0: no state settings changed on the component.
|
|
1: some state setting changed on the component.
|
|
*/
|
|
virtual
|
|
unsigned int SetComponentStates(
|
|
ON_COMPONENT_INDEX component_index,
|
|
ON_ComponentStatus states_to_set
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Clear states on an individual component.
|
|
Parameters:
|
|
component_index - [in]
|
|
The states will be cleared on this component.
|
|
states_to_clear - [in]
|
|
If a state is set in the states_to_clear parameter, the same
|
|
state will be cleared on the component.
|
|
Returns:
|
|
0: no state settings changed on the component.
|
|
1: some state setting changed on the component.
|
|
*/
|
|
virtual
|
|
unsigned int ClearComponentStates(
|
|
ON_COMPONENT_INDEX component_index,
|
|
ON_ComponentStatus states_to_clear
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Copy status settings to an individual component.
|
|
Parameters:
|
|
component_index - [in]
|
|
The states will be copied to this component.
|
|
status_to_copy - [in]
|
|
Returns:
|
|
0: no state settings changed on the component.
|
|
1: some state setting changed on the component.
|
|
*/
|
|
virtual
|
|
unsigned int SetComponentStatus(
|
|
ON_COMPONENT_INDEX component_index,
|
|
ON_ComponentStatus status_to_copy
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Call whenever a component status setting is modified
|
|
by directly changing it on a component in a way that
|
|
will result in any saved information about the parent
|
|
object's aggregate component status becoming invalid.
|
|
|
|
Returns:
|
|
Aggregate information about the object's component states.
|
|
|
|
Remarks:
|
|
This function "should" return a const ON_AggregateComponentStatusEx,
|
|
but that requires breaking the C++ SDK.
|
|
*/
|
|
virtual
|
|
ON_AggregateComponentStatus AggregateComponentStatus() const;
|
|
|
|
/*
|
|
Description:
|
|
Call whenever a component status setting is modified
|
|
by directly changing it on a component in a way that
|
|
will result in any saved information about the parent
|
|
object's aggregate component status becoming invalid.
|
|
|
|
Remarks:
|
|
The implementations of this function are nearly instant.
|
|
and this function may be called as frequently as needed.
|
|
The next time AggregateComponentStatus()
|
|
is called the information used to return the value
|
|
will be updated.
|
|
*/
|
|
virtual
|
|
void MarkAggregateComponentStatusAsNotCurrent() const;
|
|
|
|
/*
|
|
Description:
|
|
Delete the portions of the object identified in ci_list[].
|
|
Parameters:
|
|
ci_list - [in]
|
|
List of components to delete.
|
|
ci_list_count - [in]
|
|
Number of elements in the ci_list[] array.
|
|
Returns:
|
|
True: successful
|
|
False: failure - no changes.
|
|
*/
|
|
virtual
|
|
bool DeleteComponents(
|
|
const ON_COMPONENT_INDEX* ci_list,
|
|
size_t ci_count
|
|
);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
// Expert interface
|
|
//
|
|
|
|
/*
|
|
Description:
|
|
Expert user function. If you are using openNURBS in its
|
|
default configuration to read and write 3dm archives,
|
|
you never need to call this function.
|
|
Many objects employ lazy creation of (runtime) caches
|
|
that save information to help speed geometric calculations.
|
|
This function will destroy all runtime information.
|
|
Parameters:
|
|
bDelete - [in] if true, any cached information is properly
|
|
deleted. If false, any cached information
|
|
is simply discarded. This is useful when
|
|
the cached information may be in alternate
|
|
memory pools that are managed in nonstandard
|
|
ways.
|
|
*/
|
|
virtual void DestroyRuntimeCache( bool bDelete = true );
|
|
|
|
private:
|
|
class ON_UserData* m_userdata_list;
|
|
class ON_UserData* TransferUserDataItem(
|
|
const class ON_UserData* source_ud_copy_this,
|
|
class ON_UserData* source_ud_move_this,
|
|
bool bPerformConflictCheck,
|
|
ON_Object::UserDataConflictResolution userdata_conflict_resolution
|
|
);
|
|
};
|
|
|
|
#endif
|
|
|