├── .gitignore ├── README.md ├── img ├── 2020-04-14-13-34-42.png ├── 2020-04-14-13-35-17.png ├── 2020-04-14-13-37-53.png ├── 2020-04-14-13-40-29.png ├── 2020-04-14-13-41-41.png ├── 2020-04-14-13-50-12.png ├── 2020-04-14-13-50-47.png └── isoparm.png └── release ├── create_spline_from_all_polygons.py ├── normalize_spline.py ├── quick_isoparm_render.py ├── replace_with_instance.py └── split_by_selection_tag.py /.gitignore: -------------------------------------------------------------------------------- 1 | _test/ 2 | _download/ 3 | dev/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # C4D Python Scripts 3 | 4 | 5 | ### create_spline_from_all_polygons.py 6 | 7 | ![](img/2020-04-14-13-40-29.png) 8 | 9 | 10 | ### normalize_spline.py 11 | 12 | ![](img/2020-04-14-13-41-41.png) 13 | 14 | 15 | ### quick_isoparm_render.py 16 | 17 | ![](img/isoparm.png) 18 | 19 | ### replace_with_instance.py 20 | 21 | temporary model 22 | ![](img/2020-04-14-13-50-12.png) 23 | 24 | instances 25 | ![](img/2020-04-14-13-50-47.png) -------------------------------------------------------------------------------- /img/2020-04-14-13-34-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-34-42.png -------------------------------------------------------------------------------- /img/2020-04-14-13-35-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-35-17.png -------------------------------------------------------------------------------- /img/2020-04-14-13-37-53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-37-53.png -------------------------------------------------------------------------------- /img/2020-04-14-13-40-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-40-29.png -------------------------------------------------------------------------------- /img/2020-04-14-13-41-41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-41-41.png -------------------------------------------------------------------------------- /img/2020-04-14-13-50-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-50-12.png -------------------------------------------------------------------------------- /img/2020-04-14-13-50-47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/2020-04-14-13-50-47.png -------------------------------------------------------------------------------- /img/isoparm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yknishidate/c4d_python_scripts/31e6ae6334b5613e0deef8642706866da1c8b209/img/isoparm.png -------------------------------------------------------------------------------- /release/create_spline_from_all_polygons.py: -------------------------------------------------------------------------------- 1 | import c4d 2 | import random 3 | 4 | # setting of "convert selection" command 5 | setting = c4d.BaseContainer() 6 | setting[c4d.MDATA_CONVERTSELECTION_LEFT] = 2 # polygon 7 | setting[c4d.MDATA_CONVERTSELECTION_RIGHT] = 1 # edge 8 | 9 | # get object 10 | obj = doc.GetActiveObject() 11 | poly_cnt = obj.GetPolygonCount() 12 | 13 | # initialize polygon selection 14 | sel = obj.GetPolygonS() 15 | sel.DeselectAll() 16 | 17 | for index in xrange(poly_cnt): 18 | # select polygon 19 | sel.DeselectAll() 20 | sel.Select(index) 21 | 22 | # convert selection (polygon -> edge) 23 | c4d.utils.SendModelingCommand(c4d.MCOMMAND_CONVERTSELECTION, [obj], 24 | c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, 25 | setting, doc) 26 | # edge to spline 27 | c4d.utils.SendModelingCommand(c4d.MCOMMAND_EDGE_TO_SPLINE, [obj]) 28 | c4d.EventAdd() -------------------------------------------------------------------------------- /release/normalize_spline.py: -------------------------------------------------------------------------------- 1 | import c4d 2 | 3 | def make_editable(obj, inserted=False): 4 | res = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_MAKEEDITABLE, list=[obj]) 5 | if not res: 6 | print "ERROR: make_editable" 7 | return False 8 | return res[0] 9 | 10 | def copy_coodinates(from_obj, to_obj): 11 | to_obj.SetMg(from_obj.GetMg()) 12 | 13 | def main(): 14 | spline = doc.GetActiveObject() 15 | 16 | doc.StartUndo() 17 | 18 | if not spline.CheckType(c4d.Ospline): 19 | print "this is NOT Oline" 20 | return 21 | 22 | count = spline.GetPointCount() 23 | matrix = spline.GetMg() 24 | spline.SetMg(c4d.Matrix()) 25 | 26 | mospl = c4d.BaseObject(440000054) # MoSpline 27 | mospl[c4d.MGMOSPLINEOBJECT_MODE] = 1 # spline 28 | mospl[c4d.MGMOSPLINEOBJECT_SPLINE_MODE] = 2 # even 29 | mospl[c4d.MGMOSPLINEOBJECT_SOURCE_SPLINE] = spline 30 | mospl[c4d.MGMOSPLINEOBJECT_SPLINE_COUNT] = count 31 | mospl.SetName(spline.GetName()) 32 | mospl.SetMg(matrix) 33 | 34 | doc.InsertObject(mospl) 35 | res = make_editable(mospl) 36 | res.InsertBefore(spline) 37 | doc.AddUndo(c4d.UNDOTYPE_NEW, mospl) 38 | 39 | c4d.EventAdd() 40 | 41 | doc.AddUndo(c4d.UNDOTYPE_DELETE, spline) 42 | spline.Remove() 43 | 44 | doc.SetActiveObject(mospl,1) 45 | 46 | doc.EndUndo() 47 | 48 | if __name__ == '__main__': 49 | main() 50 | c4d.EventAdd() -------------------------------------------------------------------------------- /release/quick_isoparm_render.py: -------------------------------------------------------------------------------- 1 | import c4d 2 | from c4d import gui 3 | 4 | class MyDialogs(gui.GeDialog): 5 | def findSketchAndToon(self, renderData): 6 | curEffect = renderData.GetFirstVideoPost() 7 | while curEffect is not None: 8 | if curEffect.GetType() == 1011015: # 'Sketch and Toon' 9 | return curEffect 10 | curEffect = curEffect.GetNext() 11 | return 0 12 | 13 | def CreateLayout(self): 14 | self.SetTitle("Quick Isoparm Render") 15 | 16 | self.GroupBegin(1, c4d.BFH_LEFT, 2) # |-|-| 17 | 18 | self.AddStaticText(1000, c4d.BFH_LEFT, 150, 0, "Background", c4d.BORDER_NONE) 19 | self.AddColorField(1001, c4d.BFH_LEFT, 115, 0) 20 | self.SetColorField(1001, c4d.Vector(0.1, 0.1, 0.1), 1, 1, c4d.DR_COLORFIELD_NO_BRIGHTNESS) 21 | 22 | self.AddStaticText(1010, c4d.BFH_LEFT, 150, 0, "Line Color", c4d.BORDER_NONE) 23 | self.AddColorField(1011, c4d.BFH_LEFT, 115, 0,) 24 | self.SetColorField(1011, c4d.Vector(1, 1, 1), 1, 1, c4d.DR_COLORFIELD_NO_BRIGHTNESS) 25 | 26 | self.AddStaticText(1020, c4d.BFH_LEFT, 150, 0, "Line Thickness", c4d.BORDER_NONE) 27 | self.AddEditNumberArrows(1021, c4d.BFH_LEFT, 82, 0) 28 | self.SetFloat(1021, 2) 29 | 30 | self.GroupEnd() 31 | 32 | self.AddButton(1100, c4d.BFH_CENTER, 0, 0, "OK") 33 | 34 | return True 35 | 36 | def Command(self, id, msg): 37 | if id == 1100: 38 | doc.StartUndo() 39 | #doc.AddUndo(c4d.UNDOTYPE_CHANGE, None) 40 | 41 | renderData = doc.GetActiveRenderData() 42 | 43 | # Add Material 44 | sketchMat = c4d.BaseMaterial(1011014) 45 | sketchMat[c4d.OUTLINEMAT_COLOR] = self.GetColorField(1011)['color'] 46 | sketchMat[c4d.OUTLINEMAT_THICKNESS] = self.GetFloat(1021) 47 | doc.InsertMaterial(sketchMat) 48 | 49 | # Add Sketch and Toon 50 | sketchEffect = self.findSketchAndToon(renderData) 51 | if(sketchEffect != 0): 52 | sketchEffect[c4d.OUTLINEMAT_LINE_DEFAULT_MAT_V] = sketchMat 53 | sketchEffect[c4d.OUTLINEMAT_LINE_CREASE] = False 54 | sketchEffect[c4d.OUTLINEMAT_LINE_BORDER] = False 55 | sketchEffect[c4d.OUTLINEMAT_LINE_ISOPARMS] = True 56 | sketchEffect[c4d.OUTLINEMAT_LINE_OUTLINE] = True 57 | sketchEffect[c4d.OUTLINEMAT_SHADING_BACK_COL] = self.GetColorField(1001)['color'] 58 | sketchEffect[c4d.OUTLINEMAT_SHADING_OBJECT] = 4 # Object->Background 59 | else: 60 | newSketchEffect = c4d.documents.BaseVideoPost(1011015) 61 | newSketchEffect[c4d.OUTLINEMAT_LINE_DEFAULT_MAT_V] = sketchMat 62 | newSketchEffect[c4d.OUTLINEMAT_LINE_CREASE] = False 63 | newSketchEffect[c4d.OUTLINEMAT_LINE_BORDER] = False 64 | newSketchEffect[c4d.OUTLINEMAT_LINE_ISOPARMS] = True 65 | newSketchEffect[c4d.OUTLINEMAT_LINE_OUTLINE] = True 66 | newSketchEffect[c4d.OUTLINEMAT_SHADING_BACK_COL] = self.GetColorField(1001)['color'] 67 | newSketchEffect[c4d.OUTLINEMAT_SHADING_OBJECT] = 4 # Object->Background 68 | renderData.InsertVideoPostLast(newSketchEffect) 69 | 70 | ########## 71 | doc.EndUndo() 72 | c4d.EventAdd() 73 | self.Close() 74 | 75 | return True 76 | 77 | def main(): 78 | dlg = MyDialogs() 79 | dlg.Open(c4d.DLG_TYPE_MODAL) 80 | 81 | print "Execute" 82 | c4d.EventAdd() 83 | 84 | 85 | if __name__=='__main__': 86 | main() -------------------------------------------------------------------------------- /release/replace_with_instance.py: -------------------------------------------------------------------------------- 1 | import c4d 2 | import os 3 | from c4d import gui 4 | 5 | class MyDialogs(gui.GeDialog): 6 | 7 | def GetLink(self, param_id): 8 | gui = self.FindCustomGui(param_id, c4d.CUSTOMGUI_LINKBOX) 9 | if gui: 10 | return gui.GetLink() 11 | return None 12 | 13 | def AddLinkBox(self, param_id, flags, link=None): 14 | gui = self.AddCustomGui(param_id, c4d.CUSTOMGUI_LINKBOX, "", flags, 400, 0) 15 | gui.SetLink(link) 16 | return gui 17 | 18 | def CreateLayout(self): 19 | self.SetTitle("Replace with instance") 20 | self.GroupBegin(1, c4d.BFH_LEFT, 2) 21 | self.AddStaticText(1002, c4d.BFH_LEFT, 150, 0, "Reference Object", c4d.BORDER_NONE) 22 | self.AddLinkBox(1000, c4d.BFH_LEFT) 23 | self.AddStaticText(1003, c4d.BFH_LEFT, 150, 0, "Instance Mode", c4d.BORDER_NONE) 24 | self.AddComboBox(1004, c4d.BFH_LEFT, 357, 0) 25 | self.AddChild(1004, 0, "Instance") 26 | self.AddChild(1004, 1, "Render Instance") 27 | self.AddChild(1004, 2, "Multi-Instance") 28 | self.AddStaticText(1005, c4d.BFH_LEFT, 150, 0, "Position Source", c4d.BORDER_NONE) 29 | self.AddLinkBox(1006, c4d.BFH_LEFT) 30 | self.AddStaticText(1007, c4d.BFH_LEFT, 150, 0, "Viewport Mode", c4d.BORDER_NONE) 31 | self.AddComboBox(1008, c4d.BFH_LEFT, 357, 0) 32 | self.AddChild(1008, 0, "Off") 33 | self.AddChild(1008, 1, "Points") 34 | self.AddChild(1008, 3, "Matrix") 35 | self.AddChild(1008, 4, "Bounding Box") 36 | self.AddChild(1008, 2, "Object") 37 | self.SetInt32(1008, 2) 38 | self.HideElement(1005, True) 39 | self.HideElement(1006, True) 40 | self.HideElement(1007, True) 41 | self.HideElement(1008, True) 42 | self.GroupEnd() 43 | # Layer Setting 44 | self.GroupBegin(2, c4d.BFH_LEFT, 2) 45 | self.GroupBorder(c4d.BORDER_MASK) 46 | self.AddStaticText(1009, c4d.BFH_LEFT, 150, 0, "Layer", c4d.BORDER_NONE) 47 | self.AddComboBox(1010, c4d.BFH_LEFT, 357, 0) 48 | self.AddChild(1010, 0, "None") 49 | self.AddChild(1010, 1, "Keep Original Layer") 50 | self.AddChild(1010, 2, "Replace with Reference Layer") 51 | self.GroupEnd() 52 | # Replace 53 | self.GroupBegin(2, c4d.BFH_CENTER, 2) 54 | self.AddButton(1100, c4d.BFH_CENTER, 0, 0, "Replace") 55 | self.GroupEnd() 56 | return True 57 | 58 | def Command(self, id, msg): 59 | if id == 1100: 60 | base = self.GetLink(1000) 61 | if base != None: 62 | objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE) 63 | doc.StartUndo() 64 | for i, obj in enumerate(objects): 65 | # Create Instance 66 | instance = c4d.BaseObject(c4d.Oinstance) 67 | # Undo 68 | doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj) 69 | doc.AddUndo(c4d.UNDOTYPE_NEW, instance) 70 | # Instance Data 71 | instance[c4d.INSTANCEOBJECT_LINK] = base 72 | instance[c4d.ID_BASEOBJECT_REL_POSITION] = obj[c4d.ID_BASEOBJECT_REL_POSITION] 73 | instance[c4d.ID_BASEOBJECT_REL_SCALE] = obj[c4d.ID_BASEOBJECT_REL_SCALE] 74 | instance[c4d.ID_BASEOBJECT_REL_ROTATION] = obj[c4d.ID_BASEOBJECT_REL_ROTATION] 75 | instance[c4d.INSTANCEOBJECT_RENDERINSTANCE_MODE] = self.GetInt32(1004) 76 | instance[c4d.INSTANCEOBJECT_MULTIPOSITIONINPUT] = self.GetLink(1006) 77 | instance[c4d.INSTANCEOBJECT_DRAW_MODE] = self.GetInt32(1008) 78 | # Layer 79 | layer = self.GetInt32(1010) 80 | if layer == 1: 81 | instance.SetLayerObject( obj.GetLayerObject(doc) ) 82 | if layer == 2: 83 | instance.SetLayerObject( base.GetLayerObject(doc) ) 84 | instance.SetName(obj.GetName() + "_" + base.GetName() + "_" + str(i) ) 85 | instance.InsertBefore(obj) 86 | # Replace Children 87 | children = obj.GetChildren() 88 | for child in reversed(children): 89 | child.InsertUnder(instance) 90 | # Copy Animation 91 | tracks = obj.GetCTracks() 92 | trackListToCopy = [c4d.ID_BASEOBJECT_POSITION, c4d.ID_BASEOBJECT_ROTATION, c4d.ID_BASEOBJECT_SCALE] 93 | for track in tracks: 94 | did = track.GetDescriptionID() 95 | if not did[0].id in trackListToCopy: 96 | continue 97 | foundTrack = instance.FindCTrack(did) 98 | if foundTrack: 99 | foundTrack.Remove() 100 | clone = track.GetClone() 101 | instance.InsertTrackSorted(clone) 102 | animateflag = c4d.ANIMATEFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.ANIMATEFLAGS_0 103 | doc.AnimateObject(instance, doc.GetTime(), animateflag) 104 | # Remove Obj 105 | obj.Remove() 106 | doc.EndUndo() 107 | c4d.EventAdd() 108 | if id == 1004: 109 | mode = self.GetInt32(1004) 110 | if mode == 0: 111 | self.HideElement(1005, True) 112 | self.HideElement(1006, True) 113 | self.HideElement(1007, True) 114 | self.HideElement(1008, True) 115 | self.LayoutChanged(1) 116 | elif mode == 1: 117 | self.HideElement(1005, True) 118 | self.HideElement(1006, True) 119 | self.HideElement(1007, True) 120 | self.HideElement(1008, True) 121 | self.LayoutChanged(1) 122 | else: 123 | self.HideElement(1005, False) 124 | self.HideElement(1006, False) 125 | self.HideElement(1007, False) 126 | self.HideElement(1008, False) 127 | self.LayoutChanged(1) 128 | return True 129 | 130 | def main(): 131 | dlg = MyDialogs() 132 | script_open_async_dialog(dlg) 133 | 134 | def script_open_async_dialog(dlg): 135 | dialogs = vars(os).setdefault('__c4d_dialogs', []) 136 | dialogs = [d for d in dialogs if d.IsOpen()] 137 | dialogs.append(dlg) 138 | os.__c4d_dialogs = dialogs 139 | return dlg.Open(c4d.DLG_TYPE_ASYNC, 0, -1, -1, 0, 0) 140 | 141 | if __name__=='__main__': 142 | main() 143 | c4d.EventAdd() -------------------------------------------------------------------------------- /release/split_by_selection_tag.py: -------------------------------------------------------------------------------- 1 | import c4d 2 | from c4d import utils 3 | from c4d import gui 4 | 5 | def deselect_all(): 6 | c4d.CallCommand(100004767, 100004767) 7 | 8 | def activate(obj): 9 | deselect_all() 10 | obj.SetBit(c4d.BIT_ACTIVE) 11 | 12 | def activate_prev_obj(): 13 | obj = doc.GetActiveObject().GetPred() 14 | activate(obj) 15 | 16 | def split(): 17 | c4d.CallCommand(14046) 18 | activate_prev_obj() 19 | 20 | def get_empty_polygons(): 21 | polys = op.GetPolygonS() 22 | polys.DeselectAll() 23 | return polys 24 | 25 | def split_by_selection_tag(selection_tag): 26 | polys = get_empty_polygons() 27 | count = op.GetPolygonCount() 28 | selection = selection_tag.GetBaseSelect() 29 | for i in range(count): 30 | if selection.IsSelected(i): 31 | polys.Select(i) 32 | split() 33 | 34 | def main(): 35 | tags = op.GetTags() 36 | for tag in tags: 37 | if type(tag) is c4d.SelectionTag: 38 | split_by_selection_tag(tag) 39 | 40 | op.Message(c4d.MSG_UPDATE) 41 | c4d.EventAdd() 42 | 43 | if __name__=='__main__': 44 | main() 45 | --------------------------------------------------------------------------------