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 [email protected].

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.