Image2Vertex map

On 08/06/2015 at 16:39, xxxxxxxx wrote:

Because i get so much help in the internet I want to share my plugin here.
I used code fragments from here and there...
It is a Bitmap to Vertexmap helper.
The Script load a Bitmap from a texture tag. From color channel or alpha channel, or from a seperate file.
Then it convert the bitmap to a vertexmap.

Code is comment in german.

Maybe someone helps:
http://www.total3d.de/?page_id=550

Code can surely be much better. (Like my english)
But it works ;-)

  
import c4d   
import os   
from c4d import bitmaps, storage   
from c4d import utils,gui   
from c4d.gui import GeDialog   
from c4d.modules import render   
import math   
  
  
chlist = []   
scaleart = 0   
button = 0   
alpha = 0   
orig = bitmaps.BaseBitmap()   
objekttext = ""   
showo = False   
shows = False   
bitmapfile = ""   
  
  
# Dialog erstellen   
class Dialog(GeDialog) :   
    global objekttext, showo, shows   
    def __init__(self) :   
        pass   
       
    # Layout definieren   
    def CreateLayout(self) :   
        # Objektname in Beschreibungstext einfügen   
        objekttext = "Selected object is: "+op.GetName()   
        self.SetTitle("RenameTexture")    # Titel definieren   
          
        self.GroupBegin(1000,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,0,8)   
        self.AddStaticText(1001,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"This is a simple image to vertex map converter!",0);   
        self.AddStaticText(1007,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"Use at your own risk - Please save Document before use!",0);   
        self.AddSeparatorH(0,c4d.BFV_FIT)   
        self.AddStaticText(1009,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"1) Please select an object.",0);   
        self.AddStaticText(1011,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"2) Plugin use the first uvw tag of the select polygon object.",0);   
        self.AddStaticText(1012,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"3) Please select a textur tag at the object.",0);   
        self.AddStaticText(1012,c4d.BFH_CENTER|c4d.BFH_SCALE|c4d.BFH_FIT,800,10,"4) Choose a button for use color map, alpha map or load a bitmap file.",0);   
        self.AddSeparatorH(0,c4d.BFV_FIT)   
        self.GroupEnd()   
  
        self.GroupBegin(1010,c4d.BFH_LEFT,1,1)   
        self.AddStaticText(1008,c4d.BFH_LEFT,800,10,objekttext,0);   
        self.AddSeparatorH(0,c4d.BFV_FIT)   
        self.GroupEnd()   
        self.GroupBegin(1010,c4d.BFH_LEFT,2,4)   
        self.AddCheckbox(1003,c4d.BFH_LEFT,10,10,"Bitmap COLOR Channel\n To Vertex Map!")   
        self.AddStaticText(1012,c4d.BFH_LEFT,800,10,"Show Bitmap in the picture manager",0);   
        self.AddCheckbox(1004,c4d.BFH_LEFT,10,10,"Bitmap COLOR Channel\n To Vertex Map!")   
        self.AddStaticText(1014,c4d.BFH_LEFT,800,10,"Show scaled bitmap in picture manager",0);   
        self.GroupEnd()   
  
        self.GroupBegin(1000,c4d.BFH_LEFT|c4d.BFH_SCALE|c4d.BFH_FIT,1,3)   
        self.AddStaticText(1001,c4d.BFH_LEFT,800,10,"How much scale the bitmap before check color :",0);   
        self.AddEditSlider(1002,c4d.BFH_LEFT|c4d.BFH_SCALE|c4d.BFH_FIT, 10, 0)         
        self.GroupEnd()   
  
        self.AddSeparatorV(0,c4d.BFV_FIT)   
          
        self.GroupBegin(1020,c4d.BFV_CENTER,3,1)   
        self.AddButton(1022,c4d.BFH_CENTER,0,40,"Bitmap COLOR Channel\n To Vertex Map!")   
        self.AddButton(1023,c4d.BFH_CENTER,0,40,"Bitmap ALPHA Channel\n To Vertex Map!")   
        self.AddButton(1024,c4d.BFH_CENTER,0,40,"Load a Bitmap File\n To Vertex Map!")   
        self.GroupEnd()   
        return True   
  
       
    # Dialog Verarbeitung definieren   
    def Command(self,id,msg) :   
        global chlist, scaleart, orig, alpha, button, showo, shows, bitmapfile   
          
        button = id    # Variable button für Benutzung im Hauptprogramm speichern   
        if(id < 1002 or id > 1005) :# Wurde nur der Slider, oder die Checkboxen verändert? Dann mit True zurückgeben   
            if(id == 1022 or id == 1023) : # Button links oder mitte (Color oder Alpha) wurde gedrückt   
               # Button 1 (Alpha Channel) gedrückt   
               if (id == 1023) : alpha = 1                 
               #Scalierungs Slider speichern   
               scaleart = int (self.GetReal(1002) * 0.1)       
               showo= self.GetBool(1003)          
               shows= self.GetBool(1004)          
               self.Close()    # Fenster schließen und weiter im Hauptprogramm   
               return True   
            else:   
               if (id == 1024) :# Der Button rechts für die Datei-Auswahl wurde gedrückt   
                    # Datei-Dialog öffnen   
                    bitmapfile = c4d.storage.LoadDialog (type=c4d.FILESELECTTYPE_IMAGES, title="Select a bitmap file for mapping!", flags=c4d.FILESELECT_LOAD)   
                    if not bitmapfile:   
                        gui.MessageDialog("no File loading!")   
                        return False   
                    scaleart = int (self.GetReal(1002) * 0.1)       
                    showo= self.GetBool(1003)          
                    shows= self.GetBool(1004)      
                    self.Close()   
                    return True   
               else:   
                    self.Close()   
                    return False   
        return True   
  
  
  
  
