import c4dfrom c4d import gui#Welcome to the world of Python#Unique id numbers for each of the GUI elementsBACKGROUND = 1000BACKGROUND_COLOR = 1001GROUP_OPTIONS = 10000OPTION_COLOR = 10001OPTION_AO = 10002GROUP_BUTTONS = 20000BUTTON_OK = 20001BUTTON_CANCEL = 20002OPTION_WIDTH = 20003OPTION_HIGHT = 20004#This class defines the dialogue that pops up to request user optionsclass OptionsDialog(gui.GeDialog):#Add all the items we want to show in the dialogue boxdef CreateLayout(self):#Bake cehck boxself.GroupBegin(GROUP_OPTIONS, c4d.BFH_SCALE|c4d.BFH_LEFT, 1, 2)self.AddCheckbox(OPTION_COLOR, c4d.BFH_LEFT, 0,0, name="Color")self.AddCheckbox(OPTION_AO, c4d.BFH_LEFT, 0,0, name="AO")self.GroupEnd()#BG colorself.AddStaticText(BACKGROUND, c4d.BFH_LEFT, name="Background Color")self.AddColorField(BACKGROUND_COLOR, c4d.BFH_SCALEFIT, 80, 12)#Group nameself.GroupBegin(10000, c4d.BFH_SCALEFIT, 1, title = 'Texture size')self.GroupBorder(c4d.BORDER_GROUP_IN)self.GroupBorderSpace(20, 5, 20, 5)#Arrow numbersself.AddEditNumberArrows(OPTION_WIDTH, c4d.BFH_SCALEFIT, 50, 0)self.AddEditNumberArrows(OPTION_HIGHT, c4d.BFH_SCALEFIT, 50, 0)#Buttons - an OK and a CANCEL buttonself.GroupBegin(GROUP_OPTIONS, c4d.BFH_CENTER, 2, 1)self.AddButton(BUTTON_OK, c4d.BFH_SCALE, name="Set")self.AddButton(BUTTON_CANCEL, c4d.BFH_SCALE, name="Cancel")self.GroupEnd()return True#This is where we react to user input (eg button clicks)def Command(self, id, msg):if id==BUTTON_CANCEL:#The user has clicked the 'Cancel' buttonself.ok = Falseself.Close()elif id==BUTTON_OK:#The user has clicked the 'OK' buttonself.ok = True#Save the checkbox values so that the rest of the script can access themself.option_color = self.GetBool(OPTION_COLOR)self.option_AO = self.GetBool(OPTION_AO)self.option_BG = self.GetColorField(BACKGROUND_COLOR)['color'] # GetColorField returns a dictionary. The actual vector of the color is an item with the key 'color'self.option_width = self.GetInt32(OPTION_WIDTH) # the field in the BakeTexture tag expects integers, not floats ;)self.option_hight = self.GetInt32(OPTION_HIGHT)self.Close()return True#This is where the action happensdef main():#Open the options dialogue to let users choose their optionsoptionsdialog = OptionsDialog()optionsdialog.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50)#Quit if the user has clicked cancelif not optionsdialog.ok:return#create tagdef tool():return plugins.FindPlugin(doc.GetAction(), c4d.PLUGINTYPE_TOOL)def object():return doc.GetActiveObject()def tag():return doc.GetActiveTag()def renderdata():return doc.GetActiveRenderData()def prefs(id):return plugins.FindPlugin(id, c4d.PLUGINTYPE_PREFS)# c4d.CallCommand(100004788, 50005) # you should avoid using CallCommand if where you can.tag = doc.GetActiveObject().MakeTag(c4d.Tbaketexture) # this creates the tag and applies it to the active objecttag[c4d.BAKETEXTURE_CHANNEL_COLOR] = optionsdialog.option_color # you don't need () around the variablestag[c4d.BAKETEXTURE_CHANNEL_AO] = optionsdialog.option_AOtag[c4d.BAKETEXTURE_WIDTH] = optionsdialog.option_widthtag[c4d.BAKETEXTURE_HEIGHT] = optionsdialog.option_highttag[c4d.BAKETEXTURE_BACKGROUND] = optionsdialog.option_BGc4d.EventAdd()if __name__=='__main__':main()
import c4ddef main():doc.StartUndo()# Flags# 0 GETACTIVEOBJECTFLAGS_0# 1 GETACTIVEOBJECTFLAGS_CHILDREN# 2 GETACTIVEOBJECTFLAGS_SELECTIONORDERobjs = doc.GetActiveObjects(1)if not objs:print("No objects selected.")returnfor i in objs:tag = i.MakeTag(c4d.Texpresso)doc.AddUndo(c4d.UNDOTYPE_NEW, tag)c4d.EventAdd()doc.EndUndo()if __name__=='__main__':main()

