C4DAtom Manual
C4DAtom is the base class for many entities in the classic Cinema 4D API. Along with GeListNode and BaseList2D it implements the basic functionality of most classic entities. C4DAtomGoal is the extension of the C4DAtom class that allows to create safe references to an C4DAtom entity with a BaseLink .
A pointer to a C4DAtom is typically provided by resolving a BaseLink to an entity. See BaseLink Manual .
// read the "Reference Object" parameter if (!instanceObject->GetParameter( DescID { INSTANCEOBJECT_LINK }, data, DESCFLAGS_GET::NONE )) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION );
C4DAtom pointers to any kind of entity are often stored in AtomArray objects. See AtomArray Manual .
C4DAtom instances cannot be created directly. Only instances of C4DAtom based classes can be created.
C4DAtom gives access to information about the type and class of the specific entity:
// check the classification const Int32 classification = atom-> GetClassification (); if (classification == Obase ) { const BaseObject * const baseObject = static_cast< BaseObject * > (atom); const 向量 position = baseObject-> GetMg (). off ; ApplicationOutput ( "Position: " + String::VectorToString (position));
// check if it is an instance of a given class if (atom-> IsInstanceOf ( Opoint )) { PointObject * const pointObject = static_cast< PointObject * > (atom); const Int32 pointCount = pointObject-> GetPointCount (); ApplicationOutput ( "Point Count: " + String::IntToString (pointCount));
// check the specific type if (atom-> GetType () == Offd ) { // If this point object is a FFD object, change its grid size. atom-> SetParameter ( FFDOBJECT_SIZE , 向量 (500, 500, 500), DESCFLAGS_SET::USERINTERACTION ); EventAdd (); } } }
C4DAtom based entities are easily copied and cloned:
The copy flags are:
The AliasTrans argument of these functions is optional. If an AliasTrans instance is provided it is used to update BaseLink parameters of the copied entities. If a BaseLink references an element that is also copied the BaseLink is changed to reference the copy of the originally referenced entity.
// This example clones the objects defined in the given AtomArray. // The clones are created using an AliasTrans object. // So if an object is referenced by another object in the object list // this reference is redirected to the clone of the original object. AutoAlloc<AliasTrans> alias; // check if the AliasTrans was allocated // and can be initiated if (alias == nullptr || !alias-> Init (doc)) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); doc-> GetActiveObjects (objectSelection, GETACTIVEOBJECTFLAGS::NONE ); const Int32 selectionCount = objectSelection->GetCount(); if (selectionCount == 0) return maxon::IllegalArgumentError( MAXON_SOURCE_LOCATION ); for ( Int32 i = 0; i < selectionCount; ++i) { BaseObject * const object = static_cast< BaseObject * > (objectSelection->GetIndex(i)); if ( object == nullptr ) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); BaseObject * const clone = static_cast< BaseObject * > ( object ->GetClone( COPYFLAGS::NONE , alias)); if (clone == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); const String objectName = object ->GetName(); clone-> SetName (objectName + " clone" ); doc-> InsertObject (clone, nullptr , nullptr ); }// this fixes links to elements that are not part of the given object selection alias-> Translate ( true );
A C4DAtom based element can be read from and written to a HyperFile .
If the entity is handled inside another read/write function ( NodeData::Read() and NodeData::Write() ) these functions must be used:
Parameter descriptions and IDs are managed with these functions:
// get the Description of the given object if (!object-> GetDescription (description, DESCFLAGS_DESC::NONE )) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); void * handle = description-> BrowseInit (); const BaseContainer * bc = nullptr ; DescID id, gid;
// loop through all elements of the description while (description-> GetNext (handle, &bc, id , gid)) { ApplicationOutput ( "Parameter Name: " + bc-> GetString ( DESC_NAME )); } description-> BrowseFree (handle);
The value of parameters should be changed with C4DAtom::GetParameter() and C4DAtom::SetParameter() . In this way one can be sure, the parameters are set correctly even if the entity does not store the data in its BaseContainer .
// check if the active object is a "Cube" object if (cube == nullptr || !cube-> IsInstanceOf ( Ocube )) return maxon::IllegalArgumentError( MAXON_SOURCE_LOCATION ); GeData data; const DescID cubeLenID { PRIM_CUBE_LEN };
// read the "Size" parameter if (!cube-> GetParameter (cubeLenID, data, DESCFLAGS_GET::NONE )) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); 向量 size = data. GetVector (); size = size + 向量 { 100 }; cube-> SetParameter (cubeLenID, size, DESCFLAGS_SET::NONE );
The dirty status of an entity is a number that is increased every time the entity is changed.
The dirty flags are:
// Get the current dirty checksums UInt32 dataDirtyStatus = baseObject-> GetDirty ( DIRTYFLAGS::DATA ); UInt32 matrixDirtyStatus = baseObject-> GetDirty ( DIRTYFLAGS::MATRIX ); ApplicationOutput ( "Data Status: " + String::UIntToString (dataDirtyStatus)); ApplicationOutput ( "Martix Status: " + String::UIntToString (matrixDirtyStatus));
// edit the object's data baseObject-> SetName ( "New Name" _s);
// Check the dirty checksums dataDirtyStatus = baseObject-> GetDirty ( DIRTYFLAGS::DATA ); matrixDirtyStatus = baseObject-> GetDirty ( DIRTYFLAGS::MATRIX ); ApplicationOutput ( "Data Status: " + String::UIntToString (dataDirtyStatus)); ApplicationOutput ( "Martix Status: " + String::UIntToString (matrixDirtyStatus));
Hierarchy dirty (HDirty) states are used to check if the given entity or some child elements in the hierarchy were changed. Typically used with a BaseDocument 或 GeListHead .
The hierarchy dirty flags are:
// edit a material BaseMaterial * const mat = doc-> GetActiveMaterial ();
// check if the active material is a Cinema 4D standard material if (mat && mat-> IsInstanceOf ( Mmaterial )) { mat-> SetParameter ( MATERIAL_COLOR_COLOR , 向量 (255, 0, 0), DESCFLAGS_SET::NONE ); }
// check the dirty checksums materialsDirtyState = doc-> GetHDirty ( HDIRTYFLAGS::MATERIAL ); objectsDirtyState = doc-> GetHDirty ( HDIRTYFLAGS::OBJECT ); ApplicationOutput ( "Materials Status: " + String::UIntToString (materialsDirtyState)); ApplicationOutput ( "Objects Status: " + String::UIntToString (objectsDirtyState));
Entities in Cinema 4D often communicate by sending messages to each other. Such a message can be used to inform the element about some event or to retrieve data from the element. A message can be sent to an entity with these functions:
// check if the active object is a point object if (activeObject == nullptr || !activeObject-> IsInstanceOf ( Opoint )) return maxon::IllegalArgumentError( MAXON_SOURCE_LOCATION ); PointObject * const pointObject = static_cast< PointObject * > (activeObject); 向量 * const points = pointObject-> GetPointW (); if (points == nullptr ) return maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); const Int32 pointCount = pointObject-> GetPointCount (); for ( Int32 i = 0; i < pointCount; ++i) points[i] = points[i] + 向量 (0, 100, 0); pointObject-> 消息 ( MSG_UPDATE );
另请参阅 NodeData::Message() Manual .