def main() :   
    # globale Variablen übernehmen   
    global scaleart, orig, alpha, button, showo, shows, bitmapfile   
  
    c4d.CallCommand (13957) # Pythonkonsole leeren   
       
    # Objekt ausgewählt? Sonst Fehlerausgabe und beenden   
    if not op:   
        gui.MessageDialog("Please select a object!")   
        return False                        # EXIT   
       
    # Prüfen ob das Objekt ein Polygonobjekt ist   
    if (op.GetType()== 5100) :           # 5100 ist der Type für das Polygonobjekt   
        print   
    else:   
        gui.MessageDialog("ERROR - Object is not a polygon object?")   
        return False   
          
    # Erstes UVTag auslesen   
    uvtag = op.GetTag(c4d.Tuvw)   
    # Kein UVW Tag? Sonst Fehlerausgabe und beenden   
    if not uvtag:   
        gui.MessageDialog("Please assign UVW to the object")   
        return   
       
    # Dialog aufrufen   
    dlg = Dialog();   
    dlg.Open(c4d.DLG_TYPE_MODAL)   
    if (button == 0) : return False    # Kein Button gedrückt (z.B. beim Fenster schließen über Fensterelement X)   
       
    # Bitmap Variablen vorbereiten   
    smallbitm = bitmaps.BaseBitmap()   
    bitmap = bitmaps.BaseBitmap()          
    bitmapPath = bitmapfile   
  
    if (button == 1024) :   
        abspath = bitmapfile   
        bitmapPath = bitmapfile   
    else:   
        # Selektiertes Tag auslesen   
        ttag = doc.GetActiveTag()   
        if (not ttag or not ttag.CheckType(c4d.Ttexture) ) : # Falls kein Material Tag vorhanden oder/und ausgewählt - abbrechen   
            gui.MessageDialog("Please attach AND SELECT a Material to the object!")   
            return False   
  
        # Material der Variable mat zuweisen   
        mat = ttag.GetMaterial()   
       
        # Kein Material übernehmen können? Dann Fehlerausgabe und beenden   
        if not mat:   
            gui.MessageDialog("Please attach a Material with simple bitmap in color Channel to the object!")   
            return False # EXIT   
  
        # Farbkanal auslesen falls Variable alpha = 0 (Button links gedrückt)   
        if (alpha == 0) :   
            if (mat[c4d.MATERIAL_USE_COLOR] == True) : # ist der Color kanal des Materials aktiv?   
               shader = mat[c4d.MATERIAL_COLOR_SHADER] # dann Shader auslesen   
            else:   
               gui.MessageDialog("Miss COLOR Channel!")   
               return False # Exit   
        # Alphakanal auslesen falls Variable alpha = 1 (Button mitte gedrückt)   
        if (alpha == 1) :   
            if (mat[c4d.MATERIAL_USE_ALPHA] == True) : # ist der Alpha kanal des Materials aktiv?   
               shader = mat[c4d.MATERIAL_ALPHA_SHADER] # dann Shader auslesen   
            else:   
               gui.MessageDialog("Miss ALPHA Channel!")   
               return False # Exit   
          
        # Farbkanal / Alphakanal konnte nicht gelesen werden?   
        if shader is None:   
            if (alpha == 0) : gui.MessageDialog("Can't get the Shader!\nPlease check that the COLOR Channel is not empty!")   
            if (alpha == 1) : gui.MessageDialog("Can't get the Shader!\nPlease check that the ALPHA Channel is not empty!")   
            return False # EXIT   
          
          
        # Shader vor dem auslesen erst abrufbar machen!!!   
        bitmapPath = shader[c4d.BITMAPSHADER_FILENAME]   
        # Shadertyp und Filename bei Bitmapshader auslesen   
        name, path = shader.GetName(), shader[c4d.BITMAPSHADER_FILENAME]   
               
        #if bitmapPath is´nt absolute   
        if not os.path.dirname(bitmapPath) :   
            #the document has´nt been saved already ->picture in user library   
            if not doc.GetDocumentPath() :   
               abspath= c4d.storage.GeGetStartupWritePath()+"/"+"tex"+"/"+bitmapPath   
            #the picture should be inside the asset´s texture folder       
            else:   
               abspath= doc.GetDocumentPath()+"/"+bitmapPath   
        else:   
            abspath = bitmapPath   
  
       
       
    #   
    if op is not None:       
          
        # Bitmap mit vollem Pfad und Dateinamen Initialisieren:   
        result = bitmap.InitWith(abspath)   
  
        if (button <> 1024) : irs = render.InitRenderStruct()   
        else: irs = True   
        if (button <> 1024) : shader.InitRender(irs)   
        if irs:   
  
               
            # Bitmapdateien in Shadern können absolut oder relativ gespeichert werden.   
            # Also muss geprüft werden ob der komplette Pfad ausgelesen wurde!   
  
  
            # Falls Bitmap ordnungsgemäß verarbeitet wurde:   
            if result:   
                 
               # Die Variable bitmap wurde jetzt auf eine von 3 Arten befüllt:   
               if bitmap is not None: # hats geklappt? Dann weiter:   
                    width, height = bitmap.GetSize()       # Pixel-Maße der Bilddatei auslesen   
                    bits = bitmap.GetBt()                  # Bittiefe auslesen   
                    pixelzahl = width*height               # Gesamtpixelanzahl ermitteln   
                    punktezahl = uvtag.GetDataCount()      # Punkteanzahl der UVW-Map ermitteln   
  
  
                    # Scalierung auf basis des Skalierungs-Sliders berechnen   
                    # Aufgrund der Differenz der Auflösung der Bilddatei   
                    # und der Auflösung des Polygonmesh (bzw. der UVW-Map)   
                    # berechnet sich die Scalierung der Bilddatei.   
                    # Die Bilddatei wird skaliert damit in einer hohen Bildauflösung   
                    # ein einzelner ausgerissener Pixel den Punkt in einem niedrig aufgelösen Mesh                        # nicht so stark beeinflusst beeinflusst. nur weil der UV-Punkt genau auf diesem Pixel liegt.   
                       
                    differenz = pixelzahl - punktezahl             # Differenz ermitteln   
                    if scaleart == 10: diffadd = float(differenz)/1000    # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 1000   
                    if scaleart == 9: diffadd = float(differenz)/500     # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 500   
                    if scaleart == 8: diffadd = float(differenz)/100      # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 100   
                    if scaleart == 7: diffadd = float(differenz)/50       # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 50                           
                    if scaleart == 6: diffadd = float(differenz)/20       # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 20   
                    if scaleart == 5: diffadd = float(differenz)/10       # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durh 10   
                    if scaleart == 4: diffadd = float(differenz)/5        # Neue Bildgröße = Anzahl der Punkte der UV-Map + Differenz geteilt durch 5   
                    if scaleart == 3: diffadd = float(differenz)/3        # Neue Bildgröße = Anzahl der Punkte der UV-Map + ein Drittel der Differenz   
                    if scaleart == 1: diffadd = float(differenz)/2        # Neue Bildgröße = Anzahl der Punkte der UV-Map + die Hälfte der Differenz   
                    if scaleart == 2: diffadd = float((differenz/3))*2    # Neue Bildgröße = Anzahl der Punkte der UV-Map + Zwei Drittel der Differenz   
                    if scaleart == 0: diffadd = differenz          # Neue Bildgröße = Anzahl der Punkte der UV-Map + komplette Defferenz - Also volle Auflösung!   
  
                    # Geladenes Bild bestimmt das Seitenverhältnis. Anhand der alten Menge an Pixel,   
                    # der zur Verfügung stehenden Punkte im UV-Mesh und dem Grad der Skalierung (Slider)   
                    # wird die neue Bildgröße berechnet. mit gleich bleibenden Seitenverhältnis.   
  
                    # Scalierungsfaktor berechnen: Punkte+Pixelreduzierung geteilt durch Pixelanzahl   
                    scalefaktor = float(punktezahl+diffadd) / (pixelzahl)   
                    # Anhand des Skalierungsfaktors der Fläche die Seitenlängen berechnen                           
                    scale_width = int(width * math.sqrt(scalefaktor))              
                    scale_height = int(height * math.sqrt(scalefaktor))   
                                                  
  
                    # Kleinere Version der Bitmap erstellen   
                    smallbitm.Init(scale_width, scale_height, bits)    # Kleinere Maße, gleiche Bittiefe, gleiches Seitenverhältnis   
  
                    # Copy&Scale; Original Bitmap zu Kleine Bitmap   
                    bitmap.ScaleBicubic(smallbitm, 0, 0, width-1, height-1, 0, 0, scale_width-1, scale_height-1)   
                       
                    if (showo == True) : bitmaps.ShowBitmap(bitmap)   
                    if (shows == True) : bitmaps.ShowBitmap(smallbitm)   
                    bitmap = smallbitm   
  
               else:   
                    gui.MessageDialog("Bitmap-Error")   
                    return False   
  
               if (button <> 1024) : shader.FreeRender()   
                 
               # Abbrechen falls Bitmap nicht übergeben werden konnte   
               if bitmap is None:   
                    gui.MessageDialog("Bitmap can't load")   
                    return False   
                           
            else:   
               # Im Kanal steckt keine einfache Bitmap-Datei. Wahrscheinlich ein prozeduraler Shader, oder Ebenen ect.   
               gui.MessageDialog("In channel ist not a simple bitmap")   
               return False                           # EXIT   
                 
            # Es wird eine Vertexmap erstellt die gleichviele Punkte enthält wie das Polygonobjekt   
            vtag = c4d.VariableTag(c4d.Tvertexmap, op.GetPointCount())   
            bitmap_w = bitmap.GetBw()              # Breite der Bitmap auslesen   
            bitmap_h = bitmap.GetBh()              # Höhe der Bitmap auslesen   
            pixel = (bitmap_w * bitmap_h)          # Pixelanzahl des Skalierten Bildes   
            points = uvtag.GetDataCount()          # Punktanzahl des UVW-Tags   
            if (op.GetPointCount() > 0) :           # Prüfen ob das Objekte Punkte zum auslesen hat   
               vertexList = op.GetPointCount() * [0] # Die Variable für die Vertagsmap-Befüllung mit der Anzahl an Punkten des selektierten Objektesvorbereiten   
            else:   
               gui.MessageDialog("Object have no read able points! Is it a polygon object?")   
               return False   
               
            # Schleife liest jedes UVW-tag Polygon aus. Ein Punkt eines UVW-Tags kann mehreren Polygonobjekt-Punkten zugewisen sein   
            # Es wird der Reihe nach jedes UV-Polygon ausgelesen. Dann wird das zugehörige Polygon des Objektes ausgelesen und   
            # dessen Punkte mit den Farbwerten der Bitmap gefüllt. Die Anzahl der Polygonpunkte müssen nämlich gleich sein mit der Anzahl der Vertexmap-Punkte   
               
            # Laut Wiki: Grauwert = 0,299 × Rotanteil + 0,587 × Grünanteil + 0,114 × Blauanteil   
               
            for i in xrange(uvtag.GetDataCount()) : # Schleife durchläuft Polygone des UVW-Tag   
                    uvwdict = uvtag.GetSlow(i)     # UVW-Polygon wird eingelesen   
                    objpolygon = op.GetPolygon(i) # Objekt-Polygon wird eingelesen   
                    point_a = op.GetPoint(objpolygon.a) # Objekt Polygon-PunktA ID wird ausgelesen   
                    point_b = op.GetPoint(objpolygon.b) # Objekt Polygon-PunktB ID wird ausgelesen   
                    point_c = op.GetPoint(objpolygon.c) # Objekt Polygon-PunktC ID wird ausgelesen   
                    point_d = op.GetPoint(objpolygon.d) # Objekt Polygon-PunktD ID wird ausgelesen   
                    u = uvwdict["a"].x                  # UVW-Koordinate des Punktes A wird ermittelt   
                    v = uvwdict["a"].y                  # UVW-Koordinate des Punktes A wird ermittelt   
                    w = uvwdict["a"].z   
                    ux = bitmap_w*u                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildbreite multipliziert   
                    uy = bitmap_h*v                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildhöhe multipliziert   
                    color = bitmap.GetPixel(int(ux), int(uy))   
                    # "ubjektiver" Helligkeitswert aus RGB ermitteln   
                    weight_a = 0.299 * (float(color[0])/256) + 0.587 * (float(color[1])/256) + 0.114 * (float(color[2])/256)   
  
                    u = uvwdict["b"].x                  # UVW-Koordinate des Punktes B wird ermittelt   
                    v = uvwdict["b"].y                  # UVW-Koordinate des Punktes B wird ermittelt   
                    w = uvwdict["b"].z   
                    ux = bitmap_w*u                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildbreite multipliziert   
                    uy = bitmap_h*v                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildhöhe multipliziert   
                    color = bitmap.GetPixel(int(ux), int(uy))   
                    # "ubjektiver" Helligkeitswert aus RGB ermitteln   
                    weight_b = 0.299 * (float(color[0])/256) + 0.587 * (float(color[1])/256) + 0.114 * (float(color[2])/256)   
  
                    u = uvwdict["c"].x                  # UVW-Koordinate des Punktes C wird ermittelt   
                    v = uvwdict["c"].y                  # UVW-Koordinate des Punktes C wird ermittelt   
                    w = uvwdict["c"].z   
                    ux = bitmap_w*u                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildbreite multipliziert   
                    uy = bitmap_h*v                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildhöhe multipliziert   
                    color = bitmap.GetPixel(int(ux), int(uy))   
                    # "ubjektiver" Helligkeitswert aus RGB ermitteln   
                    weight_c = 0.299 * (float(color[0])/256) + 0.587 * (float(color[1])/256) + 0.114 * (float(color[2])/256)   
  
                    u = uvwdict["d"].x                  # UVW-Koordinate des Punktes D wird ermittelt   
                    v = uvwdict["d"].y                  # UVW-Koordinate des Punktes D wird ermittelt   
                    w = uvwdict["d"].z   
                    ux = bitmap_w*u                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildbreite multipliziert   
                    uy = bitmap_h*v                     # UV-Koordinate liegt zwischen 0-1 und wird mit der Bildhöhe multipliziert   
                    color = bitmap.GetPixel(int(ux), int(uy))   
                    # "ubjektiver" Helligkeitswert aus RGB ermitteln   
                    weight_d = 0.299 * (float(color[0])/256) + 0.587 * (float(color[1])/256) + 0.114 * (float(color[2])/256)   
  
                    # Helligkeitswerte der Vertexmap Wert-Variable zuweisen   
                    vertexList[objpolygon.a] = weight_a   
                    vertexList[objpolygon.b] = weight_b   
                    vertexList[objpolygon.c] = weight_c   
                    vertexList[objpolygon.d] = weight_d   
                           
            if vtag: # falls die Vertexmap auch wirlich erstellt wurde kann es weiter gehen:   
               op.InsertTag(vtag) # Vertexmap wird an dem objekt erstellt   
  
               vtag.SetAllHighlevelData(vertexList) # erstellte Vertexmap wird mit den ermittelten Werten gefüllt   
                           
            c4d.EventAdd() # Veränderung in der Szene mitteilen, damit C4D aktualisiert.   
        else:   
            # Das Vorbereiten der Bitmapinitialisierung hat fehlgeschlagen:   
            gui.MessageDialog("Can Not Init Shader")   
            if irs == c4d.INITRENDERRESULT_OUTOFMEMORY: gui.MessageDialog("Out Of Memory")   
            if irs == c4d.INITRENDERRESULT_ASSETMISSING: gui.MessageDialog("Texture Not Assigned")   
            if irs == c4d.INITRENDERRESULT_UNKNOWNERROR: gui.MessageDialog("Unknown Error")   
            if irs == c4d.INITRENDERRESULT_THREADEDLOCK: gui.MessageDialog("Threaded Lock")   
          
        gui.MessageDialog(" - Finish - ")   
  
if __name__=='__main__':   
    main()   
  

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

Hi,

thanks for sharing!
As I wrote a similar plugin, last year, for an in house production I want to ask if you feel like working together and publish an optimized version with a few more features?
If so, feel free to send me a pm.

Best wishes
Martin

On 09/06/2015 at 08:11, xxxxxxxx wrote:

Hello,

thank you for sharing your work!

Best wishes,
Sebastian