Code Vonc

Objet UVW

v 1.3

Script Python pour Cinéma 4D R13.

TéléchargerDownload
Faire un donMake a donation
Comment installer ?How to install ?
CommentairesComments

Transforme les coordonnées UVW en un objet polygonal et inversement.





import c4d
from c4d import gui, Vector
import math
from math import pi

class Dialogue(gui.GeDialog):
    objs = None
    uvws = None
    obj_3d = None
    obj_uvw = None
    proj = 0
    annuler = True
    mode = 0
    echelle = 1000
    cadre = True
    
    def __init__(self, ops):
        self.objs = ops
    
    def CreateLayout(self):
        nb = len(self.objs)
        if (nb == 2):
            nom = self.objs[1].GetName()
        else:
            nom = "[Nouveau]"
        
        self.SetTitle("Objet UVW v1.3")
        self.GroupBegin(100, c4d.BFH_SCALEFIT, 2)
        
        self.GroupBegin(101, c4d.BFH_SCALEFIT|c4d.BFV_TOP, 1, title = "Objet 3D")
        self.GroupBorder(c4d.BORDER_GROUP_IN)
        self.GroupBorderSpace(7, 7, 7, 7)
        self.AddRadioGroup(200, c4d.BFH_LEFT, 1)
        self.AddChild(200, 0, self.objs[0].GetName())
        if (nb == 2): self.AddChild(200, 1, nom)
        self.AddStaticText(205, c4d.BFH_SCALEFIT, inith = 14, name = "")
        self.AddButton(203, c4d.BFH_SCALEFIT, inith = 20, name = "Texturer")
        self.GroupEnd()
        
        self.GroupBegin(102, c4d.BFH_SCALEFIT|c4d.BFV_TOP, 1, title = "Objet UVW")
        self.GroupBorder(c4d.BORDER_GROUP_IN)
        self.GroupBorderSpace(7, 7, 7, 7)
        self.AddRadioGroup(201, c4d.BFH_LEFT, 1)
        if (nb == 2): self.AddChild(201, 0, self.objs[0].GetName())
        self.AddChild(201, 1, nom)
        self.AddComboBox(204, c4d.BFH_SCALEFIT)
        self.AddChild(204, 0, "Projection UVW")
        self.AddChild(204, 1, "Projection Frontale (3D)")
        self.AddButton(202, c4d.BFH_SCALEFIT, inith = 20, name = "Créer")
        self.GroupEnd()
        
        self.GroupEnd()
        self.GroupBegin(100, c4d.BFH_SCALEFIT, 4)
        self.GroupBorderSpace(20, 5, 20, 5)
        self.AddStaticText(103, c4d.BFH_RIGHT, 0, 0, "Échelle : ")
        self.AddEditNumberArrows(207, c4d.BFH_LEFT, 80)
        self.AddCheckbox(208,c4d.BFH_SCALE, 0, 0, "Cadre")
        self.AddButton(206, c4d.BFH_SCALE, 100, 15, name = "Annuler")
        self.GroupEnd()
        self.AddStaticText(103, c4d.BFH_SCALEFIT, 500, 0, "César Vonc - http://code.vonc.fr", 1)
        
        self.SetLong(200, 0)
        self.SetLong(201, 1)
        self.SetReal(207, 1000)
        self.SetBool(208, True)
        if (nb == 1): self.Enable(203, False)
        else:
            self.Enable(202, False)
            self.Enable(204, False)
        return True
    
    def Command(self, id, msg):
        if (id == 200):
            if self.GetLong(200) == 0: self.SetLong(201, 1)
            else: self.SetLong(201, 0)
        
        if (id == 201):
            if self.GetLong(201) == 0: self.SetLong(200, 1)
            else: self.SetLong(200, 0)
        
        if (id == 202 or id == 203):
            self.annuler = False
            self.obj_3d = self.GetLong(200)
            self.obj_uvw = self.GetLong(201)
            self.proj = self.GetLong(204)
            self.echelle = self.GetReal(207)
            self.cadre = self.GetBool(208)
            if (id == 202): self.mode = 0
            else :self.mode = 1
            self.Close()
            
        if (id == 206):
            self.annuler = True
            self.Close()
        
        return True

