I am trying to figure out if it is possible to retrieve the position of an object while you are dragging it around with the mouse. This would mean to pass the message with the instant position to an already running plugin to update dinamically the GUI.
For the moment I thought about getting the position with a button after the mouse movement but is very annoying for the final user.
I looked for posts regarding similar topics and I thought it could be a case for threadding or using a python tag, but I am pretty much lost here.
Any help would be appreciated.
thank you for clarifying your question. There are unfortunately some things still unclear to me, so let me start with a set of assumptions of mine:
So, there are basically two major ways you can do this. You can either A. push the information into the other plugin from the action of the objects being moved. This option does necessarily need a second plugin which is pushing the information into your other plugin. Or you can B. grab the information from the objects when they have been moved from within the other plugin. This option does not need necessarily a second plugin. Which might sound like semantics is an important distinction, since you cannot move data without restrictions in the message system of Cinema 4D.
When the the other plugin is some GeDialog, option B lends itself best via core messages and EVMSG_CHANGE, see end of posting for an example. However, when the other plugin is some kind of classic API node, e.g., an object itself, you will have to push the information into that node, e.g., with MSG_BASECONTAINER. But depending on how you structure all that, you might need a third plugin in between to handle the transfer. Your question is here unfortunately so broad that I cannot give you anything more concrete.
I hope this helps and cheers,
"""Example for tracking object matrices in a GeDialog.
This can be run as a script manager script and will create a dialog which
tracks the global transform matrices of the objects that have been selected
when the dialog was created.
As discussed in:
class ObjectTrackerDialog (c4d.gui.GeDialog):
"""Example dialog that tracks the transforms of a set of objects.
ID_GADGETS_START = 1000
ID_GADGET_GROUP = 0
ID_GADGET_LABEL = 1
ID_GADGET_TEXT = 2
GADGETS_STRIDE = 10
def __init__(self, objects: list[c4d.BaseObject]) -> None:
self._objects = objects
def CoreMessage(self, mid: int, msg: c4d.BaseContainer) -> bool:
"""Receives core messages.
We react here to EVMSG_CHANGE to update all our object matrices.
EVMSG_CHANGE is the message for EventAdd(), i.e., is being fired
ALOT. To make this less throttling, we could also use
GeDialog.SetTimer and GeDialog.Timer to update the matrices in a
fixed interval. What is better depends on how time-consuming you
would consider your updates to be. But the timer approach will also
consume process time when nothing changed. So, the best approach
would be to mix the two. I.e., only react to EVMSG_CHANGE when a
certain time span X has passed since the last time you did react to
if mid == c4d.EVMSG_CHANGE:
def CreateLayout(self) -> bool:
"""Creates a static text and a text box for each tacked object.
for i, item in enumerate(self._objects):
gid = self.ID_GADGETS_START + i * self.GADGETS_STRIDE
name = item.GetName()
self.GroupBegin(gid + self.ID_GADGET_GROUP,
c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=2)
self.AddStaticText(gid + self.ID_GADGET_LABEL,
c4d.BFH_LEFT | c4d.BFV_SCALEFIT, name=name)
self.AddEditText(gid + self.ID_GADGET_TEXT,
c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
def InitValues(self) -> bool:
"""Initializes the dialog values.
def UpdateValues(self) -> bool:
"""Updates the dialog values.
for i, item in enumerate(self._objects):
gid = gid = self.ID_GADGETS_START + i * self.GADGETS_STRIDE
self.SetString(gid + self.ID_GADGET_TEXT, item.GetMg())
"""Creates an instance of the ObjectTrackerDialog.
items = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)
if not isinstance(items, list) or len(items) < 1:
raise RuntimeError("Please select at least one object.")
# Please do not do this in a production environment. This is just a hack
# to keep an async dialog alive from the script manager. Which will lead
# to problems when used in production.
dialog = ObjectTrackerDialog(items)
if __name__ == '__main__':
thank you for reaching out to us. We will answer your question more thoroughly, but to be able to do so, we will need more information. Your topic is missing:
Please read our Forum Guidelines for details on the support process.
Hello @ferdinand, thanks for the quick reply and sorry for the lack of information.
I cannot add tags to the original post but I am using windows as the operating system.
An example of the GUI used by the already running plugin could be somewhat similar to this (I'm working on a simpler GUI but the back-end will be the same):
As you can see, when I press "add model" I get the global coordinates of the selected cube and printed in the GUI. However I would like those values (Global x, Global y and Global Z) to be updated when I drag the cube around without the need of refreshing it manually.
I hope this clarifies the topic.
Hello @ferdinand ,
this example was perfect for me, thank you very much!