Automatically generate an uvw tag and rename it



  • On 13/04/2018 at 02:06, xxxxxxxx wrote:

    Hi people, as a redshift for c4d user, i'd like to make a little script which would make me win a lot of time. Indeed, i have a lot of objects which contain UVW coordinates to apply textures on them and as redshift use multiple UVW chanels to project them in a different way, i have to manually create different UVW tags to obtain what i want. I explain: let's say i have a cube with a diffuse map using uvw projection, i can also add a noise map for bump (or reflection, etc.) using the cubic projection instead. So i select my material, apply a cubic projection on it and then generate a new uvw tag which name will be "CUBIC". then in the UV chanel of the texture (in RS material) i give each map the good name to project correctly. I hope i am clear ;-)
    So, i'd like to do this operation with a script and it seems to me the only way to do that is "python", that i have never used and was sure would never have to. I've tried to copy and paste the code generated by c4d and it works (in a way) because i'm able to generate my new UVW tag but still have to rename it manually (that's what i'd like to avoid). And after long long hours on the web, i'd like real professionals to help me a bit. 
    So, is it possible? And if it is, how to do that? While searching, i've found "functions" such as SetActive, GetActive, etc. but i don't know how to implement them.
    So thank you if you've read this (and understood what i meant) and thank you for your time.

    Here is my actual code:

      
    import c4d
    from c4d import documents, plugins
    #Welcome to the world of Python
      
    def main() :
        def tool() :
            return plugins.FindPlugin(doc.GetAction(), c4d.PLUGINTYPE_TOOL)
      
        def object() :
            return doc.GetActiveObject()
      
        def tag() :
            return doc.GetActiveTag()
      
        def renderdata() :
            return doc.GetActiveRenderData()
      
        def prefs(id) :
            return plugins.FindPlugin(id, c4d.PLUGINTYPE_PREFS)
      
        tag()[c4d.TEXTURETAG_PROJECTION]=3
        newTag = c4d.CallCommand(12235, 12235) # Générer des coordonnées UVW
     
        c4d.EventAdd()
        
    if __name__=='__main__':
        main()
    

    Thanks a lot



  • On 13/04/2018 at 04:00, xxxxxxxx wrote:

    I have tried to explain in your thread over at the C4DCafe that the best option for you was to rename the created tag.
    For this, of course, you need to get the created tag, which cannot directly from the callcommand

    So, I came up with this code. Maybe not the best approach (I am not a Python developer).

      
    import c4d  
      
    def main() :  
      doc = c4d.documents.GetActiveDocument()  
      obj = doc.GetActiveObject()  
      
      tags = obj.GetTags()  
      c4d.CallCommand(12235, 12235)  
      newtags = obj.GetTags()  
      
      newname = "NewName"  
        
      for tag in newtags:  
          if tag not in tags:  
              # this is your newly created UVW tag  
              # rename it  
              tag.SetName(newname)  
      
      c4d.EventAdd()  
      
      
    if __name__=='__main__':  
      main()  
      
    

    Basically, you get the list of tags applied to your object, then perform your callcommand to generate the UVW tag. Then you get the list of the tags after. The difference between the tags after and before your callcommand will give you the UVW tag being created.
    Then it's simply a matter of setting its name.

    Notice that I left out validation code, checking if an object was selected ... and such things as error checking.



  • On 15/04/2018 at 00:54, xxxxxxxx wrote:

    Thank you C4DS… Taking in account your answer (here and on the C4Dcafe forum), i'm now able to create my new UVW tag but i don't know yet how to apply a cubic projection to my material and then give this attribute to the new uvw tag. 
    Finally, I think i don't have to use the projection but recreate dynamically new coordinates to my UV and that's my new goal.

    If someone could give me advices, or confirm it's the good way to make it, i would be glad.
    Thank you

    Here is my actual code (i don't find the way to format it as a code, sorry) :

    import c4d
    from c4d import documents, plugins
    #Welcome to the world of Python
      
    def main() :
        #VARIABLES
        doc = c4d.documents.GetActiveDocument()
        obj = doc.GetActiveObject()
        tags = obj.GetTags()
        uvTag = obj.GetTag(c4d.Ttexture)
        #print tags
        
        #CUBIC PROJECTION (useless i think)
        projection = uvTag[c4d.TEXTURETAG_PROJECTION] = 3
        
        #Create new UVW TAG
        ensemble = obj.GetPolygonCount()
        print ensemble
        newTag = obj.MakeVariableTag(c4d.Tuvw,ensemble)
        
        newtags = obj.GetTags()
        newname = "CUBIC"
            
        for tag in newtags:
            if tag not in tags: # this is your newly created UVW tag
                tag.SetName(newname)  # rename it
      
        c4d.EventAdd();
      
    if __name__=='__main__':
        main()
    


  • On 15/04/2018 at 06:36, xxxxxxxx wrote:

    When you create your own "newTag" you don't need the "newtags" and the for loop, since you already have the tag you need to rename.

      
        newTag = obj.MakeVariableTag(c4d.Tuvw, ensemble)  
        newTag.SetName("CUBIC")
      
        c4d.EventAdd();
    

    With the new UVW tag created you then still need to populate the UV coordinates



  • On 15/04/2018 at 10:00, xxxxxxxx wrote:

    Hello, yes i already corrected this part. 😉
    It's now time for the last part of my hassle. At this point obviously, my UVW are stretched. I think i must retrieve points position in a table and use them to generate new UVW coordinates. I do not despair

    import c4d
    from c4d import documents, plugins
    #Welcome to the world of Python
      
    def main() :
        
        #VARIABLES
        doc = c4d.documents.GetActiveDocument()
        obj = doc.GetActiveObject()
      
        
        #CREER NOUVEAU UVW TAG
        ensemble = obj.GetPolygonCount() #Definit le nombre de polygones
        newTag = obj.MakeVariableTag(c4d.Tuvw,ensemble) #Crée le tag avec le nombre
        newTag.SetName('CUBIC')#Renomme le tag
      
        #DEFINIR SES COORDONNEES
        dimensions = obj.GetAllPoints() #Définit une LISTE et position de tous les points
        print dimensions
        
        for i in xrange(newTag.GetDataCount()) :
            uvwdict = newTag.GetSlow(i)
            #print uvwdict["a"], uvwdict["b"], uvwdict["c"], uvwdict["d"]
            p1 = c4d.Vector(0,0,0)
            p2 = c4d.Vector(0,1,0)
            p3 = c4d.Vector(1,1,0)
            p4 = c4d.Vector(1,0,0)
            print p1,p2,p3,p4
            newTag.SetSlow(i, p1, p2, p3, p4)
      
            
        c4d.EventAdd();
      
    if __name__=='__main__':
        main()
    


  • On 16/04/2018 at 08:52, xxxxxxxx wrote:

    Hi nicolectro, first of all, welcome on plugincafe.

    I think your first approach is the easiest way, here is how to process.
    The key is to use GenerateUVW

    import c4d
      
    def main() :
        doc = c4d.documents.GetActiveDocument()
        obj = doc.GetActiveObject()
        tags = obj.GetTags()
        matTag = obj.GetTag(c4d.Ttexture)
        if matTag is None:
            matTag = c4d.BaseTag(c4d.Ttexture)
            obj.InsertTag(matTag)    
        
        matTag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_CUBIC
      
        uvwTag = c4d.utils.GenerateUVW(obj, obj.GetMg(), matTag, obj.GetMg())
        uvwTag.SetName("CUBIC")
        obj.InsertTag(uvwTag)
      
        c4d.EventAdd()
      
    if __name__=='__main__':
        main()
    

    In another hand, I suggest you put your code [code ] markdown in order to increase the readability of your code for other users.

    Please let me know if you got any questions.

    Cheers,
    Maxime



  • On 16/04/2018 at 09:40, xxxxxxxx wrote:

    Hello MaximeA, thanks a million. I've spent so much time without finding a simple way to do that. It seems to be so simple when you give me the answer. First try, big headache but thanks to you, it finally works. So, here is my final code. You're the one…

    import c4d
    from c4d import documents, plugins
    from c4d import gui
    #Welcome to the world of Python
      
    def main() :
        doc = c4d.documents.GetActiveDocument()
        obj = doc.GetActiveObject()
        
        #SELECTION OBJET
        if obj is None:
            gui.MessageDialog('Select an object first') 
            return
        
        tags = obj.GetTags()
        
        matTag = obj.GetTag(c4d.Ttexture)
        if matTag is None:
            gui.MessageDialog('Insert a material first')
      
        
        matTag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_CUBIC
      
        uvwTag = c4d.utils.GenerateUVW(obj, obj.GetMg(), matTag, obj.GetMg())
        uvwTag.SetName("CUBIC")
        newName = uvwTag.GetName() # Récupère le nom du tag
        #print newName
        finalName = gui.RenameDialog(newName) #fenêtre dialogue
        uvwTag.SetName(finalName) #Renomme le tag définitivement
        #print finalName
        
        obj.InsertTag(uvwTag)
      
        matTag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW
        
        c4d.EventAdd();
      
    if __name__=='__main__':
        main()
    

    PS : petit mot en français car je vois que tu es de l'hexagone. Est-ce qu'il y a une manière d'utiliser la documentation que je n'aurais pas compris. C'est moi ou c'est hyper compliqué ? Et très peu de ressources sur Google. J'ai eu un mal fou à trouver des infos claires. Finalement, on est un peu obligé de s'en remettre à de vrai pro (comme toi par exemple) qui finissent par donner des bouts de code déjà exploitables. J'aime bien chercher par moi-même mais là je ne te cache pas que j'étais sur le point d'abandonner. Merci mille fois en tout cas et j'espère que j'ai bien inséré les balises de code car je ne vois pas de preview.



  • On 17/04/2018 at 05:58, xxxxxxxx wrote:

    Hi Nicolectro,

    Thanks for sharing your final code.

    Even if I understand French, please consider speaking English in order to also help future users ;)
    Sadly there is no easy way to learn, the python sdk, except reading it. But I can suggest you to look at https://developers.maxon.net/?p=2985, in any way do not hesitate to ask us on the forum or even by email at sdk_support@maxon.net.

    About code markdown, you forget a / it's actually [code ] your code [/code ] :)

    Cheers,
    Maxime



  • On 17/04/2018 at 06:15, xxxxxxxx wrote:

    Thank you very much. I've changed that in my posts.


Log in to reply