Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Accessing a virtual matrix object.

    Cinema 4D SDK
    c++ sdk
    4
    5
    921
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      JohnThomas
      last edited by

      Hello,

      I am attempting to get the MoData from a Matrix object that hasn't been inserted in the open document, instead its been inserted into a virtual document. Inside of the virtual document I set the parameters of the Matrix object so that it is in Object mode. Once the mode has been changed I insert a clone of an object into the virtual document that is then linked with the Object field of the Matrix object.

      
      	BaseDocument *virtualDoc = BaseDocument::Alloc();
      	BaseObject *matrixObj = BaseObject::Alloc(1018545); // Matrix
      	if (matrixObj == nullptr)
      		return nullptr;
      	
      	BaseObject *cloneObj = (BaseObject*)op->GetDown()->GetClone(COPYFLAGS::NONE, nullptr);
      	virtualDoc->InsertObject(matrixObj, nullptr, nullptr);
      	virtualDoc->InsertObject(cloneObj, nullptr, nullptr);
      
      	BaseContainer *matrixData = matrixObj->GetDataInstance();
      	matrixData->SetInt32(ID_MG_MOTIONGENERATOR_MODE, 0);
      	matrixData->SetLink(MG_OBJECT_LINK, cloneObj);
      	matrixData->SetInt32(MG_POLY_MODE_, 0);
      
      	BaseTag *tmp = matrixObj->GetTag(ID_MOTAGDATA); // Newly inserted Matrix does not have an ID_MOTAGDATA tag
      	if (!tmp)
      		return nullptr;
      

      The code runs properly until it attempts to get the tag from the Matrix object, on the initial insertion of the Matrix it doesn't generate its MoTagData tag. Is there a way to force a refresh on the Matrix object so that it generates the MoTagData tag so that I can access the MoData?

      Any help would be appreciated,

      John Thomas

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        hello,

        you can update the document using ExecutePasses

        be aware sometimes you have to call it several times.

        BaseContainer *matrixData = matrixObj->GetDataInstance();
        	matrixData->SetInt32(ID_MG_MOTIONGENERATOR_MODE, 0);
        	matrixData->SetLink(MG_OBJECT_LINK, cloneObj);
        	matrixData->SetInt32(MG_POLY_MODE_, 0);
        
        	virtualDoc->ExecutePasses(nullptr, true, true, true, BUILDFLAGS::NONE);
        
        	BaseTag *tag = matrixObj->GetTag(ID_MOTAGDATA); 
        	if (tag == nullptr)
        		return maxon::NullptrError(MAXON_SOURCE_LOCATION);
        	
        	GetMoDataMessage msg = GetMoDataMessage();
        	tag->Message(MSG_GET_MODATA, &msg);
        	
        	MoData *md = msg.modata;
        	
        	if (md == nullptr)
        		return maxon::NullptrError(MAXON_SOURCE_LOCATION);
        
        
        	MDArray<maxon::Matrix> mdmg = md->GetMatrixArray(MODATA_MATRIX);
        

        cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        CairynC J 2 Replies Last reply Reply Quote 2
        • CairynC
          Cairyn @Manuel
          last edited by

          @m_magalhaes Speaking of ExecutePasses(): The documentation is using it per frame to forward to a certain frame for rendering. That makes sense, as the simulation (and any related task that is relying on previous-frame information) needs to be processed completely from frame 0 (or maybe even farther back).

          But what happens when you enter a frame number on the GUI and jump there? Usually, simulations that are not cached do not work properly with direct frame jumps, so I assume ExecutePasses() is only called once in these functions? It would probably be too time-consuming to run through all previous frames.

          If so, what is the underlying difference between DrawViews() with animation allowed in the flags, and ExecutePasses()? Which calls which? Am I correct in assuming that ExecutePasses() just evaluates the object tree, and is called by DrawViews() when the animation flag is set, so DrawViews() will have the current (animated) object states? Is ExecutePasses() called in any way by DrawViews() when that flag is NOT set?

          S 1 Reply Last reply Reply Quote 0
          • S
            s_bach @Cairyn
            last edited by

            @Cairyn

            DrawViews() draws the views (editor windows), which includes ExecutePasses(). ExecutePasses() itself just updates the associated BaseDocument.

            You find some information here: Scene Execution Pipeline and Thread

            For questions unrelated to this thread, please open a new thread. Thanks.

            Best wishes,
            Sebastian

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • J
              JohnThomas @Manuel
              last edited by

              @m_magalhaes Thanks for the response Manuel, that was exactly what I needed.

              John Thomas

              1 Reply Last reply Reply Quote 0
              • First post
                Last post