Jump to content

Create object and Delete tag


Recommended Posts

Hello for everyone!

 

My aim to make a script which will create grey material tag for all nulls and objects. But i have some problems with it. I will write my code partly

 

FIRST PART - search same object, create texture tag.

Problem - 1) Everything is okey but i can't set corona render material for my texture tag. 2) Can't understand what should i write if i want insert my tag after all tags of object.(I know insert after command, but don't know how to use it correctly with tags)

 

# Search mat and create new mat
def main():

    # Variables assigment
    mat_name = 'all to grey'
    search_mat = doc.SearchMaterial(mat_name)
    new_mat = c4d.BaseMaterial(1032100)
    new_mat.SetName(mat_name)

    # Main code
    for obj in recur_iter(doc.GetFirstMaterial(),True):
        print obj.GetName()

        if search_mat == None:
            print 'TROUBLE'
            doc.InsertMaterial(new_mat)

    for obj in recur_iter(doc.GetFirstObject(),True):
        print obj.GetName() 
        tag = obj.MakeTag(c4d.Ttexture)
        tag.SetMaterial(new_mat)  #PROBLEM PLACE

    c4d.EventAdd()

if __name__=='__main__':
    main()

 

SECOND PART - remove created tags

Problem - In this case i can't understand how to find created texture tag name, and delete it after that. I'm using doc.SearchObject but it search name of tag in general. Its not a name of material.

 

# Search mat and create new mat
def main():

    # Создание переменных для кода
    mat_name = 'all to grey'
    search_mat = doc.SearchMaterial(mat_name)
    new_mat = c4d.BaseMaterial(1032100)
    new_mat.SetName(mat_name)

    for obj in recur_iter(doc.GetFirstObject(),True):
        for tag in recur_iter(obj.GetFirstTag()):
            print tag.GetName()
            if doc.SearchObject(mat_name) == None:
                print "Can't Find all to grey material"
            if doc.SearchMaterial(mat_name) == mat_name:
                print "WOW"

    c4d.EventAdd()

if __name__=='__main__':
    main()

 

Link to comment

What is recur_iter?

Are you aware that InsertMaterial() in your first code possibly executes as often as the loop loops?

new_mat is not guaranteed to be a part of the document when SetMaterial happens.

I'm not sure what your for loop even does, except printing a list of materials. The if conditional has a condition that is independent from the for loop.

If your material is already present in the scene, new_mat will not be added to the scene, and when it comes to SetMaterial(), you have a problem.

 

In your second code, why do you create a base material? You never use it.

Again, what is recur_iter? You seem to have left out parts of the code. I can only guess it iterates through a BaseList2D.

SearchObject(mat_name) searches an object with that name, I don't know whether that is what you want.

You do not test the type of the tag.

The material name is not in the tag. The tag contains a link to the material, which you must follow to find the material name.

Again, both if conditionals are misplaced in the double loop. The conditions don't seem to be connected to the for loops at all.

In the second if, you compare the result of SearchMaterial, which is a BaseMaterial, with a string. This will always return False.

 

If you want to identify the tag by name for simplicity's sake, then you forgot to set a name for the tag in the first code block.

 

Regarding InsertAfter(), you just need to pass the result from GetLastTag() on the object where you want to append the tag.

 

----------
Learn more about Python for C4D scripting:
https://www.patreon.com/cairyn

 

Link to comment
Quote

What is recur_iter?

 

Cairyn, at first thank you a lot for your answers! 

1) i forgot to add iteration method (recur_iter).

 

import c4d

def recur_iter(mat,deep=True):
    if mat:
        yield mat
        for x in recur_iter(mat.GetDown()):
            yield x
        if deep:
            for x in recur_iter(mat.GetNext()):
                yield x

 

 

2)

Quote

If your material is already present in the scene, new_mat will not be added to the scene, and when it comes to SetMaterial(), you have a problem.

Yes i didn't want to make a new material if i already have it.

 

 

3)  I wrote my code partly because i dont understand yet how to create def function in c4d. That's why i made a copy the first part of first code in second one. 

Quote

In your second code, why do you create a base material? You never use it.

 

4)  Is it the easiest way to add tag at last position? https://developers.maxon.net/?p=904

 

 

Link to comment
2 hours ago, ROMAN ZHAMALETDINOV said:

 

Cairyn, at first thank you a lot for your answers! 

1) i forgot to add iteration method (recur_iter).

 

2)

Yes i didn't want to make a new material if i already have it.

 

3)  I wrote my code partly because i dont understand yet how to create def function in c4d. That's why i made a copy the first part of first code in second one. 

 

4)  Is it the easiest way to add tag at last position? https://developers.maxon.net/?p=904

 

 

 

1) I have the feeling that the parameter is either named wrongly, or the condition in the code is set wrongly - deep is tested before going through the following nodes, not the actual children which would be "deeper" (but I'm nagging; it doesn't change the functionality)

 

2) okay, but look at what happens to new_mat in this case: it will be a free-floating object, never Inserted into the scene. So when you get to SetMaterial, you're linking to an object that is not even in the scene! You need to make sure that InsertMaterial is always called, OR that the object you use in SetMaterial is actually already in the scene (which would be search_mat, NOT new_mat if the material already existed.

 

    mat_name = 'all to grey'
    search_mat = doc.SearchMaterial(mat_name)
    if search_mat == None:
        new_mat = c4d.BaseMaterial(1032100)
        new_mat.SetName(mat_name)
        doc.InsertMaterial(new_mat)
    else:
        new_mat = search_mat

 

This code ensures that new_mat is always defined. Either it is the material that already exists (in the else case), or it is a new material. (You need to set the material's parameters here, of course.)

You do not need the for loop over the materials, that makes no sense since SearchMaterial already loops over all materials.

After that, you can go through your objects and set the material tags accordingly. (You will need to look for existing material tags, of course, or else all objects will get a new tag.)

 

3) This looks like two scripts anyway, and you cannot reuse functions across scripts unless you define a module of your own.

Anyway, you are using Search functions inside the double loop; what you really need to do is to compare the properties of the loop variable tag against your condition.

 

4) There is a function GetLastTag(), but I don't know whether this is already present in the R18 API which you set as your current version. You may need to look up the functionality in your version in the documentation. But you can use the code in the link as well.

Link to comment
×
×
  • Create New...

Copyright Core 4D © 2023 Powered by Invision Community