Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
@ferdinand Thanks for your help!
Hi, I want to refresh the dialog when switching documents. I tried to use the following code, but it seems that this cannot be achieved . When I switch documents, it seems that I only receive type==c4d.MSG_COMMANDINFORMATION
code:
def Message(self, type, data): print("msg type:{}".format(type)) print("data:{}".format(data)) if type == c4d.MSG_DOCUMENTINFO: if data['type'] == c4d.MSG_DOCUMENTINFO_TYPE_SETACTIVE: print("doc Change!") return True
Thanks for any help!
@manuel Thanks for your help!
Hi, i want to Copy all info of one Object to other Object.Use source.CopyTo(aim), But object aim is dead after CopyTo(). My purpose is to copy all the information of an object except the basic information to another object, so after CopyTo(), I want to use the backup information to restore the basic information of aim, but the object is dead and an exception will be thrown
this is code:
import c4d from c4d import gui def main(): source,aim = doc.GetActiveObjects(2) doc.StartUndo() #backup basic properties info_list = [] description = aim.GetDescription(c4d.DESCFLAGS_DESC_NONE) did_list = [c4d.DescID(c4d.DescLevel(110050, 1, 110050)), c4d.DescID(c4d.DescLevel(1041666, 1, 110050))] for bc, paramid, groupid in description: if groupid in did_list: if aim[paramid]: info_list.append((paramid, aim[paramid])) doc.AddUndo(c4d.UNDOTYPE_CHANGE,aim) source.CopyTo(aim, c4d.COPYFLAGS_NO_BRANCHES|c4d.COPYFLAGS_NO_MATERIALPREVIEW|c4d.COPYFLAGS_NO_BITS) #restore basic properties for info in info_list: aim[info[0]] = info[1] doc.EndUndo() c4d.EventAdd() # Execute main() if __name__=='__main__': main()
@ferdinand Thanks you for your help!
@ferdinand Thanks
pic 2 : Close Save, the regluar image Save must be not save
pic 3:Open Save, the regluar image Save save or not save depends on itself
@ferdinand Thanks,MyRenderSetting[c4d.RDATA_SAVEIMAGE] = True I use this method in my code, it can achieve the purpose of not save image, but I am wondering if I can access the state of the Save element in pic1, so that when I activate my renderSetting, I do not click Go in and check the status of [c4d.RDATA_SAVEIMAGE], you can also directly know whether it is a saved state or an unsaved state during the current rendersetting
@m_adam Thanks for your help,great work!
@m_adam Thanks!
Hi, Use RenderData how to change "Save" state! Thanks for any help!
pic1
This is the sample code, I tried to dynamically create the element inside the group to achieve, the picture is not drawn completely as expected:
import c4d import os import sys from c4d import gui,bitmaps,plugins,utils,modules,storage PLUGIN_ID = 10000000 #only for test GROUP_SCROLL = 1100 USEEAREA_GROUP = 1102 USERAREA = 1101 ADD_BUTTON = 1200 class PreViewArea(gui.GeUserArea): bmp = None def DrawMsg(self,x1, y1, x2, y2, msg): self.OffScreenOn() self.SetClippingRegion(x1, y1, x2, y2) BG_colorDict = self.GetColorRGB(c4d.COLOR_BG) BG_color = c4d.Vector(BG_colorDict['r'], BG_colorDict['g'], BG_colorDict['b']) / 255.0 self.DrawSetPen(BG_color) self.DrawRectangle(x1, y1, x2, y2) if self.bmp: width = self.bmp.GetBw() height = self.bmp.GetBh() self.DrawBitmap(self.bmp, 0, 0, width, height, 0, 0, width, height, c4d.BMP_NORMAL) def dynamic_Group(dialog,ua): dialog.LayoutFlushGroup(USEEAREA_GROUP) if ua.bmp: width = ua.bmp.GetBw() height = ua.bmp.GetBh() else: width,height = 0,0 dialog.AddUserArea(USERAREA, c4d.BFH_SCALE | c4d.BFV_SCALE,width,height) dialog.AttachUserArea(ua, USERAREA) dialog.LayoutChanged(USEEAREA_GROUP) class S_Lib_Dialog(gui.GeDialog): ua = PreViewArea() def CreateLayout(self): self.SetTitle("test") self.ScrollGroupBegin(PLUGIN_ID, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, c4d.SCROLLGROUP_HORIZ | c4d.SCROLLGROUP_VERT) self.GroupBegin(USEEAREA_GROUP,c4d.BFH_LEFT | c4d.BFV_TOP,1,1) self.GroupBorder(c4d.BORDER_ACTIVE_1) self.AddUserArea(USERAREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT) self.AttachUserArea(self.ua, USERAREA) self.GroupEnd() self.GroupEnd() self.AddButton(ADD_BUTTON,c4d.BFH_SCALEFIT,150,30,"Load image") return True def Command(self, id, msg): if id == ADD_BUTTON: path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES) if path: bmp = bitmaps.BaseBitmap() result,ismovie = bmp.InitWith(path) if result == c4d.IMAGERESULT_OK: self.ua.bmp = bmp dynamic_Group(self, self.ua) self.ua.Redraw() else: print("Load image Fail") else: print("Not select image") return True return True class S_Lib(plugins.CommandData): dialog = None def Execute(self,doc): # create the dialog if self.dialog is None: self.dialog = S_Lib_Dialog() return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=800, defaulth=400) def RestoreLayout(self, sec_ref): # manage nonmodal dialog if self.dialog is None: self.dialog = S_Lib_Dialog() return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) # Execute main() if __name__=='__main__': path, fn = os.path.split(__file__) plugins.RegisterCommandPlugin(id=PLUGIN_ID, str="test", info=0, help="", dat=S_Lib(), icon=None)
Hi, In my scrollgroup, I created a UserArea to draw pictures, but the size of the pictures to be drawn is dynamic, that is to say, when the dialog is opened, different pictures are loaded and switching displayed by clicking button . When image size changing, expect the scrolling gui component to always be correct. (The picture drawn in the UserArea is 1:1, such as a 1280 * 720 picture file, the size in UserArea drawed also 1280 * 720).
When I created it, the size of the UserArea could not automatically adapt to the image size, which caused the gui component of the scroll group to not work as expected.
After reading these two posts(Scrolling in UA/Scaling a GeUserArea in a ScrollGroup), I still can't achieve this goal! Thanks for any help!
@m_magalhaes Thanks for the detailed explanation as to why it crashed!
Hey @ferdinand , Using the following code, the crash will also occur
test commanddata plugins code
import c4d import os import sys from c4d import gui,bitmaps,plugins,utils,modules,storage PLUGIN_ID = 10000000 #only for test SUB_DIALOG_ID = 1000001 SUB_DIALOG_GONE = 5000 SUB_DIALOG_GONE_NAMETEXT = 5001 SUB_DIALOG_GONE_NAME = 5002 SUB_DIALOG_GONE_ANIGROUP = 5003 SUB_DIALOG_GONE_ANIGROUP_ALLRANGE = 5004 SUB_DIALOG_GONE_ANIGROUP_PRERANGE = 5005 SUB_DIALOG_GTWO = 5010 SUB_DIALOG_GTWO_EDITIMAGE = 5011 SUB_DIALOG_GTWO_CUTIMAGE = 5012 SUB_DIALOG_IMAGE = 5020 SUB_DIALOG_SAVE = 5021 #active tool def UseSreenShot(active=False,path=None,name=None,size=None,cutimage=False,child_path="image"): tool_id = 1000010 doc = c4d.documents.GetActiveDocument() tool = plugins.FindPlugin(tool_id, c4d.PLUGINTYPE_TOOL) data = plugins.GetToolData(doc, tool_id) if active: doc.SetAction(tool_id) #c4d.CallCommand(1059888) # S_ScreenShot if path: data[1] = os.path.join(path,child_path) if name: data[2] = name if size: data[3] = size if cutimage: tool.Message(tool_id) # else: tool.Message(tool_id) # # class S_Add_Dialog(gui.GeDialog): name = None path = None size = None mode = 0 ua = None def CreateLayout(self): if self.mode == 3: self.SetTitle("Setting") else: self.SetTitle("New ") self.GroupBegin(SUB_DIALOG_GONE,c4d.BFH_SCALEFIT,3,1) self.AddStaticText(SUB_DIALOG_GONE_NAMETEXT,c4d.BFH_LEFT,100,10,"Name:") self.AddEditText(SUB_DIALOG_GONE_NAME,c4d.BFH_SCALEFIT,150,20) if self.mode == 1: # self.AddRadioGroup(SUB_DIALOG_GONE_ANIGROUP,c4d.BFH_RIGHT,2,1) self.AddChild(SUB_DIALOG_GONE_ANIGROUP,SUB_DIALOG_GONE_ANIGROUP_ALLRANGE,"All Range") self.AddChild(SUB_DIALOG_GONE_ANIGROUP, SUB_DIALOG_GONE_ANIGROUP_PRERANGE, "Preview Range") self.SetInt32(SUB_DIALOG_GONE_ANIGROUP,SUB_DIALOG_GONE_ANIGROUP_ALLRANGE) self.GroupEnd() self.GroupBegin(SUB_DIALOG_GTWO,c4d.BFH_SCALEFIT,1,1) self.AddButton(SUB_DIALOG_GTWO_CUTIMAGE,c4d.BFH_SCALEFIT,150,30,"Get Image") #self.AddButton(SUB_DIALOG_GTWO_CUTIMAGE, c4d.BFH_SCALEFIT, 150, 30, "Get Image") self.GroupEnd() #self.AddUserArea(SUB_DIALOG_IMAGE,c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,100,100) #self.ua = UserArea_forAdd() #self.AttachUserArea(self.ua,SUB_DIALOG_IMAGE) self.AddButton(SUB_DIALOG_SAVE, c4d.BFH_SCALEFIT, 150, 30, "Save") return True def Command(self, id, msg): return True class S_Lib_Dialog(gui.GeDialog): sub_dialog = S_Add_Dialog() def CreateLayout(self): self.SetTitle("test") self.AddButton(1001,c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,150,30,"test") return True def Command(self, id, msg): if id == 1001: #SUB_DIALOG_ID = 1000001 UseSreenShot(active=True, path='AAAA', name='BBB') # active tool,and send message self.sub_dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC,pluginid=PLUGIN_ID, defaultw=100, defaulth=100,subid=SUB_DIALOG_ID) return True def Restore(self, pluginid, secret): if secret['subid'] == SUB_DIALOG_ID: return self.sub_dialog.Restore(pluginid, secret) else: return super(S_Lib_Dialog, self).Restore(pluginid, secret) class S_Lib(plugins.CommandData): dialog = None def Execute(self,doc): # create the dialog if self.dialog is None: self.dialog = S_Lib_Dialog() return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=800, defaulth=400) def RestoreLayout(self, sec_ref): # manage nonmodal dialog if self.dialog is None: self.dialog = S_Lib_Dialog() return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref) # Execute main() if __name__=='__main__': path, fn = os.path.split(__file__) plugins.RegisterCommandPlugin(id=PLUGIN_ID, str="test command", info=0, help="", dat=S_Lib(), icon=None)
test tool plugins code:
import c4d import os from c4d import gui, plugins, bitmaps PLUGIN_ID = 1000010 #only for test def GetSafeWindow_Center(): doc = c4d.documents.GetActiveDocument() bd = doc.GetActiveBaseDraw() window_dict = bd.GetFrame() window_l = window_dict['cl'] window_r = window_dict['cr'] window_t = window_dict['ct'] window_b = window_dict['cb'] return bd, window_l, window_r, window_t, window_b def Draw2dbox(bd, x_min, x_max, y_min, y_max): p1 = c4d.Vector(x_min, y_min, 0) p2 = c4d.Vector(x_max, y_min, 0) p3 = c4d.Vector(x_max, y_max, 0) p4 = c4d.Vector(x_min, y_max, 0) bd.DrawLine2D(p1, p2) bd.DrawLine2D(p2, p3) bd.DrawLine2D(p3, p4) bd.DrawLine2D(p4, p1) def DrawBox(width_height, offset=c4d.Vector(0, 0, 0), color=c4d.Vector(1, 0, 0)): # draw box bd, safe_window_l, safe_window_r, safe_window_t, safe_window_b = GetSafeWindow_Center() safe_center = ((safe_window_r + safe_window_l) / 2 + offset[0], (safe_window_b + safe_window_t) / 2 + offset[1]) # width_half = width_height[0] / 2 height_half = width_height[1] / 2 x_min = safe_center[0] - width_half x_max = safe_center[0] + width_half y_min = safe_center[1] - height_half y_max = safe_center[1] + height_half # bd.SetMatrix_Screen() bd.SetPen(color) bd.DrawPoint2D(c4d.Vector(safe_center[0], safe_center[1], 0)) Draw2dbox(bd, x_min, x_max, y_min, y_max) class S_ScreenShot_Dialog(gui.SubDialog): parameters = None def __init__(self, para_in): self.parameters = para_in def update(self,command=False): if command: #update gui parameter if self.parameters['path']: self.SetString(1012,self.parameters['path']) if self.parameters['name']: self.SetString(1014,self.parameters['name']) def Command(self,id,msg): if id == 1033: return True if id == 1022 or id == 1032: # self.parameters['width'] = self.GetInt32(1022) self.parameters['height'] = self.GetInt32(1032) c4d.DrawViews(c4d.DRAWFLAGS_ONLY_BASEDRAW) return True if id == 1021: # self.SetInt32(1032, self.GetInt32(1022)) self.parameters['width'] = self.GetInt32(1022) self.parameters['height'] = self.GetInt32(1032) c4d.DrawViews(c4d.DRAWFLAGS_ONLY_BASEDRAW) return True if id == 1031: # self.SetInt32(1022, self.GetInt32(1032)) self.parameters['width'] = self.GetInt32(1022) self.parameters['height'] = self.GetInt32(1032) c4d.DrawViews(c4d.DRAWFLAGS_ONLY_BASEDRAW) return True if id == 1051: # self.parameters['offset'] = c4d.Vector(0) c4d.DrawViews(c4d.DRAWFLAGS_ONLY_BASEDRAW) return True if id == 1012: # self.parameters['path'] = self.GetString(1012) return True if id == 1034: # self.parameters['showbmp'] = self.GetBool(1034) return True return True def CreateLayout(self): self.GroupBegin(1010, c4d.BFH_SCALEFIT, 2, 1) self.GroupBorderSpace(10, 10, 10, 10) self.AddStaticText(1011, c4d.BFH_MASK, initw=50, inith=0, name="Path:") bc = c4d.BaseContainer() bc.SetBool(c4d.FILENAME_DIRECTORY,True) self.AddCustomGui(1012, c4d.CUSTOMGUI_FILENAME,"",c4d.BFH_SCALEFIT, 50, 20, bc) self.AddStaticText(1013, c4d.BFH_MASK, initw=50, inith=0, name="Name:") self.AddEditText(1014,c4d.BFH_MASK, initw=200, inith=0) self.GroupEnd() self.GroupBegin(1020, c4d.BFH_SCALEFIT, 2, 1) self.GroupBorderSpace(10, 10, 10, 10) self.GroupBegin(1100, c4d.BFH_SCALEFIT, 2, 1) self.AddButton(1021, c4d.BFH_MASK, initw=0, inith=0, name="Width:") self.AddEditNumberArrows(1022, c4d.BFH_MASK, initw=70, inith=0) self.AddButton(1031, c4d.BFH_MASK, initw=0, inith=0, name="Height") self.AddEditNumberArrows(1032, c4d.BFH_MASK, initw=70, inith=0) self.GroupEnd() self.AddButton(1051, c4d.BFH_LEFT, initw=100, inith=20, name="Center") self.GroupEnd() self.AddButton(1033, c4d.BFH_MASK, 100, 20, "Cut") self.AddCheckbox(1034,c4d.BFH_LEFT,100,10,"Show In Picture View ") return True def InitValues(self): self.SetInt32(1022, self.parameters['width']) self.SetInt32(1032, self.parameters['height']) self.SetBool(1034,self.parameters['showbmp']) if self.parameters['path']: self.SetString(1012, self.parameters['path']) return True class S_ScreenShot(plugins.ToolData): subdialog = None def __init__(self): self.data = {'width':512,'height':512,'offset':c4d.Vector(0),'path':'','name':'','showbmp':False} self.subdialog = S_ScreenShot_Dialog(self.data) #self.last_offset = c4d.Vector(0) def set_para_self(self,data): # if data[1]: self.data['path'] = data[1] # path if data[2]: self.data['name'] = data[2] # name def Message(self,doc, data, type, t_data): if type == PLUGIN_ID: #get commanddata plugins message self.set_para_self(data) # update tool gui parameter self.subdialog.update(True) return True return True def Draw(self, doc, data, bd, bh, bt, flags): DrawBox((self.data['width'],self.data['height']), self.data['offset']) return c4d.TOOLDRAW_NONE def MouseInput(self, doc, data, bd, win, msg): mx = msg[c4d.BFM_INPUT_X] my = msg[c4d.BFM_INPUT_Y] device = 0 #print msg[c4d.BFM_INPUT_CHANNEL],c4d.BFM_INPUT_MOUSELEFT,c4d.BFM_INPUT_MOUSERIGHT,c4d.BFM_INPUT_MOUSEMIDDLE if msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSELEFT: device = c4d.KEY_MLEFT elif msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSERIGHT: device = c4d.KEY_MRIGHT elif msg[c4d.BFM_INPUT_CHANNEL] == c4d.BFM_INPUT_MOUSEMIDDLE: device = c4d.KEY_MMIDDLE else: return True dx = 0.0 dy = 0.0 win.MouseDragStart(button=device, mx=int(mx), my=int(my), flags=c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE | c4d.MOUSEDRAGFLAGS_NOMOVE) result, dx, dy, channel = win.MouseDrag() while result == c4d.MOUSEDRAGRESULT_CONTINUE: mx += dx my += dy # continue if user doesnt move the mouse anymore if dx == 0.0 and dy == 0.0: result, dx, dy, channel = win.MouseDrag() continue if msg[c4d.BFM_INPUT_QUALIFIER] & c4d.QSHIFT: self.data['offset'] = c4d.Vector(dx, dy, 0) + self.data['offset'] if msg[c4d.BFM_INPUT_QUALIFIER] & c4d.QCTRL: # scale = dx * 0.0005 + 1.0 self.data['width'] *= scale self.data['height'] *= scale self.subdialog.update() #set camera parameter c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW | c4d.DA_NO_THREAD) result, dx, dy, channel = win.MouseDrag() return True def AllocSubDialog(self, bc): self.subdialog = S_ScreenShot_Dialog(self.data) return self.subdialog #always return new instance if __name__ == "__main__": dir, file = os.path.split(__file__) plugins.RegisterToolPlugin(id=PLUGIN_ID, str="tool_test", info=0, icon=None, help="", dat=S_ScreenShot())
This is the screen recording of the crash of the above code example:
Hi, i use a CommandData plugins to creat a button to active my tool plugins,and use tool.Message(123) to pass messages to tool plugins and refresh the gui parameters of tool plugins. In practice it is: When I click the button, the tool is activated, and some str parameters of the tool are set, and then the changed parameters are displayed. As shown below image1, I will set some strings to these 2 gui elements
image1:
Here's a screen recording showing c4d crashing:
I tried to find the reason, I found that c4d does not crash when I activate the tool by click button, without setting the parameters of the tool!
two plugins use python! Thanks for any help!
Hi, i read python sdk BaseContainer.FindIndex() return a bool but actually return a dict
@ferdinand Thanks!
Hi, Use MenuInitString() change checked/unchecked state of menu item, how to get checked/unchecked state? Thanks for any help!