# For each selected open spline (line), turns it into a thick# closed spline (polygon) along the path of the original line.# No additional chamfer points are added, so very sharp corners will# look funny - resulting spline will have twice as many points.# Alternatively can also fold the spline back on itself in place# without duplicating the first or last line.import c4dfrom c4d import guiimport math# Unique id numbers for each of the GUI elementsLBL_USAGE = 1000LBL_INFO1 = 1001LBL_INFO2 = 1002GROUP_OPTS = 10000NUMEDIT_THICKNESS = 10001CHK_CLOSE_SPLINE = 10003CHK_MAKE_COPY = 10004CMB_ACTION = 20000CMB_ACTION_EXPAND = 20001CMB_ACTION_REVERSE = 20002class OptionsDialog(gui.GeDialog):""" Dialog for expanding a open spline."""def CreateLayout(self):self.SetTitle('Expand Open Spline')self.AddMultiLineEditText(LBL_USAGE, c4d.BFH_SCALEFIT, inith=40, initw=500,style=c4d.DR_MULTILINE_READONLY)self.SetString(LBL_USAGE,"USAGE: For any selected open splines, makes them\n"" thick closed polygons of specified thickness")# Dropdown and thickness option:self.GroupBegin(GROUP_OPTS, c4d.BFH_SCALEFIT, 2, 2)self.AddStaticText(LBL_INFO1, c4d.BFH_LEFT, name='Action: ')self.AddComboBox(CMB_ACTION, c4d.BFH_SCALEFIT)self.AddChild(CMB_ACTION, CMB_ACTION_EXPAND, "expand spline in XZ")self.AddChild(CMB_ACTION, CMB_ACTION_REVERSE, "reverse on itself")self.SetInt32(CMB_ACTION, CMB_ACTION_EXPAND) # Set default action.self.AddStaticText(LBL_INFO2, c4d.BFH_LEFT, name='Thickness: ')self.AddEditNumber(NUMEDIT_THICKNESS, c4d.BFH_SCALEFIT)self.SetReal(NUMEDIT_THICKNESS, 10)self.GroupEnd()self.AddSeparatorH(c4d.BFH_SCALE);# Checkbox options:self.AddCheckbox(CHK_CLOSE_SPLINE, c4d.BFH_SCALEFIT,initw=1, inith=1, name="close spline when done")self.SetBool(CHK_CLOSE_SPLINE, True)self.AddCheckbox(CHK_MAKE_COPY, c4d.BFH_SCALEFIT,initw=1, inith=1, name="make new copy")self.SetBool(CHK_MAKE_COPY, True)self.AddSeparatorH(c4d.BFH_SCALE);# Buttons - an Ok and Cancel button:self.AddDlgGroup(c4d.DLG_OK|c4d.DLG_CANCEL);self.ok = Falsereturn True# React to user's input:def Command(self, id, msg):if id==c4d.DLG_CANCEL:self.Close()elif id==c4d.DLG_OK:self.ok = Trueaction = self.GetInt32(CMB_ACTION)self.option_action_expand = action == CMB_ACTION_EXPANDself.option_action_reverse = action == CMB_ACTION_REVERSEself.option_thickness = self.GetReal(NUMEDIT_THICKNESS)self.option_close_spline = self.GetBool(CHK_CLOSE_SPLINE)self.option_make_copy = self.GetBool(CHK_MAKE_COPY)self.Close()return Truedef get_yaw(start_pt, end_pt):"""Determines the azimuth from the given start to end point.Rotation is around XZ where -X = 0Args:start_pt: c4d.Vector representing start point.end_pt: c4d.Vector representing end point.Returns:yaw angle in degrees."""rad = math.atan2(end_pt.z - start_pt.z, end_pt.x - start_pt.x)return math.degrees(rad)def angle_formed_by_three_points_xy(pt1, pt2, pt3):"""Determines the theta (in degrees) between 3 connected points.pt3 o// thetapt2 o---------o pt1Args:pt1: c4d.Vector representing point before middle point.pt2: c4d.Vector representing middle point.pt3: c4d.Vector representing point after middle point.Returns:angle between 0 and 360."""line1_yaw = get_yaw(pt1, pt2)line2_yaw = get_yaw(pt3, pt2)return (line2_yaw - line1_yaw) % 360.0def get_point_rel_to_end_xy(start_pt, end_pt, dist_offset, rel_angle):"""Get a point 'dist_offset' from 'end_pt' at an angle relative to the line.Example: if dist_offset=2 and rel_angle=90:o <-- the point returned would be herestart_pt o-----------o end_ptArgs:start_pt: c4d.Vector representing start point.end_pt: c4d.Vector representing end point.dist_offset: Numeric distance to offset away from end_pt.rel_angle: Angle relative from the direction of the line to use indisplacing the returned point. 0 is straight (in direction of line).Returns:angle between 0 and 360."""yaw = get_yaw(start_pt, end_pt)theta = math.radians(yaw + rel_angle)offset_x = dist_offset * math.cos(theta)offset_z = dist_offset * math.sin(theta)return c4d.Vector(offset_x + end_pt.x, end_pt.y, offset_z + end_pt.z)def get_chamfer_point_xy(pt1, pt2, pt3, offset):"""Get a chamfer on the outside of a point connected to two other points.- - - o <-- chamfer pointthickness / (for this case would be 45 degress offset)/pt1 o-------o pt2||o pt3Args:pt1: c4d.Vector representing point before middle point.pt2: c4d.Vector representing middle point.pt3: c4d.Vector representing point after middle point.offset: Numerical value representing thickness to baseoffset on. A sharper turn will mean further offset.Returns:c4d.Vector representing chamfer point."""if pt1 == pt2:return get_point_rel_to_end_xy(pt3, pt2, offset, -90)if pt2 == pt3:return get_point_rel_to_end_xy(pt1, pt2, offset, 90)angle_at_curr = 360 - angle_formed_by_three_points_xy(pt1, pt2, pt3)angle_inset = angle_at_curr / 2.0rad = math.sin(math.radians(angle_inset)) # Radiansdist_from_corner = offsetif rad != 0:dist_from_corner = offset / radreturn get_point_rel_to_end_xy(pt1, pt2, dist_from_corner, 180.0-angle_inset)def expand_spline_xz(spline, thickness):"""Takes a 'spline' object, and expands it by 'thickness' in XZ.Args:spline: Open spline object to expand.thickness: Number representing thickness/diameter of final line.Returns:number of points added."""if (spline == None or not spline.CheckType(c4d.Ospline) orspline.GetPointCount() < 2):return 0;len_orig = spline.GetPointCount()len_new = len_orig * 2new_spline = splinenew_spline.ResizeObject(len_new)for i in range(0,len_orig):p_prev = spline.GetPoint(i) # Previous point.p_curr = spline.GetPoint(i) # Current point.p_next = spline.GetPoint(i) # Next point.if i > 0:p_prev = spline.GetPoint(i-1)if i < len_orig-1:p_next = spline.GetPoint(i+1)p_mid_cw = get_chamfer_point_xy(p_prev, p_curr, p_next, thickness / 2.0)p_mid_ccw = get_chamfer_point_xy(p_next, p_curr, p_prev, thickness / 2.0)new_spline.SetPoint(i, p_mid_cw)new_spline.SetPoint(len_new-i-1, p_mid_ccw)doc.AddUndo(c4d.UNDOTYPE_CHANGE, spline)spline = new_splinereturn len_new - len_orig;def fold_spline_on_itself(spline):"""Takes a 'spline' object, and appends points which backtrack to the first.If the origional spline has points at positions: A,B,C,DThe new spline append s(len*2-2) points and becomes: A,B,C,D,C,BNeither the last or first point are not repeated.Args:spline: Spline object to fold back on itself by appending.Returns:number of points added."""if (spline == None or not spline.CheckType(c4d.Ospline) orspline.GetPointCount() < 3):return 0;len_orig = spline.GetPointCount()len_new = (len_orig) * 2 - 2doc.AddUndo(c4d.UNDOTYPE_CHANGE, spline)spline.ResizeObject(len_new)for i in range(1, len_orig-1):e = len_new - i # Working back from last point.point = spline.GetPoint(i)new_point = c4d.Vector(point.x, point.y, point.z)spline.SetPoint(e, new_point)return len_new - len_orig;def main():# Get the selected objects, including children.selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)if len(selection) <= 0:gui.MessageDialog('Must select spline object(s)!')return# Open the options dialogue to let users choose their options.dlg = OptionsDialog()dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50)if not dlg.ok:returndoc.StartUndo() # Start undo block.num_splines_changed = 0for i in range(0,len(selection)):spline = selection[i]if not spline.CheckType(c4d.Ospline) or spline.GetPointCount() < 2:continuenum_splines_changed += 1# Make copy if needed:if dlg.option_make_copy:new_spline = spline.GetClone()doc.InsertObject(new_spline, pred=spline)doc.AddUndo(c4d.UNDOTYPE_NEW, new_spline)spline = new_spline# Apply chosen action:points_added = 0if dlg.option_action_expand:points_added = expand_spline_xz(spline, dlg.option_thickness)elif dlg.option_action_reverse:points_added = fold_spline_on_itself(spline)# Close spline:if dlg.option_close_spline:spline[c4d.SPLINEOBJECT_CLOSED] = Truedoc.EndUndo() # End undo block.c4d.EventAdd() # Update C4D to see changes.gui.MessageDialog(str(num_splines_changed) + ' splines changed')if __name__=='__main__':main()
自定义图标案例
import c4d,osfrom c4d import gui,bitmapsMY_BITMAP_BUTTON = 1003class MyDialog(c4d.gui.GeDialog):def CreateLayout(self):self.SetTitle("My Python Dialog")self.GroupBegin(0, c4d.BFH_SCALEFIT|c4d.BFH_SCALEFIT, 1, 1, "Bitmap Example",0)bc = c4d.BaseContainer() ######Create a new container to store the button imagebc.SetLong(c4d.BITMAPBUTTON_BORDER, c4d.BORDER_OUT) #Sets the border to look like a buttonbc.SetLong(c4d.BITMAPBUTTON_ICONID1, c4d.RESOURCEIMAGE_MOVE) #####Sets Button Iconbc.SetBool(c4d.BITMAPBUTTON_BUTTON, True) #<---Does Not animate in R13!?self.myBitButton=self.AddCustomGui(MY_BITMAP_BUTTON, c4d.CUSTOMGUI_BITMAPBUTTON, "My Button", c4d.BFH_CENTER | c4d.BFV_CENTER, 50, 50, bc)self.GroupEnd()return True#Do something when the button is presseddef Command(self, id, msg=None):if id==MY_BITMAP_BUTTON:print "Hello"return Trueif __name__=='__main__':dlg = MyDialog()dlg.Open(c4d.DLG_TYPE_ASYNC, defaultw=100, defaulth=100)
坐标相关
import c4ddef main():#创建物体obj1 = c4d.BaseObject(5160)doc.InsertObject(obj1) #导入到文档return#常用标签print "所有标签", op.GetTags() #所有标签print "点总数", op.GetTagDataCount(c4d.Tpoint) #点总数print "面总数", op.GetTagDataCount(c4d.Tpolygon) #面总数print "第一个标签", op.GetFirstTag() #第一个标签print "最后一个标签", op.GetLastTag() #最后一个标签op.MakeTag(5612) #平滑标签op.MakeTag(5637) #合成标签op.MakeTag(5629) #保护标签op.MakeTag(5676) #目标标签op.MakeTag(1019364) #约束标签op.MakeTag(1019561) #IK标签op.MakeTag(1001149) #XPresso标签op.KillTag(5612) #删除标签#文档doc = c4d.documents.GetActiveDocument()print "当前文档名称:", doc.GetDocumentName() #当前文档名称print "当前文档路径:", doc.GetDocumentPath() #当前文档路径print "顶级对象集合:", doc.GetObjects() #顶级对象集合returnprint "当前选中对象:", doc.GetActiveObject() #当前选中的单个对象(多个为None)#名称print "对象名称:", op.GetName() #对象名称print "对象类型名称:", op.GetTypeName() #对象类型#层级#点print "隐藏点的集合:", op.GetPointH() #隐藏点的集合print "所选点的集合:", op.GetPointS() #所选点的集合print "点的位置集合:", op.GetAllPoints() #所有点的位置集合print "第n个点的位置:", op.GetPoint(1) #第n个点的位置print "顶点数量:", op.GetPointCount() #点的总数量print "更改后点的数量:", op.ResizeObject(5) #更改对象点的数量#位置#print "GetAbsPos:", op.GetAbsPos()print "GetMgn:", op.GetMgn()print "GetMg:", op.GetMg()print "GetMp:", op.GetMp()print "GetMln:", op.GetMln()print "GetMl:", op.GetMl()print "GetUpMg:", op.GetUpMg()print "GetRelMl:", op.GetRelMl()print "GetRelMln:", op.GetRelMln()if __name__=='__main__':main()c4d.EventAdd()#刷新界面
监测键盘被按下

https://developers.maxon.net/docs/Cinema4DPythonSDK/html/misc/inputevents.html
import c4ddef main():# Check all keysbc =c4d.BaseContainer()if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):print "Qualifier Bitwise:",bc[c4d.BFM_INPUT_QUALIFIER]if bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT:print "SHIFT PRESSED"if bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL:print "CONTROL PRESSED"if bc[c4d.BFM_INPUT_QUALIFIER] & c4d.QALT:print "ALT PRESSED"# Execute main()if __name__=='__main__':main()
