Issue with GeDialog

On 19/04/2018 at 04:06, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R19 
Platform:   Windows  ;   
Language(s) :     C++  ;

I have created a GeDialog that control the focal length of n number of the cameras that is created by the command plugin. When I am using the plugin the value of the entered focal length is not changing with ctrl+z and cinema4d is getting crashed. I have tried to debug the code and found that after pressing the ctrl+z when I tried to change the focal length, then the camera object is getting corrupt. You have any Idea what I am doing wrong here.:cry:

On 20/04/2018 at 02:20, xxxxxxxx wrote:

Hi Amlendra

Even if we don't have any code which is hard for us to know exactly what you are doing.
Here some advice in order to get everything you need to make it work.

- When you change something in the document, you should always call StopAllThreads in order to be sure nothing touches the scene except your code.
If you want to have a more in-depth understanding of StopAllThreads, I invite you to read this topic.

- In C++ when you store a pointer to an object it's always recommended to use BaseLink instead of a pointer to the BaseObject itself.
Memory location of an object can change often in a life of an object, and it's probably what's making your code crash since CTRL+Z will destroy the object while your pointer is trying to access this memory location.
Then please read BaseLink Manual.

- Finally to properly support undo you have to make aware of c4d undo system which action has to be "undoable" for that please follow the Undo System Manual.

If you still get issues, please let me know and post a code in order to know exactly what happens.


On 20/04/2018 at 07:31, xxxxxxxx wrote:

Thank you for your valuable reply, There is any sample code that handles multiple objects using the BaseLink. My requirement only to change the position and focal length of the cameras through the GeDialog entry. **

I have also one query in below code, what is the instanceObject here.

// This example reads the object link of the given Instance Object.
    GeData data;
    // read "Reference Object" parameter
    if (instanceObject->GetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_GET_0))
      BaseList2D* linkedEntity = data.GetLink(doc);
      // check if a BaseList2D element is linked and if it is a BaseObject
      if (linkedEntity && linkedEntity->IsInstanceOf(Obase))
        BaseObject* linkedObject = static_cast<BaseObject*>(linkedEntity);
        if (linkedObject)
          GePrint("Linked Object: " + linkedObject->GetName());

Right now I am reading the user entry in Command(Int32 id, const BaseContainer& msg) function and modify the properties.**

On 23/04/2018 at 01:53, xxxxxxxx wrote:

Hi Amlendra,

the purpose of a BaseLink is to store only one link of a C4dAtom (in your case your camera).
So you have to make an array of baselink in order to handle all your cameras, for that, you have multiple solutions, from the BaseLink manual I gave you in my last post, there is BaseLinkArray
but you can also use a BaseArray, take a look at this example or even a HashMap to store your baselink, please take a look at this topic for a quick overview.

Regarding the code example you posted, Instance Object is actually an instance object within c4d, take a look here for more information.
The instance object has a parameter called "Reference Object" and this parameter is actually a BaseLink to another object.

I hope it makes the example more understandable if you still get any troubles, please let me know!


On 23/04/2018 at 10:21, xxxxxxxx wrote:

Thanks, Maxime for your reply. I have tried to create the base link for an object using the SetLink. If I am trying to access the object in other function through the base link, it returns nullptr. Have you any idea what I am doing wrong, See the below sample code,

AutoAlloc<BaseLink> link; //Declare in class 

//In execute function

// In another function, getting objTest nullptr

BaseObject\* objTest = static_cast<BaseObject\*>(link->GetLink(doc));
if (objTest)
GePrint("Could access the linked object.");

On 23/04/2018 at 12:07, xxxxxxxx wrote:

This is the purpose of AutoAlloc, it will automatically delete the pointed object (the BaseLink) at the end of the scope. This topic can bring you some valuable information.

So you need to pass the ownership of the AutoAlloc. Use link.Release() before the end of your first function.
But again read the previous topic for a better understanding.

Anyway, don't feel demotivated and keep asking us! You will success! :D


On 25/04/2018 at 09:37, xxxxxxxx wrote:

Thanks, Maxime for your valuable suggestion, I have implemented the base link array it is working but still I am testing the crashing the issue It might be resolved. I have found that after the implementation of undo functionality all objects disappear after pressing the ctrl+z but GeDialog still present. So there is another way to change the status of GeDialog entry and close automatically after disappearing the plugin's object with ctrl+z.

On 26/04/2018 at 03:51, xxxxxxxx wrote:

Hi Amlendra,

Do you still experience the crash? If yes, please share your code. Without knowing in which context, you are running is very difficult for us to be able to help you.
About the undo I'm not sure to understand if the fact that all objects disappear is something you want or not. Please confirm.
If it's not the expected behavior please share your code.

Since I'm not really sure about what you want to achieve, I prefer to ask and give you some clues, but of course please confirm and tell us what is the expected behavior, and what you currently have (with a piece of code), in order to solve your issues as soon as possible ;)

And finally your last question regarding closing when CTRL+Z is pressed is a bit weird in a c4d workflow/design decision and I don't see any other GUI in C4D which quit when you undo an action in the scene.
With that said, if you really want to close your GeDialog no matter the active window.
You have to register a SceneHook and react to KeyboardInput(). Then send a CoreMessage to your GeDialog, finally catch this message in your GeDialog and close it using Close().
In the same time make sure to not only test for CTRL+Z even if it can look weird, maybe some users have replaced undo shortcut by something else.


On 26/04/2018 at 04:32, xxxxxxxx wrote:

Right now not facing crashing issues also I am going to work as per your suggestion thank you Maxime for your valuable support.