Plugin Cafe Homepage
Forum Home Forum Home > Plugin Cafe > PYTHON Development
  New Posts New Posts
  FAQ FAQ  Forum Search

Set Texture by script

Author
Message
  Topic Search Topic Search
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Topic: Set Texture by script
    Posted: 2011 Oct 26 at 1:58am
Is there any chance to change the texture file by script? I import models from a 3D-Scanner. On import there are texture groups but noe texture file is assigned.
The groups are named "texture_group_0", "texture_group_1" ...
The texture files are named "texture_0", "texture_1"...
If I set the texture_0 to texture_group_0 and so on it's ok. But there are many texture_groups. Is there any way to assign them automatically.
Back to Top
NiklasR View Drop Down
Member
Member


Joined: 2010 Dec 13
Location: Germany
Online Status: Offline
Posts: 2575
Direct Link To This Post Posted: 2011 Oct 26 at 7:09am
Do you mean with "texture groups" a null-object that groups objects with the same texture ?
There are many possible ways to solve this.

Let's say all your objects are at top level of the document and that the path to the textures is C:/Textures/3DScanner/.

#note: you do not have to adapt my coding-style
#      like the indentation of assignment operators, etc.

import  os
import  c4d

myObjects       = doc.GetObjects()
pathToTextures  = r"C:\Textures\3DScanner"
fileExtension   = ".jpg"

def main():
    # go through the list and to the stuff with
    # every object in it
    for obj in myObjects:
        # get the name of the object
        name        = obj.GetName()

        # arrange the new name by replacing
        # every `_group` with just nothing ``.
        textureName = name.replace( "_group", "" )

        # concetenate the path to textures with the name
        # of the texture
        # we use `os.path` because it adapts the operating
        # systems way to deal with pathnames
        fullPath    = os.path.join( pathToTextures, textureName )

        # we need the original texturename, so we add the
        # file extension now
        fullPath    = fullPath + fileExtension

        # check if the texture exists
        if not os.path.exists( fullPath ):
            # tell that the object could not be associated
            # with a texture
            print "Texture could not be found:", fullPath
        else:
            # create a standart material for the texture
            mat     = c4d.BaseMaterial(c4d.Mmaterial)
            mat.SetName( textureName )

            # create a shader for the material
            sha     = c4d.BaseList2D(c4d.Xbitmap)
            sha[c4d.BITMAPSHADER_FILENAME]  = fullPath
            mat.InsertShader( sha )
            mat[c4d.MATERIAL_COLOR_SHADER]  = sha

            # update the material
            mat.Message( c4d.MSG_UPDATE )
            mat.Update( True, True )

            # insert the material into the document
            doc.InsertMaterial( mat )

            # create a texturetag and insert the material
            tag     = c4d.BaseTag( c4d.Ttexture )
            tag[c4d.TEXTURETAG_MATERIAL]    = mat

            # assign the tag to the object
            obj.InsertTag(tag)

    # update the Cinema 4D UI
    c4d.EventAdd()

    # tell that the processing was finished
    print "Finished processing."

main()


Cheers, Niklas


Edited by nux95 - 2011 Oct 26 at 7:10am
Back to Top
rne View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 4
Direct Link To This Post Posted: 2011 Oct 26 at 2:20pm
If I read this correctly then you create a new material first.
Is there also a way to change the texture in an already exsisting material?
Greets Ronnie
Back to Top
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Posted: 2011 Oct 26 at 10:49pm
Originally posted by rne

If I read this correctly then you create a new material first.
Is there also a way to change the texture in an already exsisting material?
Greets Ronnie

Thanks, you understood my problem. The texture groups are existing. I have to assign the files to the existing texture groups.
Back to Top
NiklasR View Drop Down
Member
Member


Joined: 2010 Dec 13
Location: Germany
Online Status: Offline
Posts: 2575
Direct Link To This Post Posted: 2011 Oct 27 at 6:32am
Use
doc.SearchMaterial(name)

to find a material by name.


Edited by nux95 - 2011 Oct 27 at 10:25pm
Back to Top
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Posted: 2011 Oct 28 at 1:41am
Thanks to all. I solved the problem. Here is my final script:

import c4d
from c4d import gui
from c4d import storage
import  os
#Welcome to the world of Python

myMaterials       = doc.GetMaterials()
fileExtension   = ".jpg"

def main():
    pathToTextures = c4d.storage.LoadDialog(0,"Texturpfad wählen",2)
    for mat in myMaterials:
        name        = mat.GetName()

        # arrange the new name by replacing
        # every `_group` with just nothing ``.
        textureName = name

        # arrange the new name by replacing
        # every `_group` with just nothing ``.
        textureName = name.replace( "material_", "texture_" )
       
        # concetenate the path to textures with the name
        # of the texture
        # we use `os.path` because it adapts the operating
        # systems way to deal with pathnames
        fullPath    = os.path.join( pathToTextures, textureName )

        # we need the original texturename, so we add the
        # file extension now
        fullPath    = fullPath + fileExtension
       
        # check if the texture exists
        if not os.path.exists( fullPath ):
            # tell that the object could not be associated
            # with a texture
            print "Texture could not be found:", fullPath
        else:
            # create a shader for the material
            sha     = c4d.BaseList2D(c4d.Xbitmap)
            sha[c4d.BITMAPSHADER_FILENAME]  = fullPath
            mat.InsertShader( sha )
            mat[c4d.MATERIAL_COLOR_SHADER]  = sha

            # update the material
            mat.Message( c4d.MSG_UPDATE )
            mat.Update( True, True )           

    # update the Cinema 4D UI
    c4d.EventAdd()

    # tell that the processing was finished
    print "Finished processing."               
    gui.MessageDialog("Finished processing.")

