Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    SendModelingCommand() in R20 and R21

    Cinema 4D SDK
    r20 r21 c++
    2
    8
    1.1k
    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.
    • Danchyg1337D
      Danchyg1337
      last edited by m_adam

      Hello! I have a problem with SendModelingCommand().
      I'm compiling my plugin for 2 versions of Cinema 4D and i noticed that code below works perfectly on R20 but returns false in R21-22.
      Is there some changes in SendModelingCommand() use in R21?

      void MyPlugin::Disconnect(BaseObject* main) {
      	ModelingCommandData mcd;
      	BaseContainer bc1;
      	bc1.SetData(MDATA_DISCONNECT_PRESERVEGROUPS, false);
      	mcd.doc = main->GetDocument();
      	mcd.op = main;
      	mcd.mode = MODELINGCOMMANDMODE::POLYGONSELECTION;
      	mcd.flags = MODELINGCOMMANDFLAGS::CREATEUNDO;
      	mcd.bc = &bc1;
      	if (!SendModelingCommand(MCOMMAND_DISCONNECT, mcd)) ApplicationOutput("Disconnect error.");
      }
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @Danchyg1337 here I have no issue it's working as it was previously, can you share a scene or maybe the context of your call of SendModelingCommand?

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        Danchyg1337D 1 Reply Last reply Reply Quote 0
        • Danchyg1337D
          Danchyg1337 @m_adam
          last edited by Danchyg1337

          @m_adam I made my code as much clear as i could and i still getting false from SendModelingCommand().

          Bool MyPlugin::ModifyObject(BaseObject* mod, BaseDocument* doc, BaseObject* op, const Matrix& op_mg, const Matrix& mod_mg, Float lod, Int32 flags, BaseThread* thread)
          {
          	Disconnect(op);
          	return true;
          }
          

          While i was trying to compile the first version in R21 there was a lot of exceptions in console, i followed them and found HAS_EXCEPTIONS 0 line in apibase.h. I changed it to 1 and project did compile. Maybe it is something with that because everything else with code is ok.

          1 Reply Last reply Reply Quote 0
          • Danchyg1337D
            Danchyg1337
            last edited by

            I forgot to download R21 project tool and used R20 instead, that is why i got to change HAS_EXCEPTIONS.
            Although i recompiled it without HAS_EXCEPTIONS 1, it still doesn't work.

            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by

              @Danchyg1337 said in SendModelingCommand() in R20 and R21:

              SendModelingCommand

              As stated in the documentation it's not a good habit to do a SendModelingCommand in the ModifyObject see SendModelingCommand
              So the best workaround would be to create a temporary document, insert op into this tempo doc, ExecutePass to build the cache, operate your modeling operation on this object, and return a clone in your Deformer.

              Cheers,
              Maxime.

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

              Danchyg1337D 1 Reply Last reply Reply Quote 0
              • Danchyg1337D
                Danchyg1337 @m_adam
                last edited by

                @m_adam Thanks for your advice. I'm using multiple Disconnect calls in ModifyObject().
                I'm trying to do it, like you said, but obviously i'm doing it wrong. Can you give me another one advice on what i am doing wrong?

                AutoAlloc<BaseDocument> basedocBuffer;
                	basedocBuffer->InsertObject((BaseObject*)op->GetClone(COPYFLAGS::CACHE_BUILD, nullptr), nullptr, nullptr);
                	basedocBuffer->ExecutePasses(thread, true, true, true, BUILDFLAGS::NONE);
                	Disconnect(basedocBuffer->GetFirstObject());
                	op = basedocBuffer->GetFirstObject();
                

                That part of code still in ModifyObject(). I don't know how to avoid using it in ModifyObject().

                1 Reply Last reply Reply Quote 0
                • M
                  m_adam
                  last edited by m_adam

                  @Danchyg1337 said in SendModelingCommand() in R20 and R21:

                  mcd.flags = MODELINGCOMMANDFLAGS::CREATEUNDO;

                  sorry I overlooked the issue, the main problem here is that you pass mcd.flags = MODELINGCOMMANDFLAGS::CREATEUNDO;

                  And creating an undo step in a threading environment (aka during the scene execution) is not allowed, so you should pass MODELINGCOMMANDFLAGS::NONE;

                  Now regarding your question, since I think he can still be valid one because of some modeling operator explicitly operate on the current object but also need a document (like CurrentStateToObject) here a very naive approach that may not work in all condition (e.g. no aliastrans, so link may be lost)

                  	AutoAlloc<BaseDocument> basedocBuffer;
                  	BaseObject* clonedOp = (BaseObject*)op->GetClone(COPYFLAGS::NONE, nullptr);
                  	basedocBuffer->InsertObject(clonedOp, nullptr, nullptr);
                  	basedocBuffer->ExecutePasses(thread, true, true, true, BUILDFLAGS::INTERNALRENDERER);
                  
                  	ModelingCommandData mcd;
                  	BaseContainer bc;
                  
                  	bc.SetData(MDATA_DISCONNECT_PRESERVEGROUPS, false);
                  
                  	mcd.doc = basedocBuffer;
                  	mcd.op = clonedOp;
                  	mcd.mode = MODELINGCOMMANDMODE::POLYGONSELECTION;
                  	mcd.flags = MODELINGCOMMANDFLAGS::NONE;
                  	mcd.bc = &bc;
                  
                  	if (!SendModelingCommand(MCOMMAND_DISCONNECT, mcd))
                  		ApplicationOutput("Disconnect error.");
                  
                  	clonedOp->CopyTo(op, COPYFLAGS::NONE, nullptr);
                  	clonedOp->CopyMatrixTo(op);
                  	clonedOp->CopyTagsTo(op, NOTOK, NOTOK, NOTOK, nullptr);
                  

                  And why it was worked previously? I would say it didn't properly, but the CriticalStop wasn't there internally, so we simply returned without knowing there is an issue.

                  Hope it helps,
                  Cheers,
                  Maxime.

                  MAXON SDK Specialist

                  Development Blog, MAXON Registered Developer

                  1 Reply Last reply Reply Quote 1
                  • Danchyg1337D
                    Danchyg1337
                    last edited by

                    @m_adam MODELINGCOMMANDFLAGS::NONE works! Thanks again for helping me out!

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