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

    Can I catch Ctrl + C in a Scene Hook?

    SDK Help
    0
    16
    1.2k
    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.
    • H
      Helper
      last edited by

      On 03/02/2015 at 14:04, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:    
      Platform:      
      Language(s) :

      ---------
      I tried it by overriding SceneHookData::KeyboardInput() and I receive any character pressed but not in
      combination with CTRL pressed. Any chance this is possible?

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 03/02/2015 at 14:48, xxxxxxxx wrote:

        Hi Niklas,

        actually I may currently be working in a similar area. It sounds like you want to hook the Copy and Paste in your Scenehook. Can you provide me with some more info, what you are actually trying to achieve?

        Maybe checkout MSG_DOCUMENTINFO with DocumentInfoData[URL-REMOVED] (types: MSG_DOCUMENTINFO_TYPE_COPY and MSG_DOCUMENTINFO_TYPE_PASTE) in conjunction with the DocumentInfoClipData structure. Sorry, documentation is poor.

        Regarding the core of your question, I'll do some testing tomorrow, I had though, that this would be possible by checking the modifiers, but in the end Ctrl-C is special... we'll see.


        [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 15/09/2015 at 15:38, xxxxxxxx wrote:

          Hi there,
          is there change to see any sample code to catch copy/paste operations. I wish to add some extra materials copy buffer when material copy operation is done. Also i need to make some connections when these are pasted to other document.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 16/09/2015 at 06:16, xxxxxxxx wrote:

            Hi Ahmet,

            currently we have no example. I will do my best to provide you with one in the next few days (not sure, I'll make it this week).

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 16/09/2015 at 08:02, xxxxxxxx wrote:

              Hi Andreas,
              Thanks for reply. After asking that i solved to catch COPY message. Please see my first codes. I hope that's correct way. Also trying to catch pasted objects and materials. You can see in second part of codes. In the case "MSG_DOCUMENTINFO_TYPE_PASTE", data->arr is always NULL. Is it expected behaviour? How can we get pasted C4DAtom's?

                      case MSG_DOCUMENTINFO:
              
              
                      {
              
              
                          DocumentInfoData \*docinfo = (DocumentInfoData\* )data;
              
              
                          Int32 docInfoType = docinfo->type;
              
              
                          BaseList2D \*bl = docinfo->bl;
              
              
                          String str=LS(docInfoType);
              
              
                
              
              
              
                          switch(docInfoType)
              
              
                          {
              
              
                              case MSG_DOCUMENTINFO_TYPE_COPY:
              
              
                              {
              
              
                                  //---- CATCH MATERIAL COPY OPERATION AND CLONE/STORE LINKED MATERIALS ----//
              
              
                                  DocumentInfoClipData \*d = (DocumentInfoClipData\* ) docinfo->data;
              
              
                
              
              
              
                                  for(int j=0;j<OCTLIVE->clonedMatLinks.GetCount();j++)
              
              
                                  {
              
              
                                      BaseLink \*link = OCTLIVE->clonedMatLinks[j];
              
              
                                      if(!link) continue;
              
              
                                      BaseMaterial \*mat = (BaseMaterial\* ) link->ForceGetLink();
              
              
                                      //if(mat) info("Delete stored mat:"+mat->GetName());
              
              
                                      if(mat) BaseMaterial::Free(mat);
              
              
                                      BaseLink::Free(link);
              
              
                                  }
              
              
                                  OCTLIVE->clonedMatLinks.FreeArray();
              
              
                                  OCTLIVE->copyOperationDoc = adoc;
              
              
                
              
              
              
                                  //---- CHECK COPYBUFFER FOR MATS/OBJECTS, ADD TO MATS ARRAY ----//
              
              
                                  GeDynamicArray<BaseMaterial\*> mats;
              
              
                                  for(int i=0;i<d->arr->GetCount();i++)
              
              
                                  {
              
              
                                      C4DAtom \*atom=d->arr->GetIndex(i);
              
              
                
              
              
              
                                      if(atom->IsInstanceOf(Obase)) //--- IT'S BASEOBJECT, GET MATERIALS ----//
              
              
                                      {
              
              
                                          BaseObject \*op = static_cast<BaseObject\*> (atom);
              
              
                                          for (BaseTag\* tag=op->GetFirstTag(); tag; tag=tag->GetNext())
              
              
                                          {
              
              
                                              if(tag && tag->GetType()==Ttexture)
              
              
                                              {
              
              
                                                  BaseMaterial \*mat = (Material\* )getParameterLink(\*tag, TEXTURETAG_MATERIAL, 0);
              
              
                                                  if(mat && mats.Find(mat)==NOTOK) mats.Push(mat);
              
              
                                              }
              
              
                                          }
              
              
                                      }
              
              
                                      if(atom->IsInstanceOf(Mbase))  //---- BASEMATERIAL ----//
              
              
                                      {
              
              
                                          BaseMaterial \*mat = static_cast<BaseMaterial\*> (atom);
              
              
                                          if(mats.Find(mat)==NOTOK) mats.Push(mat);
              
              
                                      }
              
              
                                  }
              
              
                
              
              
              
              		......
              
              
              		......
              
              
              		......
              
              
              		......
              
              
                
              
              
              
                
              
              
              
                
              
              
              
              
                      //---- CATCH MATERIAL PASTE OPERATION AND CREATE COPIED MATERIALS ----//
              
              
                              case MSG_DOCUMENTINFO_TYPE_PASTE:
              
              
                              {
              
              
                                  DocumentInfoClipData \*data = (DocumentInfoClipData\* ) docinfo->data;
              
              
                                  if(data) info("PASTE data:"+PS(data)+"  "+PS(data->arr));
              
              
                
              
              
              
                                  //--- avoid handling on same document ---//
              
              
                                  if(adoc==OCTLIVE->copyOperationDoc) return false;
              
              
                
              
              
              
                                  matPastePath=adoc->GetDocumentPath().GetDirectory().GetString();
              
              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 16/09/2015 at 08:07, xxxxxxxx wrote:

                Hi Ahmet,

                I'm not sure, that it's the intended behavior, but unfortunately it is the behavior... you don't get the array on paste. But DocumentInfoClipData contains a BaseContainer (bcdata), which you can use to pass any data you need from copy to paste.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 16/09/2015 at 08:22, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  Hi Ahmet,

                  I'm not sure, that it's the intended behavior, but unfortunately it is the behavior... you don't get the array on paste. But DocumentInfoClipData contains a BaseContainer (bcdata), which you can use to pass any data you need from copy to paste.

                  So, how can i add additional materials to BaseContainer to be pasted? Thanks

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 16/09/2015 at 08:26, xxxxxxxx wrote:

                    To be honest, that's everything else than straight forward. One way might be to store the materials BaseContainer in the copy/paste BaseContainer and recreate it from there on paste.

                    You could be tempted to simply store a BaseLink on copy and then use ForceGetLink() on paste. But be warned, that will fail, if the user closes the original document after copy.

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 16/09/2015 at 08:32, xxxxxxxx wrote:

                      So what i understand that we don't have any info about pasted objects/materials in MSG_DOCUMENTINFO_TYPE_PASTE message. So should I do it manually copy them in COPY message and use in PASTE message?

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 16/09/2015 at 08:37, xxxxxxxx wrote:

                        I'm afraid, yes. At least that's what I am doing and I haven't found a better solution, yet.

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 16/09/2015 at 08:40, xxxxxxxx wrote:

                          Just to warn you, you will need a similar mechanism in order to get "Merge..." to work (MSG_DOCUMENTINFO_TYPE_BEFOREMERGE and MSG_DOCUMENTINFO_TYPE_MERGE), except that there's no BaseContainer prepared for you...
                          As said before, I plan to provide a "simple" example in the near future.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            On 16/09/2015 at 08:45, xxxxxxxx wrote:

                            Ok i see. Situations is a bit complex here. I'm duplicating linked materials which are linked to mix materials and i should remove the doubled copy of same mix material on paste and make relink. I think solutions should be to modify this "const AtomArray* arr" in DocumentInfoClipData. Thought is as an advice for future. I'll try to do with current way.

                            Thanks for all your helps,
                            Best regards

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              On 16/09/2015 at 08:59, xxxxxxxx wrote:

                              I had to walk the road that lies ahead of you and I didn't like it...

                              Especially identifying the materials on paste can be really tricky. Can you perhaps give me some more detail on the materials and how they are linked? I mean, is it your own MaterialData material, that needs special handling? Or is it about special shaders linked into the standard material?

                              Here I had the situation, that I had my own shader, which then linked to some special resource. On Copy/Paste I needed to make sure, that on every copied material (actually every copied object, that may contain a shader), not only the material got copied, but also the special resource that was linked by the shader.

                              The copy part was actually quite easy (similar to your code above). But then on paste I needed to identify the pasted shaders, in order to repair the links. In the end I stored a pointer to my special resource inside of the shader (special care needs to be taken in CopyTo of the shader). Side note: Never ever dereference such a pointer! On copy I stored this pointer in the BaseContainer and on paste I could then walk all shaders looking for that pointer (using the pointer just as a compare key) and thus repair the link.

                              Not sure, if the above makes sense. It's a bit hard to explain in a few words.

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                On 16/09/2015 at 09:19, xxxxxxxx wrote:

                                I understand what you mean with pointers. I remember that i did similar tricks to store pointers to be sure. Because material pointers always change on previews, etc... I wrote them to BaseContainer from a Hook.
                                Here is my all code for pasting and fixing the links. This works as expected but problem is that Also C4D copies same mix material with empty linkage. I should find and replace with my cloned materials.

                                                //---- CATCH MATERIAL PASTE OPERATION AND CREATE COPIED MATERIALS ----//
                                
                                
                                                case MSG_DOCUMENTINFO_TYPE_PASTE:
                                
                                
                                                {
                                
                                
                                                    DocumentInfoClipData \*data = (DocumentInfoClipData\* ) docinfo->data;                   
                                
                                
                                                    if(data) info("PASTE data:"+PS(data)+"  "+PS(data->arr));
                                
                                
                                  
                                
                                
                                
                                                    //--- avoid handling on same document ---//
                                
                                
                                                    if(adoc==OCTLIVE->copyOperationDoc) return false;
                                
                                
                                                    matPastePath=adoc->GetDocumentPath().GetDirectory().GetString();
                                
                                
                                  
                                
                                
                                
                                                    GeDynamicArray<BaseMaterial\*> mats;
                                
                                
                                  
                                
                                
                                
                                                    Int cnt = OCTLIVE->clonedMatLinks.GetCount();
                                
                                
                                  
                                
                                
                                
                                                    adoc->StartUndo();
                                
                                
                                                    std::vector<BaseMaterial\*> pastedMats;
                                
                                
                                  
                                
                                
                                
                                                    //---- PASTE STORED MATERIALS TO DOCUMENT ----//
                                
                                
                                                    for(int j=0;j<cnt;j++)
                                
                                
                                                    {
                                
                                
                                                        BaseLink \*link = OCTLIVE->clonedMatLinks[j];
                                
                                
                                                        if(!link) continue;
                                
                                
                                                        BaseMaterial \*mat = (BaseMaterial\* ) link->ForceGetLink();
                                
                                
                                                        if(mat)
                                
                                
                                                        {
                                
                                
                                                           // info("Paste "+mat->GetName());
                                
                                
                                                            AutoAlloc<AliasTrans> aliasTrans;
                                
                                
                                                            if (!aliasTrans || !aliasTrans->Init(mat->GetDocument()))  return FALSE;
                                
                                
                                  
                                
                                
                                
                                                            BaseMaterial \*newMat=NULL;
                                
                                
                                                            newMat = (BaseMaterial\* ) mat->GetClone(COPYFLAGS_RECURSIONCHECK, aliasTrans);
                                
                                
                                                            aliasTrans->Translate(TRUE);
                                
                                
                                  
                                
                                
                                
                                                            if(newMat) adoc->InsertMaterial(newMat, NULL, false);
                                
                                
                                                            if(newMat) adoc->AddUndo(UNDOTYPE_NEW, newMat);
                                
                                
                                                            pastedMats.push_back(newMat);
                                
                                
                                                        }
                                
                                
                                                    }
                                
                                
                                  
                                
                                
                                
                                                    //---- MAKE NEW LINKS ----//
                                
                                
                                                    for(int j=0;j<cnt;j++)
                                
                                
                                                    {
                                
                                
                                                        BaseLink \*link = OCTLIVE->clonedMatLinks[j];
                                
                                
                                                        if(!link) continue;
                                
                                
                                                        BaseMaterial \*mat = (BaseMaterial\* ) link->ForceGetLink();
                                
                                
                                                        if(mat && mat->IsInstanceOf(ID_OCTANE_MIX_MATERIAL))
                                
                                
                                                        {
                                
                                
                                                            BaseMaterial\* m1 = static_cast<BaseMaterial\*> (getParameterLink(\*mat, MIXMATERIAL_TEXTURE1, Mbase));
                                
                                
                                                            BaseMaterial\* m2 = static_cast<BaseMaterial\*> (getParameterLink(\*mat, MIXMATERIAL_TEXTURE2, Mbase));
                                
                                
                                                            Int n1=-1, n2=-1;
                                
                                
                                                            for(int k=0;k<cnt;k++) if(m1==OCTLIVE->clonedMatLinks[k]->ForceGetLink()) n1=k;
                                
                                
                                                            for(int k=0;k<cnt;k++) if(m2==OCTLIVE->clonedMatLinks[k]->ForceGetLink()) n2=k;
                                
                                
                                  
                                
                                
                                
                                                            if(n1!=-1) pastedMats[j]->SetParameter(DescLevel(MIXMATERIAL_TEXTURE1), GeData(pastedMats[n1]), DESCFLAGS_SET_0);
                                
                                
                                                            if(n2!=-1) pastedMats[j]->SetParameter(DescLevel(MIXMATERIAL_TEXTURE2), GeData(pastedMats[n2]), DESCFLAGS_SET_0);
                                
                                
                                                        }
                                
                                
                                                    }
                                
                                
                                  
                                
                                
                                
                                                    EventAdd();
                                
                                
                                                    adoc->EndUndo();
                                
                                
                                                }
                                
                                
                                                break;
                                
                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  On 16/09/2015 at 09:22, xxxxxxxx wrote:

                                  Just remember that ForceGetLink() won't work, if the user closed the source document before pasting.

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    On 16/09/2015 at 09:25, xxxxxxxx wrote:

                                    Originally posted by xxxxxxxx

                                    Just remember that ForceGetLink() won't work, if the user closed the source document before pasting.

                                    Yes thanks. I think that we face up to if there's not any other way?

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