def erreur(n):
    message = ["Veuillez sélectionner un ou deux objets.",
    "L'objet 3D ne correspond pas avec l'objet UVW : leur nombre de polygones diffère.",
    "L'objet 3D ne contient pas de propriété UVW.",
    "L'objet 3D n'est pas un objet polygonal.",
    "L'objet UVW n'est pas un objet polygonal."]
    gui.MessageDialog(message[n])

def modCoor(v, ech):
    v *= ech
    return v

def demodCoor(v, ech):
    v *= 1/ech
    return v

def trouve_sel(sels, nom):
    for s in sels:
        if nom == s[c4d.ID_BASELIST_NAME]:
            return s

def creer_obj_uvw(p_uvw, p_texs, obj_3d, proj, ech, sels, cadre):
    objet = c4d.BaseObject(c4d.Opolygon)
    nb_polys = obj_3d.GetPolygonCount()
    nb_pts = 0
    maillage = []
    points = []
    if proj == 0: # UVW
        for i in xrange(p_uvw.GetDataCount()):
            p_uvw_pol = p_uvw.GetSlow(i)
            poly = obj_3d.GetPolygon(i)
            
            points.append(modCoor(p_uvw_pol["a"], ech))
            points.append(modCoor(p_uvw_pol["b"], ech))
            points.append(modCoor(p_uvw_pol["c"], ech))
            
            if (poly.c == poly.d):
                nouv_poly = c4d.CPolygon(nb_pts, nb_pts+1, nb_pts+2, nb_pts+2)
                nb_pts += 3
            else:
                nouv_poly = c4d.CPolygon(nb_pts, nb_pts+1, nb_pts+2, nb_pts+3)
                nb_pts += 4
                points.append(modCoor(p_uvw_pol["d"], ech))
                
            maillage.append(nouv_poly)
            
    elif proj == 1: # Frontale
        points = obj_3d.GetAllPoints()
        maillage = obj_3d.GetAllPolygons()
        mob = Vector(ech/2, ech/2, 0)
        points = [p + mob for p in points]
        nb_pts = len(points)
    
    objet.ResizeObject(nb_pts, nb_polys)
    objet.SetAllPoints(points)
    for p in range(nb_polys):
        objet.SetPolygon(p, maillage[p])
    
    doc.StartUndo()
    objet.Message(c4d.MSG_UPDATE)
    objet[c4d.ID_BASELIST_NAME] = obj_3d[c4d.ID_BASELIST_NAME] + " UVW"
    p_texs.reverse()
    for p_tex in p_texs:
        if not p_tex: continue
        p_tex2 = c4d.BaseTag(c4d.Ttexture)
        p_tex2[c4d.TEXTURETAG_MATERIAL] = p_tex[c4d.TEXTURETAG_MATERIAL]
        p_tex2[c4d.TEXTURETAG_SIZE] = Vector(ech/2, ech/2, ech/2)
        p_tex2[c4d.TEXTURETAG_POSITION] = Vector(ech/2, ech/2, 0)
        p_tex2[c4d.TEXTURETAG_ROTATION] = Vector(0, pi, 0)
        p_tex2[c4d.TEXTURETAG_PROJECTION] = 2
        p_tex2[c4d.TEXTURETAG_OFFSETX] = p_tex[c4d.TEXTURETAG_OFFSETX]
        p_tex2[c4d.TEXTURETAG_OFFSETY] = p_tex[c4d.TEXTURETAG_OFFSETY]
        p_tex2[c4d.TEXTURETAG_LENGTHX] = p_tex[c4d.TEXTURETAG_LENGTHX]
        p_tex2[c4d.TEXTURETAG_LENGTHY] = p_tex[c4d.TEXTURETAG_LENGTHY]
        p_tex2[c4d.TEXTURETAG_TILESX] = p_tex[c4d.TEXTURETAG_TILESX]
        p_tex2[c4d.TEXTURETAG_TILESY] = p_tex[c4d.TEXTURETAG_TILESY]
        p_tex2[c4d.TEXTURETAG_REPETITIONX] = p_tex[c4d.TEXTURETAG_REPETITIONX]
        p_tex2[c4d.TEXTURETAG_REPETITIONY] = p_tex[c4d.TEXTURETAG_REPETITIONY]
        p_tex2[c4d.TEXTURETAG_RESTRICTION] = p_tex[c4d.TEXTURETAG_RESTRICTION]
        objet.InsertTag(p_tex2)
        if p_tex[c4d.TEXTURETAG_RESTRICTION]:
            selp = objet.MakeTag(c4d.Tpolygonselection)
            selp[c4d.ID_BASELIST_NAME] = p_tex[c4d.TEXTURETAG_RESTRICTION]
            bs2 = selp.GetBaseSelect()
            sel = trouve_sel(sels, p_tex[c4d.TEXTURETAG_RESTRICTION])
            if sel:
                bs = sel.GetBaseSelect()
                bs.CopyTo(bs2)
    if cadre is True:
        rect = c4d.BaseObject(c4d.Osplinerectangle)
        rect[c4d.PRIM_RECTANGLE_WIDTH] = ech
        rect[c4d.PRIM_RECTANGLE_HEIGHT] = ech
        rect[c4d.ID_BASEOBJECT_REL_POSITION] = Vector(ech/2, ech/2, 0)
        rect[c4d.ID_BASELIST_NAME] = "Cadre"
        doc.InsertObject(rect, objet)
        doc.AddUndo(c4d.UNDOTYPE_NEW, rect)
    objet[c4d.ID_BASEOBJECT_REL_ROTATION] = Vector(0, pi/2, 0)
    doc.InsertObject(objet)
    doc.AddUndo(c4d.UNDOTYPE_NEW, objet)
    doc.SetActiveObject(objet)
    c4d.EventAdd()
    doc.EndUndo()

