Jump to content

graphos

Maxon
  • Posts

    102
  • Joined

  • Last visited

Everything posted by graphos

  1. graphos

    How to hide User Data

    I suggest you to read https://www.cineversity.com/wiki/Python%3A_User_Data/ and https://developers.MAXON.net/docs/Cinema4DPythonSDK/html/modules/c4d/DescID/index.html?highlight=descid Basicly descId[1].id give us the current id of the userdata. So I check if this id is inside the list to hide, if it's inside the list to hide then I Hide this. For more optimization I suggest you to read this topic which can be very informative also http://www.plugincafe.com/forum/forum_posts.asp?TID=13629
  2. graphos

    How to hide User Data

    Here an exemple file for hidding DU in Xpresso (but you still need a python node for doing it ! :)) hide_DU.c4d
  3. I just wanted to add for people who keep saying new core doesn't coming, if you lok at the current sdk you will see a lot of function accept a thread as argument for being executed into another thread. Even if multi threaded doesn't mean multi processor, it's show us, MAXON try to parallelize their core, and it's a huge step for making it working into multiple processor ;)
  4. Basicly row["R.H"] get the content of the row R.H. According to your last information Ithinked the data into it was for exemple 90° and not 90. So Since we need number and I guess you understand ° is not a muber so I remove it. For removing it I simply do the content of row["R.H][:-1:] where [:-1] remove the last character. And then I convert everything to flaot, like that we are sure we get number. So basicly just change the line by r_h = float(row["R.H"]) and it should work
  5. If it just for file reading I really discourage you to use it. For make it to work you have to download it and put it into the user folder. (C:\Users\XXX\AppData\Roaming\MAXON\CINEMA 4D RXXX\library\python\packages\win64) but for make it work you also have to install all the dependancy (numpy and maybe some other...) Wich again it's pretty boring cause you have to compile numpy for your version. You can find some numpy version compiled by Nicklas but there a a bit outdated (not too much just 2/3 releae ahead of the current version of numpy) http://www.plugincafe.com/forum/forum_posts.asp?TID=13558 So it's a lot of work. And if you have to share your script thoses people will must need thoses files too. So it it's another "problem" of how to send this. So if it's just for reading file again do it directly with python struct it will be more easy for you if you are not confortable with module and other things ;)
  6. #CSV Importer exemple by graphos #12/07/2017 import c4d import csv def add_mesh(num, name, r_h, p_x, p_y, outer_radius): #Create obj in memory disc_obj = c4d.BaseObject(c4d.Odisc) poly_obj = c4d.BaseObject(5174) #Set obj names disc_obj.SetName("{}-Alpha {}".format(str(num).zfill(2), name)) poly_obj.SetName("{}-{}".format(str(num).zfill(2), name)) #Set disc_parameter disc_obj[c4d.PRIM_DISC_ORAD] = outer_radius disc_obj[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = r_h disc_obj[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = p_x disc_obj[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = p_y #remove visiblity for poly_obj and set with/height poly_obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1 poly_obj[c4d.PRIM_POLY_WIDTH] = 0.1 poly_obj[c4d.PRIM_POLY_HEIGHT] = 0.1 #insert disc into the doc doc.InsertObject(disc_obj) doc.AddUndo(c4d.UNDOTYPE_NEW, disc_obj) #insert poly_obj under disc poly_obj.InsertUnder(disc_obj) doc.AddUndo(c4d.UNDOTYPE_NEW, poly_obj) def main(): path = "F:\\test.csv" doc.StartUndo() with open(path, 'rb') as csv_file: readed = csv.DictReader(csv_file, delimiter=',') for i, row in enumerate(readed): try: name = str(row["ObjectName"]) r_h = float(row["R.H"][:-1]) #-1 for removing ° depand of the encoding of the file can be -2 p_x = float(row["P.X"]) p_y = float(row["P.Y"]) outer_radius = float(row["OuterRadius"]) except: print "Error while reading - {}".format(row) continue r_h = c4d.utils.Rad(r_h) #convert in radian since c4d handle rotation in radian add_mesh(i, name, r_h, p_x, p_y, outer_radius) c4d.EventAdd() doc.EndUndo() if __name__=='__main__': main() Here you got poly obj created and set to 0.1 height / weight
  7. Sometimes it's way more efficient to do thing dirtly :p Here is what you want in 3 min chrono ! :) http://recordit.co/RdoLnyjS32 I just change the script for make it save as obj instead of c4d files. import c4d import os def get_current_frame(): frame = int(doc.GetTime().GetFrame(doc.GetFps())) return str(frame).zfill(4) def save_obj(): save_path = "C:\\Users\graphos\\Desktop\\Nouveau dossier" path = str(os.path.join(save_path, "{}.obj".format(get_current_frame()))) c4d.documents.SaveDocument(doc, path,c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, 1030178) def main(): total_frame = 1 for i in xrange(total_frame): c4d.CallCommand(12236) # Make Editable save_obj() c4d.CallCommand(12105) # Undo c4d.CallCommand(12414) # Go to Next Frame c4d.EventAdd() if __name__=='__main__': main()
  8. Here a basic script. Note that there is no material asignation since I don't know if the script need to create them or grab it from the actual doc. #CSV Importer exemple by graphos #12/07/2017 import c4d import csv def add_mesh(num, name, r_h, p_x, p_y, outer_radius): #Create obj in memory disc_obj = c4d.BaseObject(c4d.Odisc) poly_obj = c4d.BaseObject(c4d.Opolygon) #Set obj names disc_obj.SetName("{}-Alpha {}".format(str(num).zfill(2), name)) poly_obj.SetName("{}-{}".format(str(num).zfill(2), name)) #Set disc_parameter disc_obj[c4d.PRIM_DISC_ORAD] = outer_radius disc_obj[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = r_h disc_obj[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = p_x disc_obj[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = p_y #remove visiblity for poly_obj poly_obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = 1 #insert disc into the doc doc.InsertObject(disc_obj) doc.AddUndo(c4d.UNDOTYPE_NEW, disc_obj) #insert poly_obj under disc poly_obj.InsertUnder(disc_obj) doc.AddUndo(c4d.UNDOTYPE_NEW, poly_obj) def main(): path = "F:\\test.csv" doc.StartUndo() with open(path, 'rb') as csv_file: readed = csv.DictReader(csv_file, delimiter=',') for i, row in enumerate(readed): try: name = str(row["ObjectName"]) r_h = float(row["R.H"][:-1]) #-1 for removing ° depand of the encoding of the file can be -2 p_x = float(row["P.X"]) p_y = float(row["P.Y"]) outer_radius = float(row["OuterRadius"]) except: print "Error while reading - {}".format(row) continue r_h = c4d.utils.Rad(r_h) #convert in radian since c4d handle rotation in radian add_mesh(i, name, r_h, p_x, p_y, outer_radius) c4d.EventAdd() doc.EndUndo() if __name__=='__main__': main()
  9. We are not wizard, if you don't give us the informations you get and how they are exactly formatted we can't help you.
  10. Yes you can do it pretty easily can you provide how the csv is build?
  11. I would like to add you also get the possibility to use the correction deformer for make custom selection ! ;) I have made a quick tutorial for showing it !
  12. Here a quick script with both compatibility I also added another version more precise. Just change nb_point = 200 for a more precise gradient gradient_to_spline.c4d
  13. Take a look at my project here https://github.com/gr4ph0s/RefractiveIndex-Importer/ More specially https://github.com/gr4ph0s/RefractiveIndex-Importer/blob/master/res/src/Ui.py#L59 who cconvert a SplineData to a GradientData
  14. You are 100% right about a possibility of a bug because even if we set the cloner as default in object mode is not well initizialized as object mode. So there must be something wrong or at least you have to pass a special Message to the cloner for update his UI. So I encourage you to post at http://www.plugincafe.com/forum/forum_topics.asp?FID=3 where you can have an official reply. And post a sample code it will help developper to help you ;) import c4d def main(): cloner = c4d.BaseObject(1018544) doc.InsertObject(cloner) #Set mode cloner[c4d.ID_MG_MOTIONGENERATOR_MODE] = 0 cloner[c4d.MG_POLY_MODE_] = 3 #insert Animation count = c4d.CTrack(cloner, c4d.DescID(c4d.MG_POLYSURFACE_COUNT)) cloner.InsertTrackSorted(count) c4d.EventAdd() if __name__=='__main__': main()
  15. Just count = c4d.CTrack(op, c4d.DescID(c4d.MG_POLYSURFACE_COUNT)) op.InsertTrackSorted(count) c4d.EventAdd()
  16. It's a free tag plugin who allow you to import refrective index data (k and n) into curve. It's free and open source ! Feel free to share it where you want as long as you give credit. Any feedback, suggestion is welcome too. Here the preview demo: For more informations: https://gr4ph0s.github.io/RefractiveIndex-Importer/ For programmer it's was funny to do since I approche UI in a very different way that normally you should do. I firstly thinked about making it aviable in a Gedialog but since user can't copy/paste SplineData directly from the UI it's suck. So I moved to a python tag. Unfortually Dynamic description are only for R18+. So I decide to dont use it for more compatibility. Hope you enjoy it ! :)
  17. I really don't see the point to develop and integrate new render engine. This two year give us Redshift, Corona, Arnold, Cycle, Thea. And we already get Octane, Vray. And they are used a lot in production. Maybe youtube kiddies who do minecraft no care. But they also no care about buying render engine. So about market place of this new engine I have some huge doubt it's worth the time it's ask. And since 90%(It's random number I don't have any proof. But I never met someone who use ar in production) of us already use 3rd party engine, I really doubt we will switch and change all our workflow for his. Moreover when you come for ma node base element why you would go backward to this old system? About video, for me it's nothing... It's just a car with a shader, nothing fenzy. And we don't know the spec of hte machine but it's for sure a monster. About UV editor I don't want to kill dream of everyone but I just want to let you know they have introduce in R18 in python the UV command who are aviable since R14 in C++. So if they rewritte everything about UV I don't see the point to take time to port C++ function to python function when you will change everything in one year. So it's why for me UV tool will AGAIN not evolve. About bodypaint, yeah it's true, but really who use it nowaday and even the sneek peak just shouw us, how bad it will be. Just look at mari/Substance Painter/Quixel simplicity vs quality. So yeah it's build in c4d, but personally I prefer loose 10sec for export and 10sec for import and have huge more control/quality in another software ! And About core improvment, keep in mind multi-threading doesn't mean multi-cpu ! :/
  18. About priority I know is not like you but you can do a left click into object which are stacked. And select the one you want. For other thing you can do it in python ;) About tag I don't really udnerstand what you mean but I have no doubt you can do it in python ^^ Even if you can't do it directly in python you can display it in the viewport or anywhere you want throught python. About preset you mean for UD creation? Again it can be made in python :) New projet can be easily done in python excepted for texture path which are global :/ About Nitropose I currently developped one And I will release it as open source when finnished ! About material creation I 100% agree but again you can make a simple button which gonna create your material. And since you speak about redshift I point you to the script I made for rs script creation => https://www.redshift3d.com/forums/viewthread/10457/P30/#69130 For the background color you can change it into preference color. And you can also easily make a python plugin for switch beetwen them. Anyway I don't have a lot of free time due to my school animation project + work but when finnished (in 2months), and acording the update from R19 I will make thoses plugins ;)
  19. graphos

    Easier iteration

    Ok didn't thinked you was into a tag. But it's ok ! :) Anyway here is two methods. One automatic but which is not really optimized on object with a so huge amount of data. import c4d def reset(id_reset, id_parent, last_id): #Since we are in a tag is way more clean to do obj = op.GetObject than to proccess a search in the whole document. obj = op.GetObject() #Only if reset is True if obj[c4d.ID_USERDATA, id_reset]: obj[c4d.ID_USERDATA, id_reset] = False #We list all our data for id, bc in obj.GetUserDataContainer(): #Check if the parent_group = id_parent if yes reset if bc[c4d.DESC_PARENTGROUP][-1].id == id_parent: try: obj[id] = bc[c4d.DESC_DEFAULT] except TypeError: pass #Don't use elif we want the conditional statement before to have effect ! So if it's our last id we left the loop if id == last_id: break def main(): #list who store all our data #Reset_id, Group_id, Last_id_in_group datas = list() #Data exemple for G_Vegas datas.append([486, 284, 389]) #Loop for each data then reset them for data in datas: reset(data[0], data[1]) c4d.EventAdd() if __name__ == '__main__': main() Here is my second method way more optimized. Since you loop into all ud only 1 time. But for that you need to have a list of all userData under parent_id (but I have made a quick script for retrieve them ;) So basicly. Here is the code into the tag. I hope you understand it. import c4d #dict who gonna store all our bc and descid. Like that we iterate only 1 time. #dict["user_data_id"] = [descid, bc] #I use global vairable liek that we only have to do build it one time. #take care if you add/remove ud you need to update it, look the main function global dict_descid_bc dict_descid_bc = None def reset(obj, id_reset, list_id): global dict_descid_bc ud_bc = obj.GetUserDataContainer() #Only if reset is True if obj[c4d.ID_USERDATA, id_reset]: obj[c4d.ID_USERDATA, id_reset] = False #We list all our id who are into our list_of_id_to_reset for id in list_id: if id == id_reset: continue descid = dict_descid_bc[str(id)][0] bc = dict_descid_bc[str(id)][1] try: obj[descid] = bc[c4d.DESC_DEFAULT] except: pass def get_descid_bc(obj, dict): for descid, bc in obj.GetUserDataContainer(): dict[str(descid[-1].id)] = [descid, bc] def main(): #Get the object attached ot the tag obj = op.GetObject() #Tell to python we use the global variable global dict_descid_bc #Only update our dict if not build yet. if not dict_descid_bc: dict_descid_bc = dict() get_descid_bc(obj, dict_descid_bc) #list who store all our data #Reset_id, List_of_id_to_reset, list_of_descid_bc datas = list() #Data exemple for G_Vegas list_G_vegas = [486, 15, 17, 4, 44, 42, 27, 28, 512, 36, 29, 393, 38, 39, 40, 19, 389] datas.append([486, list_G_vegas]) #Loop for each data then reset them for data in datas: reset(obj, data[0], data[1]) #Trigger c4d update c4d.EventAdd() if __name__ == '__main__': main() And here is the script I used for get the list_G_vegas. (just change the parent_id in the main function, open the console and you got it ;)) import c4d def get_all_children_ud(obj, list_all_children, parent_id): ignore_list = [c4d.DTYPE_GROUP, c4d.DTYPE_SEPARATOR] for id, bc in obj.GetUserDataContainer(): if bc[c4d.DESC_PARENTGROUP][-1].id == parent_id: desc_level = id[-1] if not desc_level.dtype in ignore_list: list_all_children.append(desc_level.id) def main(): obj = doc.GetActiveObject() if not obj: return list_all_children = list() parent_id = 284 get_all_children_ud(obj, list_all_children, parent_id) print list_all_children if __name__=='__main__': main() But you only have to do it one time so I guess it's ok. For future reader I will continue this discussion into plugincafee for the reason I exposed before. http://www.plugincafe.com/forum/forum_posts.asp?TID=13629
  20. graphos

    Easier iteration

    Could you provide a scene exemple? Anyway here is a not optimized but cleaned for doing what you want. Provide me scene and I will optimize it. import c4d def reset(id_reset, id_parent): if obj[c4d.ID_USERDATA, id_reset]: obj[c4d.ID_USERDATA, id_reset] = False for id, bc in obj.GetUserDataContainer(): if bc[c4d.DESC_PARENTGROUP][-1].id == id_parent: try: doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj) obj[id] = bc[c4d.DESC_DEFAULT] except TypeError: pass finally: break #Stop loop since we got our parent def main(): datas = list() datas.append([486, 284]) datas.append([485, 285]) datas.append([489, 287]) datas.append([490, 289]) datas.append([491, 291]) datas.append([492, 293]) datas.append([508, 295]) datas.append([509, 297]) datas.append([510, 299]) datas.append([511, 301]) doc.StartUndo() for data in datas: reset(data[0], data[1]) doc.EndUndo() c4d.EventAdd() if __name__ == '__main__': main() EDIT: here is one using thread, will probably crash your c4d so it's why I ask for a scene file ;) import c4d class MyThread(c4d.threading.C4DThread): id_reset = 0 id_parent = 0 obj = None def Main(self): self.obj[c4d.ID_USERDATA, self.id_reset] = False for id, bc in self.obj.GetUserDataContainer(): if bc[c4d.DESC_PARENTGROUP][-1].id == self.id_parent: try: self.obj[id] = bc[c4d.DESC_DEFAULT] except TypeError: pass finally: break # Stop loop since we got our parent def main(): datas = list() datas.append([486, 284]) datas.append([485, 285]) datas.append([489, 287]) datas.append([490, 289]) datas.append([491, 291]) datas.append([492, 293]) datas.append([508, 295]) datas.append([509, 297]) datas.append([510, 299]) datas.append([511, 301]) list_thread = list() doc.StartUndo() for data in datas: if obj[c4d.ID_USERDATA, data[0]]: thread = MyThread() list_thread.append(thread) thread.id_reset = data[0] thread.id_parent = data[1] thread.obj = obj doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj) thread.Start() for thread in list_thread: thread.End() doc.EndUndo() c4d.EventAdd() if __name__ == '__main__': main() Moreover how do you get obj? it can be also that. Without your full code/exemple I can't do more And I also encourage you to don't post on multiples forum since people may loose time to answerd you while another one already do ^^'.
  21. Yes xml is a standard python library so yes you could use it in C4D as you will do it in any other python script :) And you don't need to update/install anything just import as you do in your post. (At least it works on R17, can't test before but should also work)
  22. Using standar library. Here a good tutorial about it. https://pymotw.com/2/xml/etree/ElementTree/parse.html
  23. There nothing not understandable ! This is just matter of how much time you try to understand ! Don't give up. Never give up ! :) For understand the concept of Basecontainer I suggest you to read http://www.plugincafe.com/forum/forum_posts.asp?TID=13571&PID=53830#53830 Just ask what you didn't understand. Here is your script using the global variable method, just hit play or move the timeline and look the console. import c4d global pos, last_frame pos, last_frame = None, None def get_current_frame(): return doc.GetTime().GetFrame(doc.GetFps()) def main(): #We explicitly say we will use thoss global variable global pos global last_frame obj = op.GetObject() #If pos is not set then we set it and return if not pos: pos = obj.GetMg().off last_frame = get_current_frame() return #we not moved frame by frame don't calcul but refresh data for future use if get_current_frame()-1 < last_frame < get_current_frame()+1: pos_before = pos pos = obj.GetMg().off last_frame = get_current_frame() return #if we are here everything is ok. #get previous pos and current pos and do calcul pos_before = pos pos = obj.GetMg().off last_frame = get_current_frame() delta_vector = pos - pos_before print '{} -> {}cm'.format(delta_vector, delta_vector.GetLength()) I have started some video tutorial on python for c4d in french into my vimeo page but do to the no audiance and the time it asking to myself. I stopped. Maybe I will try to do them in english. But my english speaking suck.
  24. import c4d def get_current_frame(): return doc.GetTime().GetFrame(doc.GetFps()) def write_bc(): datas = [0, 10, 20, 30, 40] # bc_doc[YourUniqueID] => bc_all_frames[frameNumber] => bc_data UNIQUE_ID = 10000000 # Get Bc doc bc_doc = doc.GetData() # Get bc all frames bc_all_frames = bc_doc.GetContainer(UNIQUE_ID) if not bc_all_frames: bc_all_frames = c4d.BaseContainer() # Set our data bc_data = c4d.BaseContainer() for i, data in enumerate(datas): bc_data.SetInt32(i, data) # Set bc all frame with our data bc_all_frames.SetContainer(get_current_frame(), bc_data) # Set doc bc bc_doc.SetContainer(UNIQUE_ID, bc_all_frames) doc.SetData(bc_doc, False) def read_bc(frame): UNIQUE_ID = 10000000 # Get Bc doc bc_doc = doc.GetData() #Get all frames data bc_all_frames = bc_doc.GetContainer(UNIQUE_ID) if not bc_all_frames: return None #Get datas bc_data = bc_all_frames.GetContainer(frame) if not bc_data: return None datas = list() for _, data in bc_data: datas.append(data) return datas def main(): write_bc() data = read_bc(get_current_frame()) print data if __name__=='__main__': main() For the unique id get one from http://www.plugincafe.com/forum/developer.asp
  25. Dirty way is to store your data in a global vairable. Nicer way store it into a basecontainer attached to the doc.
×
×
  • Create New...