if __name__=='__main__':
    main()

But there are two new questions.
1. If I look into the documentation the function GetMaterials is in the namespace c4d.documents.BaseDocument. But if I use this namespace the command could not be found. Why and from where I can know the namespace doc? I got it from the script above.

2. In the documentation for the command LoadDialog is written about constants like FILESELECT_DIRECTORY. But it isn't known by the interpreter. Where are they defined and what I have to import that it works?
Back to Top
Yannick Puech View Drop Down
Forum Moderator
Forum Moderator


Joined: 2011 Apr 13
Location: Spain
Online Status: Offline
Posts: 1143
Direct Link To This Post Posted: 2011 Oct 28 at 2:43am
1. c4d.documents.BaseDocument isn't a namespace, it's a class representing a C4D document. To get the current document as doc:
from c4d import documents
...
doc = documents.GetActiveDocument()

2. FILESELECT_DIRECTORY and all the constants are defined in the c4d namespace : for example c4d.FILESELECT_DIRECTORY.

MAXON
Developer Support
Back to Top
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Posted: 2011 Oct 28 at 4:46am
As you see in my sourcecode I have never declared doc but it works. Is it declared implicit? I've found nothing in the documentation about it.
Back to Top
Yannick Puech View Drop Down
Forum Moderator
Forum Moderator


Joined: 2011 Apr 13
Location: Spain
Online Status: Offline
Posts: 1143
Direct Link To This Post Posted: 2011 Oct 28 at 5:11am
Originally posted by Klaus

As you see in my sourcecode I have never declared doc but it works. Is it declared implicit? I've found nothing in the documentation about it.
Yes, everywhere in the code, 'doc' is the current document and 'op' is the current activate object. I'll add this to the docs.




Edited by Yannick Puech - 2011 Oct 28 at 5:15am
MAXON
Developer Support
Back to Top
NiklasR View Drop Down
Member
Member


Joined: 2010 Dec 13
Location: Germany
Online Status: Offline
Posts: 2575
Direct Link To This Post Posted: 2011 Oct 28 at 5:18am
You don't seem to understand that I have written the code above just for you, and not just because I'm so bored. I don't think many other people would have done this for you.
At least some sort of thank you in your second post would have been appropriate rather than to complain it is not exactly the way you need it.
Back to Top
Yannick Puech View Drop Down
Forum Moderator
Forum Moderator


Joined: 2011 Apr 13
Location: Spain
Online Status: Offline
Posts: 1143
Direct Link To This Post Posted: 2011 Oct 28 at 6:20am
Originally posted by nux95

You don't seem to understand that I have written the code above just for you, and not just because I'm so bored. I don't think many other people would have done this for you.
At least some sort of thank you in your second post would have been appropriate rather than to complain it is not exactly the way you need it.
I think you posted the code in the wrong topic...
The topic about finding a material by name is this one : http://www.plugincafe.com/forum/forum_posts.asp?TID=6267

MAXON
Developer Support
Back to Top
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Posted: 2011 Oct 28 at 6:20am
As you can see I used the most of your script in my solution. The only difference is that I had already materials and would like to edit them and the dynamic selection of the texture path.
Many thanks for your scriptClap Without it I wasn't able to solve the problem.

I'm sorry, if it seems that I'm not thankful to you.Embarrassed
Back to Top
Yannick Puech View Drop Down
Forum Moderator
Forum Moderator


Joined: 2011 Apr 13
Location: Spain
Online Status: Offline
Posts: 1143
Direct Link To This Post Posted: 2011 Oct 28 at 6:33am
Originally posted by Yannick Puech

I think you posted the code in the wrong topic...
The topic about finding a material by name is this one : http://www.plugincafe.com/forum/forum_posts.asp?TID=6267
Sorry, I didn't understand your previous post but the code you posted later was quite confusing Confused:



Edited by Yannick Puech - 2011 Oct 28 at 6:34am
MAXON
Developer Support
Back to Top
Klaus View Drop Down
Member
Member


Joined: 2011 Oct 26
Online Status: Offline
Posts: 9
Direct Link To This Post Posted: 2011 Nov 01 at 11:41pm
I'm sorry. My reply applies to the post from nux95.
Originally posted by nux95

You don't seem to understand that I have written the code above just for you, and not just because I'm so bored. I don't think many other people would have done this for you.
At least some sort of thank you in your second post would have been appropriate rather than to complain it is not exactly the way you need it.
Back to Top

Forum Jump Forum Permissions View Drop Down

Bulletin Board Software by Web Wiz Forums® version 9.61 [Free Express Edition]
Copyright ©2001-2009 Web Wiz

This page was generated in 0.109 seconds.