Not sure.. EventAdd() maybe..?



  • On 02/05/2013 at 19:45, xxxxxxxx wrote:

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

    ---------
    Hi Folks,

    I'm trying to retrieve the position of an object before and after a move. However, using both object->GetRelPos() or going through the DescLevel attributes gives me the same position values (shown when I GePrint them..). My process is as follows:

    1)Get Objects first position
    2)Object is moved
    3)object->Message(MSG_UPDATE) (have tried different messages here)
    4)EventAdd() (have tried different flags here..)
    5)Get object's new position

    But the initial and new object positions are being returned as the same values? Some code:

      
    GeData gedata;   
    MainObject->GetParameter(ID_TAB_OBJECT_LINKED,gedata,DESCFLAGS_GET_0); // BaseObject with a link field...   
    LinkedObject = (BaseObject* )gedata.GetLink(doc); // BaseObject taken from the MainObject's link field...   
    GeData gedataNew;   
      
    DescID posXid = DescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR,0), DescLevel(VECTOR_X, DTYPE_REAL,0));   
    DescID posYid = DescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR,0), DescLevel(VECTOR_Y, DTYPE_REAL,0));   
    DescID posZid = DescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR,0), DescLevel(VECTOR_Z, DTYPE_REAL,0));   
      
    LinkedObject->GetParameter(posXid, gedataNew, DESCFLAGS_GET_0);   
    Real X = gedataNew.GetReal();   
    LinkedObject->GetParameter(posYid, gedataNew, DESCFLAGS_GET_0);   
    Real Y = gedataNew.GetReal();   
    LinkedObject->GetParameter(posZid, gedataNew, DESCFLAGS_GET_0);   
    Real Z = gedataNew.GetReal();   
    Vector T_Pos_Editor = Vector(X,Y,Z);//LinkedObject->GetAbsPos();   
      
    // Prints of the object's initial position done here...   
      
    if(Active == TRUE)   
    {   
         ObjectSelected = TRUE; // irrelevant to the object move   
         Active = FALSE;   
    }   
      
    // LinkedObject is moved below by (what I thought was..) updating the MainObject's Execution function                       
    Pattribute.ExecutionRefresh = 1; // Bool flag to allow MainObject's execution to move LinkedObject   
    MainObject->Message(MSG_UPDATE);   
    LinkedObject->Message(MSG_UPDATE);   
    EventAdd(EVENT_ANIMATE); // different flags called here...   
      
    Vector Th = LinkedObject->GetRelPos(); //instead of the DescLevel way, I tried GetRelPos() here instead...   
    X = Th.x;   
    Y = Th.y;   
    Z = Th.z;   
      
    // Second prints are done here, but they return the same values as the first prints...!?   
    

    I've tried combinations of all sorts of things. And while the object is moved, the GePrint values are always the same (both prints the initial values)? What else can I try here?

    WP.

    P.S. these spaced line prints are irritating - they don't show in Notepad or Notepad++, or in the message form text edit field...



  • On 03/05/2013 at 02:21, xxxxxxxx wrote:

    1. I do not see any GePrint in your code at all. I think it is crucial to actually 
    include those lines.

    2. You do not explain how the objects are being moved programmatically or
    by the user.

    3. You are writing about GetRelPos() - i personally would prefer to use just the
    local or goal matrix of your object in that context.



  • On 03/05/2013 at 03:05, xxxxxxxx wrote:

    Hi littledevil,

    I didn't include the GePrint's because the double line spacing was making the post very long. Here's what the two print's look like for the above code trials:

      
    // INITIAL POSITION PRINTS:   
    GePrint("Pre-Positions:");   
    String temp = FormatNumber(X,FORMAT_REAL,NULL,NULL);   
    GePrint("X = " + temp);   
    temp = FormatNumber(Y,FORMAT_REAL,NULL,NULL);   
    GePrint("Y = " + temp);   
    temp = FormatNumber(Z,FORMAT_REAL,NULL,NULL);   
    GePrint("Z = " + temp);   
      
    // MAINOBJECTS EXECUTION RUN AGAIN   
      
    //POST/REFRESHED POSITION PRINTS   
    GePrint("Post-Positions:");   
    temp = FormatNumber(Th.x,FORMAT_REAL,NULL,NULL);   
    GePrint("X = " + temp);   
    temp = FormatNumber(Th.y,FORMAT_REAL,NULL,NULL);   
    GePrint("Y = " + temp);   
    temp = FormatNumber(Th.z,FORMAT_REAL,NULL,NULL);   
    GePrint("Z = " + temp);   
    GePrint(" ");   
    

    It's a bit awkward to explain it all without making it very long! The objects are moved by data stored in a vector array. When Cinema draws a new frame, the MainObject's Execution is run with the "if(Pattribute.ExecutionRefresh == 1)" this bool is then made false so that the execution function only runs that part of the code once. The Boolean is made TRUE on a new frame for example. This allows the user to then move the object freely without the execution running several times and returning the LinkedObject's postion over and over via the vector data. That is, the vector data is used only once per frame. Say the user can then move the object 100cm in the "X" axis. They can then hit the button and what 'should' happen is the position of the object is recorded (initial position), and then the Boolean is made TRUE so that the execution can run it's vector code again for that frame, moving the object back to where the vector data says it should be, and the position is taken again so that I should be left with two object positions that I can compare. But it's always returning the same values despite the object being moved in the viewport.

    As for the GetRelPos() - I was just using that to try it. I've tried it a few ways and that just happened to be the last way I could think of =)

    Hope that clarifies things a bit..!

    WP.



  • On 03/05/2013 at 07:44, xxxxxxxx wrote:

    If your before and after move values are coming out the the same. It's typically an indication that your "prev_position" variable is in the wrong place within your code.  And it's being overwritten (updated) when you don't want it to be updated.

    The simplest way to make sure your variables keep their values and do not get changed until you want them to change, is to use them in global variables in the prepass section (also called forward declaration) of your plugin.
    It's better coding practice to use things like structs and classes for this kind of thing. But because C4D plugins don't talk to each other by default. You can cheat and get away with using globals without running into problems most of the time.

    -ScottA



  • On 03/05/2013 at 15:45, xxxxxxxx wrote:

    Howdy,

    What kind of plugin is it, CommandData, TagData, etc.?

    Adios,
    Cactus Dan



  • On 03/05/2013 at 18:01, xxxxxxxx wrote:

    Hmmmm,

    Scott - I've just tried some class level variables but that hasn't seemed to of made a difference. Using a separate struct didn't seem to help either.The strange thing is both prints are returning the first value. So the second print isn't returning the new position after the supposed move update.

    Dan - it's an ObjectData plugin, but the button command is being run from a GeDialog that's buried in the object. So the dialog isn't a separate plugin or have a separate ID.

    WP.



  • On 03/05/2013 at 18:13, xxxxxxxx wrote:

    Howdy,

    One thing that I've done with some plugins, just to see what the program flow is, is to add a GePrint statement at the beginning of each function, something like this:

    GePrint("MyTagData::Message()");
    

    It really fills up the console but at least you can see what functions get called after each input event.

    Adios,
    Cactus Dan



  • On 03/05/2013 at 18:46, xxxxxxxx wrote:

    Hi Dan,

    Interesting. I use to do this with some things myself but seemingly it didn't occur to me to do it here (how silly!). I just put a print into the execution function and noticed that it is being run after the button call which would explain why both position values are the same. So the EventAdd() and Message()'s that I'm sending aren't being actioned until after the button's "break;" is called (if at all).

    So how would one go about executing the object's Execute() function from within the button command if EventAdd() and Message()'s don't do it?

    WP.



  • On 03/05/2013 at 19:04, xxxxxxxx wrote:

    Howdy,

    Those kind of things are difficult to follow without a print statement in each function and also printing all messages and core messages being sent.

    I use these functions to print all messages:

    // debug check for messages
    Bool ListReceivedCoreMessages(String str, LONG id, const BaseContainer &bc)
    {
    	switch(id)
    	{
    		case EVMSG_CHANGE:
    			GePrint(str+"::CoreMessage = EVMSG_CHANGE");
    			break;
    		case EVMSG_DOCUMENTRECALCULATED:
    			GePrint(str+"::CoreMessage = EVMSG_DOCUMENTRECALCULATED");
    			break;
    		case EVMSG_TOOLCHANGED:
    			GePrint(str+"::CoreMessage = EVMSG_TOOLCHANGED");
    			break;
    		case EVMSG_AUTKEYMODECHANGED:
    			GePrint(str+"::CoreMessage = EVMSG_AUTKEYMODECHANGED");
    			break;
    		case EVMSG_UPDATEHIGHLIGHT:
    			GePrint(str+"::CoreMessage = EVMSG_UPDATEHIGHLIGHT");
    			break;
    		case EVMSG_GRAPHVIEWCHANGED:
    			GePrint(str+"::CoreMessage = EVMSG_GRAPHVIEWCHANGED");
    			break;
    		case EVMSG_TIMELINESELECTION:
    			GePrint(str+"::CoreMessage = EVMSG_TIMELINESELECTION");
    			break;
    		case EVMSG_BROWSERCHANGE:
    			GePrint(str+"::CoreMessage = EVMSG_BROWSERCHANGE");
    			break;
    		case EVMSG_MATERIALSELECTION:
    			GePrint(str+"::CoreMessage = EVMSG_MATERIALSELECTION");
    			break;
    		case EVMSG_FCURVECHANGE:
    			GePrint(str+"::CoreMessage = EVMSG_FCURVECHANGE");
    			break;
    		case EVMSG_RAYTRACER_FINISHED:
    			GePrint(str+"::CoreMessage = EVMSG_RAYTRACER_FINISHED");
    			break;
    		//case EVMSG_FRAME_SCENE:
    			//GePrint(str+"::CoreMessage = EVMSG_FRAME_SCENE");
    			//break;
    		case EVMSG_MATERIALPREVIEW:
    			GePrint(str+"::CoreMessage = EVMSG_MATERIALPREVIEW");
    			break;
    		case EVMSG_ACTIVEVIEWCHANGED:
    			GePrint(str+"::CoreMessage = EVMSG_ACTIVEVIEWCHANGED");
    			break;
    		case EVMSG_ASYNCEDITORMOVE:
    			GePrint(str+"::CoreMessage = EVMSG_ASYNCEDITORMOVE");
    			break;
    		case EVMSG_TIMECHANGED:
    			GePrint(str+"::CoreMessage = EVMSG_TIMECHANGED");
    			break;
    		default:
    			GePrint(str+"::CoreMessage = "+LongToString(id));
    			break;
    	}
    	return TRUE;
    }
      
    Bool ListReceivedMessages(String str, LONG id, void* data)
    {
    	switch(id)
    	{
    		case MSG_POINTS_CHANGED:
    			GePrint(str+"::Message = MSG_POINTS_CHANGED");
    			break;
    		case MSG_POLYGONS_CHANGED:
    			GePrint(str+"::Message = MSG_POLYGONS_CHANGED");
    			break;
    		case MSG_SEGMENTS_CHANGED:
    			GePrint(str+"::Message = MSG_SEGMENTS_CHANGED");
    			break;
    		case MSG_UPDATE:
    			GePrint(str+"::Message = MSG_UPDATE");
    			break;
    		case MSG_SMALLUPDATE:
    			GePrint(str+"::Message = MSG_SMALLUPDATE");
    			break;
    		case MSG_CHANGE:
    			GePrint(str+"::Message = MSG_CHANGE");
    			break;
    		case MSG_BASECONTAINER:
    			GePrint(str+"::Message = MSG_BASECONTAINER");
    			break;
    		case MSG_FILTER:
    			GePrint(str+"::Message = MSG_FILTER");
    			break;
    		case MSG_TRANSFERGOALS:
    			GePrint(str+"::Message = MSG_TRANSFERGOALS");
    			break;
    		case MSG_DESCRIPTION_INITUNDO:
    			GePrint(str+"::Message = MSG_DESCRIPTION_INITUNDO");
    			break;
    		case MSG_DESCRIPTION_CHECKUPDATE:
    			GePrint(str+"::Message = MSG_DESCRIPTION_CHECKUPDATE");
    			break;
    		case MSG_DESCRIPTION_COMMAND:
    			GePrint(str+"::Message = MSG_DESCRIPTION_COMMAND");
    			break;
    		case MSG_DESCRIPTION_VALIDATE:
    			GePrint(str+"::Message = MSG_DESCRIPTION_VALIDATE");
    			break;
    		case MSG_EDIT:
    			GePrint(str+"::Message = MSG_EDIT");
    			break;
    		case MSG_MENUPREPARE:
    			GePrint(str+"::Message = MSG_MENUPREPARE");
    			break;
    		case MSG_RETRIEVEPRIVATEDATA:
    			GePrint(str+"::Message = MSG_RETRIEVEPRIVATEDATA");
    			break;
    		case MSG_DESCRIPTION_REMOVE_ENTRY:
    			GePrint(str+"::Message = MSG_DESCRIPTION_REMOVE_ENTRY");
    			break;
    		case MSG_DESCRIPTION_EDIT_ENTRY:
    			GePrint(str+"::Message = MSG_DESCRIPTION_EDIT_ENTRY");
    			break;
    		case MSG_DESCRIPTION_CHECKDRAGANDDROP:
    			GePrint(str+"::Message = MSG_DESCRIPTION_CHECKDRAGANDDROP");
    			break;
    		case MSG_DESCRIPTION_GETBITMAP:
    			GePrint(str+"::Message = MSG_DESCRIPTION_GETBITMAP");
    			break;
    		case MSG_DESCRIPTION_GETOBJECTS:
    			GePrint(str+"::Message = MSG_DESCRIPTION_GETOBJECTS");
    			break;
    		case MSG_DESCRIPTION_USERINTERACTION_END:
    			GePrint(str+"::Message = MSG_DESCRIPTION_USERINTERACTION_END");
    			break;
    		case MSG_MATERIALDRAGANDDROP:
    			GePrint(str+"::Message = MSG_MATERIALDRAGANDDROP");
    			break;
    			
    #if API_VERSION < 9800
    		case MSG_GETSUBPLUGINSHADER:
    			GePrint(str+"::Message = MSG_GETSUBPLUGINSHADER");
    			break;
    		case MSG_GETALLPLUGINSHADER:
    			GePrint(str+"::Message = MSG_GETALLPLUGINSHADER");
    			break;
    #endif
    			
    		case MSG_INITIALCHANNEL:
    			GePrint(str+"::Message = MSG_INITIALCHANNEL");
    			break;
    		case MSG_DOCUMENTINFO:
    			GePrint(str+"::Message = MSG_DOCUMENTINFO");
    			break;
    		case MSG_MULTI_DOCUMENTCLONED:
    			GePrint(str+"::Message = MSG_MULTI_DOCUMENTCLONED");
    			break;
    		case MSG_MULTI_DOCUMENTIMPORTED:
    			GePrint(str+"::Message = MSG_MULTI_DOCUMENTIMPORTED");
    			break;
    		case MSG_MULTI_MARKMATERIALS:
    			GePrint(str+"::Message = MSG_MULTI_MARKMATERIALS");
    			break;
    		case MSG_MULTI_RENDERNOTIFICATION:
    			GePrint(str+"::Message = MSG_MULTI_RENDERNOTIFICATION");
    			break;
    		case MSG_TRANSLATE_POINTS:
    			GePrint(str+"::Message = MSG_TRANSLATE_POINTS");
    			break;
    		case MSG_TRANSLATE_POLYGONS:
    			GePrint(str+"::Message = MSG_TRANSLATE_POLYGONS");
    			break;
    		case MSG_TRANSLATE_NGONS:
    			GePrint(str+"::Message = MSG_TRANSLATE_NGONS");
    			break;
    		case MSG_TRANSLATE_SEGMENTS:
    			GePrint(str+"::Message = MSG_TRANSLATE_SEGMENTS");
    			break;
    		case MSG_PRETRANSLATE_POINTS:
    			GePrint(str+"::Message = MSG_PRETRANSLATE_POINTS");
    			break;
    		case MSG_PRETRANSLATE_POLYGONS:
    			GePrint(str+"::Message = MSG_PRETRANSLATE_POLYGONS");
    			break;
    		case MSG_PRETRANSLATE_NGONS:
    			GePrint(str+"::Message = MSG_PRETRANSLATE_NGONS");
    			break;
    		case MSG_PRETRANSLATE_SEGMENTS:
    			GePrint(str+"::Message = MSG_PRETRANSLATE_SEGMENTS");
    			break;
    		case MSG_UPDATE_NGONS:
    			GePrint(str+"::Message = MSG_UPDATE_NGONS");
    			break;
    		case MSG_DOCUMENT_MODE_CHANGED:
    			GePrint(str+"::Message = MSG_DOCUMENT_MODE_CHANGED");
    			break;
    		case MSG_TOOL_RESTART:
    			GePrint(str+"::Message = MSG_TOOL_RESTART");
    			break;
    		case MSG_MOVE_FINISHED:
    			GePrint(str+"::Message = MSG_MOVE_FINISHED");
    			break;
    #if API_VERSION > 9799
    		case MSG_DESCRIPTION_POSTSETPARAMETER:
    			GePrint(str+"::Message = MSG_DESCRIPTION_POSTSETPARAMETER");
    			break;
    		case MSG_GETCUSTOMICON:
    			GePrint(str+"::Message = MSG_GETCUSTOMICON");
    			break;
    		case MSG_DRAGANDDROP:
    			GePrint(str+"::Message = MSG_DRAGANDDROP");
    			break;
    		case MSG_DEFORMMODECHANGED:
    			GePrint(str+"::Message = MSG_DEFORMMODECHANGED");
    			break;
    		case MSG_ANIMATE:
    			GePrint(str+"::Message = MSG_ANIMATE");
    			break;
    #endif
    		default:
    			GePrint(str+"::Message = "+LongToString(id));
    			break;
    	}
    	return TRUE;
    }
      
    
    

    The "str" you pass would be the name of your plugin's data class.

    Adios,
    Cactus Dan



  • On 04/05/2013 at 01:12, xxxxxxxx wrote:

    Hi,

    my simple python based thoughts on that topic - the important part, which does describe your
    problem better for me is :

    "[... ]But it's always returning the same values despite the object being moved in the viewport. [...]"
    _
    _
    I still do not fully  understand from where and when you do execute your code, but you are 
    talking about 'setting the linked objects position back to the stored state' and you said it is an 
    ObjectData plugin.

    1. GVO is threaded. It is allowed to modify objects already attached to the scene, but not 
    recommended.

    2. Changes made to an objects description in the attribute manager are being handled a bit
    awkward by c4d. If you hit undo it will you bring back multiple steps, not only to the last step. 
    C4d does treat the whole attribute modification operation as an undo. I am not quite sure, 
    what the outcome of that for the sent messages is, but it might be a reason.

    Happy rendering,
    Ferdinand
    _
    _



  • On 04/05/2013 at 02:01, xxxxxxxx wrote:

    I think I've managed to sort this one out. I popped an if statement with the Execution() function for that object inside the MSG_UPDATE message flag. It seems to be running as expected and I'm getting two different position values now.

    I thought MSG_UPDATE would of run the MainObject's Execution() function, but this doesn't appear to be the case.

    More testing to be done, but the ball seems to be rolling again! Thanks all.

    WP.


Log in to reply