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:
