-
首页
-
C4D R23.110 C++ SDK
Undo System Manual
内容表
关于
The undo system of
Cinema 4D
allows to store changes of elements so that these changes can be undone and redone. An undo action can contain multiple changes to multiple elements - all these changes will be undone in a single step when the undo action is applied. These undo actions are stored in an undo buffer and are created in a
BaseDocument
.
-
The undo system will create copies of the changed elements. This means that
NodeData::Init()
,
NodeData::CopyTo()
etc. of plugin classes will be called multiple times.
-
No undos should be created in expressions or generators etc. Undos should be created when the user interacts with the scene.
-
使用
CallCommand()
will create its own undo step (since it behaves like pressing the associated button in the GUI).
-
To start and end an undo based on some interaction in a
GeDialog
the messages
BFM_INTERACTSTART
and
BFM_INTERACTEND
可以使用。
The Undo System
Creating Undos
Undo actions are added to the
BaseDocument
using these functions:
// This example creates a cube object and adds it to the document with an undo step.
BaseObject
*
const
cube =
BaseObject::Alloc
(
Ocube
);
if
(cube ==
nullptr
)
return
maxon::OutOfMemoryError(
MAXON_SOURCE_LOCATION
);
doc->
StartUndo
();
doc->
InsertObject
(cube,
nullptr
,
nullptr
);
doc->
AddUndo
(
UNDOTYPE::NEWOBJ
, cube);
doc->
EndUndo
();
The undo types are:
-
UNDOTYPE::CHANGE
: Any change to an object, including hierarchy modifications; modification in positioning (e.g. object has been moved from A to B), substructures etc. Needs to be called BEFORE the change.
-
UNDOTYPE::CHANGE_NOCHILDREN
: Same as
UNDOTYPE::CHANGE
, but without child modifications. Needs to be called BEFORE the change.
-
UNDOTYPE::CHANGE_SMALL
: Change to local data only (e.g. data container). No substructures (e.g. no tags on an object) and no children. Needs to be called BEFORE the change.
// This example changes the radius of the given sphere object.
doc->
AddUndo
(
UNDOTYPE::CHANGE_SMALL
, sphere);
sphere->
SetParameter
(
DescID
(
PRIM_SPHERE_RAD
), 200.0,
DESCFLAGS_SET::NONE
);
UNDOTYPE::CHANGE_SELECTION
: Change to point/poly/edge selection only. Needs to be called BEFORE the change.
// This example clears the point selection of the given PolygonObject.
PolygonObject
* polygonObject =
ToPoly
(polyObject);
doc->
AddUndo
(
UNDOTYPE::CHANGE_SELECTION
, polygonObject);
BaseSelect
* pSelect = polygonObject->
GetPointS
();
pSelect->
DeselectAll
();
UNDOTYPE::NEWOBJ
: New object/material/tag etc. was created. Needs to be called AFTER the insertion.
// This example adds a new object to the scene.
BaseObject
*
const
cube =
BaseObject::Alloc
(
Ocube
);
if
(cube)
{
doc->
InsertObject
(cube,
nullptr
,
nullptr
);
doc->
AddUndo
(
UNDOTYPE::NEWOBJ
, cube);
}
UNDOTYPE::DELETEOBJ
: Object/node/tag etc. to be deleted. Needs to be called BEFORE removal.
// This example removes the given BaseObject.
doc->
AddUndo
(
UNDOTYPE::DELETEOBJ
, torus);
torus->Remove();
BaseObject::Free
(torus);
UNDOTYPE::BITS
: Change to object bits, e.g. selection status. Needs to be called BEFORE the change.
// This example disables a video post effect.
doc->
AddUndo
(
UNDOTYPE::BITS
, videoPost);
videoPost->
SetBit
(
BIT_VPDISABLED
);
UNDOTYPE::HIERARCHY_PSR
: Change in hierarchical placement and PSR values. Needs to be called BEFORE the change.
// This example moves the object "child" under the object "parent".
doc->
AddUndo
(
UNDOTYPE::HIERARCHY_PSR
, child);
child->Remove();
doc->
InsertObject
(child, parent,
nullptr
);
Handle Undos
Undo actions can be applied using these functions:
// This example adds a new undo action.
// If something went wrong during the operation the last actions are undone.
Bool
success =
true
;
doc->
StartUndo
();
// do something
doc->
AddUndo
(
UNDOTYPE::CHANGE_SMALL
, sphereObject);
sphereObject->SetParameter(
DescID
(
PRIM_SPHERE_RAD
), 200.0,
DESCFLAGS_SET::NONE
);
// let's assume something went wrong, could not be done or the user aborted the action
success =
false
;
const
Bool
hasundo = doc->
GetUndoPtr
() !=
nullptr
;
// end the undo step and check for success
if
(doc->
EndUndo
())
{
// if something went wrong, undo all actions
if
(!success && hasundo)
doc->
DoUndo
();
}
User Interaction
If the user changes a parameter value in the Attribute Manager,
Cinema 4D
will create the proper undos.
NodeData
based plugins will receive a message to add custom operations to the automatically created undo action.
// This example catches MSG_DESCRIPTION_INITUNDO in a Message() function.
case
MSG_DESCRIPTION_INITUNDO
:
{
DescriptionInitUndo
*
const
uData =
static_cast<
DescriptionInitUndo
*
>
(data);
// check if data and BaseDocument can be accessed
if
(!uData || !uData->
doc
)
break
;
// add undo for dependent entities
BaseDocument
*
const
doc = uData->
doc
;
doc->
AddUndo
(
UNDOTYPE::CHANGE_SMALL
, node);
return
true
;
}
延伸阅读
BaseSelect * GetPointS(void)
void InsertObject(BaseObject *op, BaseObject *parent, BaseObject *pred, Bool checknames=false)
定义:
lib_description.h:327
@ CHANGE_SELECTION
Change to point/poly/edge selection only. (Needs to be called before the change.)
Bool AddUndo(UNDOTYPE type, void *data, Bool allowFromThread=false)
#define MSG_DESCRIPTION_INITUNDO
Allows elements to create undo actions for the following parameter changes in the attributes manager....
定义:
c4d_baselist.h:358
@ BITS
Change to object bits, e.g. selection status. (Needs to be called before the change....
@ CHANGE_SMALL
Change to local data only (e.g. data container). No substructures (e.g. no tags on an object) and no ...
Bool DoUndo(Bool multiple=false)
#define Ocube
Cube.
定义:
ge_prepass.h:1040
#define MAXON_SOURCE_LOCATION
定义:
memoryallocationbase.h:66
void SetBit(Int32 mask)
定义:
c4d_baselist.h:2200
@ PRIM_SPHERE_RAD
定义:
osphere.h:6
#define ToPoly(op)
Casts a BaseObject* to a PolygonObject*.
定义:
c4d_baseobject.h:2174
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
BaseList2D * GetUndoPtr()
定义:
c4d_basedocument.h:1065
@ DELETEOBJ
Object/node/tag etc. to be deleted. (Needs to be called before action.)
#define BIT_VPDISABLED
Videopost is disabled.
定义:
ge_prepass.h:873
定义:
c4d_baseobject.h:1597
Message struct for the MSG_DESCRIPTION_INITUNDO message.
定义:
c4d_baselist.h:752
static BaseObject * Alloc(Int32 type)
@ HIERARCHY_PSR
Change in hierarchical placement and PSR values. (Needs to be called before the change....
static void Free(BaseObject *&bl)
@ NEWOBJ
New object/material/tag etc. was created. (Needs to be called after action.)
maxon::Bool Bool
定义:
ge_sys_math.h:53
定义:
c4d_basedocument.h:490
BaseDocument * doc
The current document. Cinema 4D owns the pointed document.