内容表
关于
类
GeListNode
is based on
C4DAtom
and is a base class for many entities of the classic
Cinema 4D
API. It mostly provides the functionality to organize elements in linked lists and trees.
GeListNode
objects are an instance of
Tgelistnode
.
Access
NodeData::Get()
is rarely needed, as a pointer to a
GeListNode
is typically handed over to virtual functions of
NodeData
and derived classes:
// This example shows a primitive implementation of Message().
virtual
Bool
Message(
GeListNode
* node,
Int32
type,
void
* data)
{
switch
(type)
{
case
(
MSG_UPDATE
):
{
break
;
}
// more cases
GeListNode
is also used in the context of object hierarchies with
GeListHead
元素。
Allocation/Deallocation
It is possible to create a
GeListNode
instance of a
RegisterNodePlugin()
registered node with
-
注意
-
These functions are typically not used with third party plugins. They are only useful to handle custom
NodeData
plugins.
// This example allocates a node of the type ID_PYTHONSCRIPT.
// This node can be used to execute a Python script.
String
python;
python +=
"print(\"this is python\")"
;
BaseList2D
* op =
static_cast<
BaseList2D
*
>
(
AllocListNode
(
ID_PYTHONSCRIPT
));
if
(op ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
BaseContainer
& data = op->
GetDataInstanceRef
();
data.
SetString
(
PYTHONSCRIPT_TEXT
, python);
op->
消息
(
MSG_SCRIPT_EXECUTE
,
nullptr
);
blDelete
(op);
Lists and Trees
Navigation in Lists and Trees
GeListNode
based elements can be organized in lists and trees. A
GeListNode
based entity can reference the accompanying elements in that hierarchy. If no element is referenced,
nullptr
is returned.
-
注意
-
Derived classes often provide overwritten versions of these functions for convenience.
The typical
Cinema 4D
workflow would be:
// This example iterates over a linked list.
// In this case it is the list of all tags of the given BaseObject.
// loop through all tags
for
(
BaseTag
* tag = object->
GetFirstTag
(); tag; tag = tag->
GetNext
())
{
ApplicationOutput
(
"Tag: "
+ tag->
GetName
());
}
and
// This function walks recursively over the tree of nodes.
static
void
WalkTreeRec(
GeListNode
* node)
{
while
(node !=
nullptr
)
{
// check if the current node is a BaseList2D object
if
(node->
IsInstanceOf
(
Tbaselist2d
))
{
const
BaseList2D
*
const
baseList2d =
static_cast<
BaseList2D
*
>
(node);
ApplicationOutput
(
"Name: "
+ baseList2d->
GetName
());
}
// check child objects
WalkTreeRec(node->
GetDown
());
// check next objects in the list
node = node->
GetNext
();
}
}
-
注意
-
Avoid unnecessary recursion to prevent a stack overflow.
Edit Lists and Trees
A given
GeListNode
can be inserted into a list or tree or it can be removed from that list or tree:
-
注意
-
若
GeListNode
is supposed to be deleted it must be removed from its list before.
-
At any given time a
GeListNode
can only be inserted into one single list or tree. Before inserting a node into a new list, make sure to remove it from the old one.
// This example switches the position of the given object
// and its parent object in the object tree.
BaseObject
*
const
parentObject = selectedObject->
GetUp
();
if
(parentObject ==
nullptr
)
return
maxon::IllegalArgumentError(
MAXON_SOURCE_LOCATION
);
// the parent object may or may not have a parent itself
BaseObject
*
const
parentParent = parentObject->
GetUp
();
// remove both objects from the tree
selectedObject->
移除
();
parentObject->
移除
();
// insert the selected object
doc->
InsertObject
(selectedObject, parentParent,
nullptr
);
// insert the parent object as a child
parentObject->
InsertUnder
(selectedObject);
Heads and Branches
A
GeListHead
element is used as the root of a list or tree:
见
GeListHead Manual
.
A given
GeListNode
can host multiple internal lists and trees by storing multiple
GeListHead
objects, called branches. For example the list of tags is a branch of
BaseObject
. These branches can be accessed with this function:
Valid flags are:
The used
BranchInfo
struct has the following members:
The branch flags are:
// This example loops through all branches of a given BaseDocument.
// If possible the name of the first branch child object is printed.
BranchInfo
info[20];
// 20 is just an arbitrary number, that should be enough to catch all branches
const
Int32
branchCount = doc->
GetBranchInfo
(info, 20,
GETBRANCHINFO::NONE
);
for
(
Int32
i = 0; i < branchCount; ++i)
{
ApplicationOutput
(
"Branch "
+
String::IntToString
(i));
const
String
branchName = info[i].
name
;
ApplicationOutput
(
" - Name: "
+ branchName);
GeListHead
*
const
branchHead = info[i].
head
;
if
(branchHead !=
nullptr
)
{
GeListNode
*
const
child = branchHead->
GetFirst
();
// check if the child is a BaseList2D object
if
(child && child->
IsInstanceOf
(
Tbaselist2d
))
{
BaseList2D
*
const
child2D =
static_cast<
BaseList2D
*
>
(child);
ApplicationOutput
(
" - First Child Element: "
+ child2D->
GetName
());
}
}
}
NodeData
The base class for most classic plugins is
NodeData
.
NodeData
based plugin classes build the "core" of any plugin based entity of the classic
Cinema 4D
API. This "core" class can be obtained with:
另请参阅
基本类和插件类
.
// This example checks if the given object has the type of a custom plugin class.
// If so, GetNodeData<T>() can be used to get the pointer to the plugin class.
// check if the selected object is an "ExampleGenerator"
if
(selectedObject->GetType() == g_exampleGeneratorID)
{
ExampleGenerator*
const
exampleGenerator = selectedObject->GetNodeData<ExampleGenerator>();
if
(exampleGenerator)
{
exampleGenerator->MemberFunction();
}
}
-
警告
-
It is only possible to cast the retrieved object into a specific class in the module where this class is defined.
-
Some components of
Cinema 4D
are not implemented as a plugin so there is no
NodeData
instance to access.
Document
GeListNode
based objects can also be part of a
BaseDocument
:
-
警告
-
Always check the returned document pointer for
nullptr
, as the element might not be part of any document.
// This example from a NodeData::Message() function uses
// the BaseDocument of the given GeListNode.
// get the document that hosts the given node
const
BaseDocument
* doc = node->
GetDocument
();
if
(doc)
{
GeData
geData;
// read the BaseLink parameter from the node
if
(node->
GetParameter
(EXAMPLE_GENERATOR_LINK, geData,
DESCFLAGS_GET::NONE
))
{
// resolve the link using the received document
C4DAtom
*
const
atom = geData.
GetLinkAtom
(doc,
Tbaselist2d
);
if
(atom)
{
BaseList2D
*
const
baseList2D =
static_cast<
BaseList2D
*
>
(atom);
ApplicationOutput
(baseList2D->
GetName
());
}
}
}
Infos
Additional information can be accessed:
// This example casts the given BaseObject into SplineObject
// if it is a spline or if it is a spline generator.
SplineObject
* spline =
nullptr
;
// check if the object is a "Spline" object
if
(object->
IsInstanceOf
(
Ospline
))
spline =
ToSpline
(
object
);
// check if the object is a spline generator
else
if
(object->
GetInfo
() &
OBJECT_ISSPLINE
)
spline =
object
->
GetRealSpline
();
if
(spline !=
nullptr
)
ApplicationOutput
(
"Spline Object: "
+ spline->
GetName
());
NBits
Various settings of an element can be configured by changing a corresponding bit. A list of available bits is defined in
NBIT
.
The change operations are:
// This example toggles the NBIT_EHIDE of the active object.
BaseObject
*
const
object
= doc->
GetActiveObject
();
if
(
object
==
nullptr
)
return
maxon::IllegalArgumentError(
MAXON_SOURCE_LOCATION
);
object
->ChangeNBit(
NBIT::EHIDE
,
NBITCONTROL::TOGGLE
);
延伸阅读
BaseObject * GetUp(void)
定义:
c4d_baseobject.h:268
String name
The human readable name of the branch. (Currently not used.)
定义:
c4d_baselist.h:1155
Int32 GetBranchInfo(BranchInfo *info, Int32 max, GETBRANCHINFO flags)
定义:
c4d_baselist.h:1930
C4DAtomGoal * GetLinkAtom(const BaseDocument *doc, Int32 instanceof=0) const
void InsertObject(BaseObject *op, BaseObject *parent, BaseObject *pred, Bool checknames=false)
#define Ospline
Spline - SplineObject.
定义:
ge_prepass.h:976
@ EHIDE
Hide in viewport.
GeListHead * head
Either a GeListNode or a GeListHead for the branch, depending on flags.
定义:
c4d_baselist.h:1154
void SetString(Int32 id, const maxon::String &s)
定义:
c4d_basecontainer.h:569
#define ToSpline(op)
Casts a BaseObject* to a SplineObject*.
定义:
c4d_baseobject.h:2177
GeListNode * GetFirst()
定义:
c4d_baselist.h:2037
GeListNode * AllocListNode(Int32 id)
#define blDelete(v)
Destructs objects derived from BaseList2D. It is basically the same as BaseList2D::Free().
定义:
c4d_baselist.h:2803
#define MAXON_SOURCE_LOCATION
定义:
memoryallocationbase.h:66
#define ID_PYTHONSCRIPT
定义:
ge_prepass.h:4799
Represents a C4DAtom that resides in a 4D list.
定义:
c4d_baselist.h:1767
#define MSG_UPDATE
Must be sent if the bounding box has to be recalculated. (Otherwise use MSG_CHANGE....
定义:
c4d_baselist.h:340
static String IntToString(Int32 v)
定义:
c4d_string.h:495
GeListNode * GetDown()
定义:
c4d_baselist.h:1794
const BaseContainer & GetDataInstanceRef() const
定义:
c4d_baselist.h:2299
#define MSG_SCRIPT_EXECUTE
Execute the script. (No arguments.)
定义:
ge_prepass.h:4849
SplineObject * GetRealSpline(void)
#define Tbaselist2d
2D list.
定义:
ge_prepass.h:938
maxon::Int32 Int32
定义:
ge_sys_math.h:58
BaseDocument * GetDocument()
定义:
c4d_baselist.h:1915
#define ApplicationOutput(formatString,...)
定义:
debugdiagnostics.h:207
Bool Message(Int32 type, void *data=nullptr)
定义:
c4d_baselist.h:1394
void Remove()
定义:
c4d_baselist.h:1854
GeListNode * GetNext()
定义:
c4d_baselist.h:1782
Represents a spline object.
定义:
c4d_baseobject.h:2009
#define PYTHONSCRIPT_TEXT
String Script.
定义:
ge_prepass.h:4860
maxon::Bool Bool
定义:
ge_sys_math.h:53
BaseTag * GetNext(void)
定义:
c4d_basetag.h:78
BaseObject * GetActiveObject(void)
Bool IsInstanceOf(Int32 id) const
定义:
c4d_baselist.h:1373
String GetName() const
定义:
c4d_baselist.h:2318
#define OBJECT_ISSPLINE
Spline object.
定义:
ge_prepass.h:898
BaseTag * GetFirstTag(void)
void InsertUnder(GeListNode *bl)
定义:
c4d_baselist.h:1835
Bool GetParameter(const DescID &id, GeData &t_data, DESCFLAGS_GET flags)
定义:
c4d_basedocument.h:490
定义:
c4d_basecontainer.h:46