def creer_prop_uvw(obj_3d, obj_uvw, ech):
    nb_polys = obj_uvw.GetPolygonCount()
    nb_polys_obj = obj_3d.GetPolygonCount()
    if nb_polys != nb_polys_obj:
        erreur(1)
        return
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_CHANGE_NOCHILDREN, obj_3d)
    p_uvw = obj_3d.MakeVariableTag(c4d.Tuvw, nb_polys)
    for p in range(nb_polys):
        pol = obj_uvw.GetPolygon(p)
        pA = demodCoor(obj_uvw.GetPoint(pol.a), ech)
        pB = demodCoor(obj_uvw.GetPoint(pol.b), ech)
        pC = demodCoor(obj_uvw.GetPoint(pol.c), ech)
        pD = demodCoor(obj_uvw.GetPoint(pol.d), ech)
        p_uvw.SetSlow(p, pA, pB, pC, pD)
    c4d.EventAdd()
    doc.EndUndo()

def objetuvw():
    objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
    nb = len(objs)
    if nb > 2 or nb == 0:
        erreur(0)
        return False
    
    dial = Dialogue(objs)
    dial.Open(c4d.DLG_TYPE_MODAL)
    if dial.annuler is True: return False
    
    ech = dial.echelle
    cadre = dial.cadre
    obj_3d = objs[dial.obj_3d]
    if nb > 1: obj_uvw = objs[dial.obj_uvw]
    else: obj_uvw = None
    if obj_3d.GetType() != c4d.Opolygon :
        erreur(3)
        return False
    
    if obj_uvw:
        if obj_uvw.GetType() != c4d.Opolygon:
            erreur(4)
            return False
    
    props = obj_3d.GetTags()
    props_uvw = []
    props_tex = []
    props_tex_tous = []
    props_sel = []
    prec = []
    for p in props:
        if p.GetType() == c4d.Tpolygonselection:
            props_sel.append(p)
        if p.GetType() == c4d.Ttexture:
            props_tex_tous.append(p)
            if p[c4d.TEXTURETAG_PROJECTION] == c4d.TEXTURETAG_PROJECTION_UVW:
                prec.append(p)
        if p.GetType() == c4d.Tuvw:
            props_uvw.append(p)
            props_tex.append(prec)
            prec = []
    if len(prec) > 0:
        if len(props_tex) == 0:
            props_tex.append(prec)
        else: props_tex[0].extend(prec)
    
    if dial.mode == 0: # Créer l'objet UVW
        if dial.proj == 0: # Projection UVW
            if len(props_uvw) == 0:
                erreur(2)
                return False
            for i in range(len(props_uvw)):
                creer_obj_uvw(props_uvw[i], props_tex[i], obj_3d, dial.proj, ech, props_sel, cadre)
        else:
            creer_obj_uvw(None, props_tex_tous, obj_3d, dial.proj, ech, props_sel, cadre)
    
    elif dial.mode == 1: # Créer la propriété UVW à partir de l'objet UVW
        creer_prop_uvw(obj_3d, obj_uvw, ech)
    
if __name__=='__main__':
    objetuvw()