Rename by adding a digit at the end
On 31/10/2015 at 15:47, xxxxxxxx wrote:
Is it possible to do that:
I wish when I clicked on the button "Insert Object" I create an null object then I rename it with new name by adding a digit at the end.
I would like to simply that this 1 increases each time when i click on "Insert Object" buttun. And check if the name exists or not.
def main() :
Data = doc.SearchObject("UserData")
insert = Data[c4d.ID_USERDATA,1]
Null = c4d.BaseObject(5140)
i = 1
if insert == 1:
Null.SetName('Name.' + str(i))
Data[c4d.ID_USERDATA,1] = 0
On 01/11/2015 at 02:30, xxxxxxxx wrote:
Global variables (for the counter) are discouraged, so you would need to store the counter in the tag's BaseContainer instead of in the code.
But in general, if you are checking "whether the name exists", the more practical method would be this:
- Go through the objects to check (whether they are in a certain list or anywhere in the scene)
- Find the suffix number for each
- Find the maximum of these suffix numbers
- Add 1
- Create the new object with this number (which is then 1 higher than any previously used number)
This way, you wouldn't need to store the suffix number anywhere because it is determined dynamically, and you automatically use a new number.
(Gaps in the current numbering wouldn't be considered, e.g. if you have name.1, name.2, name.4 then the next generated name would be name.5 although name.3 is not used yet. You can change the algorithm to do that, though.)
Oh, and you don't want to put all that into main() but create a message responder, see here:
On 01/11/2015 at 11:44, xxxxxxxx wrote:
Many thanks for your response, which I thought was Relevant.
I have not understand too well the part concerning "message responder" i am beginner in python :).
For the moment I would settle to rename and add incrementing number suffix.
I am arrive at this result:
import c4d def main() : Data = doc.SearchObject("UserData") Name = doc.SearchObject("Name.1") if Name == None: Name = "name.0" else : Name = doc.GetFirstObject().GetName() insert = Data[c4d.ID_USERDATA,1] Null = c4d.BaseObject(5140) if insert == 1: degit = int(filter(str.isdigit, Name))+1 doc.InsertObject(Null) Null.SetName('Name.' + str(degit) ) Data[c4d.ID_USERDATA,1] = 0
_<_span style=": rgba220, 220, 220, 0.5 "//www.c4dcafe.com/ipb/applications/core/interface/ckeditor/ckeditor/plugins/widget/s/handle.png" repeat scroll 0% 0%; top: -15px; left: 0px; display: block;" ="cke_="" cke_widget_drag_handler_container"=""_>_
It remains for me that this problem that you Mentioned in this example:
(if I have name.1, name.2, name.4 then the next generated name would be name.5)
On 01/11/2015 at 19:26, xxxxxxxx wrote:
I find a solution concerning the probleme Mentioned above
import c4d def main() : Data = doc.SearchObject("UserData") Name = doc.SearchObject("Name.1") if Name == None: Name = "name.0" else : Name = doc.GetFirstObject().GetName() insert = Data[c4d.ID_USERDATA,1] Null = c4d.BaseObject(5140) if insert == 1: degit = int(filter(str.isdigit, Name))+1 doc.InsertObject(Null) Null.SetName('Name.' + str(degit)) **for i in list(reversed(range(100))) : obj = doc.SearchObject('Name.' + str(i)) if obj == None: Null.SetName('Name.' + str(i))** Data[c4d.ID_USERDATA,1] = 0
Cinema 4D File
On 02/11/2015 at 02:02, xxxxxxxx wrote:
looking at your code it might be the easiest thing to use a script in the script manger. Then you would not have to try to capture the user data button click.
On 02/11/2015 at 03:44, xxxxxxxx wrote:
However, if you want that button, here's what a message responder does.
You need to have a method "message", which receives all the messages sent to objects. There, you check for the right type of message, the button type, and finally the id of this button. If all of this identifies the proper message that you want to respond to, you insert your responder code.
(In more complicated examples that need to react to many different messages, the responder code would probably be a separate method again, but since you only listen for a single message, you can insert it right there...)
import c4d def message(id,data) : if id == c4d.MSG_DESCRIPTION_CHECKUPDATE: # check if button if data["descid"].dtype == c4d.DTYPE_BUTTON: # get id buttonID = data["descid"].id if buttonID == 1 : print "Button!" # execute your code here def main() : pass # not needed because no execution is necessary
Now the main() function is empty (this is the "Execute" method of a tag in this case), and the responder returns early, which means it will only use as much calculation time as needed.
For the code above, the button needs to be in the UserData of the tag! Otherwise, the tag may not receive the message properly. In the link above from the other post, you will find a concept to receive the parent object's messages too; I'm not going to repeat it here.
Though, Sebastian is right, doing this as a command script seems more logical, since you could assign this to an icon and put that icon anywhere in the GUI, making it scene-independent.
On 02/11/2015 at 04:06, xxxxxxxx wrote:
Also, your name determination code has some issues.
First, you start the code with two SearchObject()s before you even check for the button. That means, you will have two all-over-the-tree searches going on every time the tag is executed, which is really inefficient (that's what I meant by "returns early" - don't perform operations whose results are abandoned afterwards).
Second, "Name" may be initialized as the name of the first object. Depending on what other objects you have in the tree in what places... If that name does not contain any digits that are extracted by "filter", the conversion to int will fail.
Third, please don't call a variable "Null", that irritates everyone who also programs C++ :-)
Fourth, your search for a free name is limited to 100 different names and performs 100 searches max, which is also pretty inefficient. Searching from the bottom and performing a break if a suitable free number is found is more reasonable.
You need to think about where you want to start the search and which objects you want to test (initial conditions) and then how you want to filter the numbers that were already used. Consider that your object tree may contain several branches, and that your Python tag may not be on the top level.
On 03/11/2015 at 19:46, xxxxxxxx wrote:
I begin this project by using the tag python and this project is almost completed. That is why I continue to use python tag, to respond to Sebastian .
The example that I use in this post is a bit broad, my project cannot support an unlimited number of copy, a dozen copies will suffice. I have taken on board your suggestion and I will give it further consideration for my futur project and look forward to it.
Thanks again for your help
Have a nice day!
On 31/12/2015 at 16:44, xxxxxxxx wrote:
Finally, I have finished this project, and I would like to share it with you.
is a new tool for Cinema 4D to create a folding text effect "Folding Title GENERATOR".
On 16/10/2016 at 10:47, xxxxxxxx wrote:
Sorry if this is a noob question, as I am new to python. How did you get this boolean Data Type, and a blank Interface. To make it a usable button? (Usable in the python tag)
On 16/10/2016 at 11:19, xxxxxxxx wrote:
If you have any questions. Create a new thread about it.
The support guys prefer you to start a new thread for each new question.