ok! finally, it is imporant to use the doc to get the irs !
now it works.
irs = c4d.modules.render.InitRenderStruct(doc)
is this the only / best way to check if textures are missing?
an alternative would be to actually check if the file is existing somewhere in the given paths
hi and thanks Maxime !
GetAllAssetsNew() is S22 only,
and I had problems with InitRender() and Vray Bitmaps
so I decided to manually check for the files...
I had it already, but GenerateTexturePath() shortens the code quite a bit, because I dont have to check all possible paths.
It seem GenerateTexturePath() returns the absolute path, if the file is found somewhere in the texture paths, otherwise it returns None.
needs some testing, but until now it seems to work well.
how is your ConsolePrint() different to a simple print() statement?
in my test i didn''t get a real time output with ConsolePrint()
tx adam, i just want a new "private" channel in the console window
(apart from "Default", "Python", "Renderer" and "Team Render")
to separate the log of my plugins from the normal chit-chat ...
Wouldn't a new instance of an existing interface (type) be enough for that?
(a reference to the normal python channel with a new name?)
right, its good to have this separated from the old thread.
there are two objectives mixed in here :
so, does this ConsolePrint() example print immediately?
i guess it is not possible use it for a dialog, but...
it should be possible to print into a custom logger channel?
(i've seen a plugin doing that)
would it be possible to get an example how to use
the goal would be to add a console channel for a cmd plugin
and to "live" output console messages to that channel
while the plugin is processing one of its commands.
it would also be nice to share that channel for all my plugins
and to have a way to to open (show) and clear the console
i tried to port the C++ example to python...
but i fail with
--> TypeError: unable to convert maxon.interface.Declaration to @net.maxon.interface.class-cR
(sorry this is probably a bit off topic and should be in a separate thread)
edit [ferdinand]: This thread is a follow up question for the thread Write to C4D console in real time.
but is this bug the reason, that there need to be more than one plugin in a plugin folder to get submenus?
or in other words ... is it possible to create a submenu in the plugin menu with a single command data plugin?
sorry to hijack this, but regarding adding tags to posts:
on my macbook pro 13" the taglist is higher than the screen, and you cant scroll it.
it is not possible to select "python" for example
(just for your info)
below is a simple CommandData plugin with a submenu to invoke different actions.
This works fine if more than one of these plugins (with unique Plugin Ids ofc) are in one plugin folder.
But there is no menu if there is only one plugin present in the folder.
Is there a way to create such a menu with one plugin, while not registering each menu point as separate command?
# encoding: utf-8
''' CommandData Plugin with Menu '''
PLUGIN_ID = 12345678 # Unique Plugin Id
MENUID_CMD0 = 1000
MENUID_CMD1 = 1001
id=PLUGIN_ID, str="Test", info=c4d.PLUGINFLAG_COMMAND_HOTKEY, icon=None, help=None, dat=MenuHandler())
def GetSubContainer(self, doc, submenu):
bc = c4d.BaseContainer()
bc.SetString(MENUID_CMD0, "Command 0")
bc.SetString(MENUID_CMD1, "Command 1")
def ExecuteSubID(self, doc, id):
if id == MENUID_CMD0:
if id == MENUID_CMD1:
def Execute(self, doc):
if __name__ == "__main__":
c4d.documents.KillDocument(doc) immediately closes a document without any checks
There is no c4d.documents.CloseDocument()
How would you close a document with the normal check and warning for changes that might be wanted to be saved first ?
right, c4d.ID_USERDATA .-)
but this works here, I just verified again :
create any object, add some userdata, lets say an integer with id = 1
op[c4d.ID_USERDATA, 1] # 0
op[c4d.ID_USERDATA, 1] = 123 # 123
op.GetData()[c4d.ID_USERDATA] # 123 <-- you need to set the value, first (by gui or code)
op.GetData() is a BaseContainer having a sub-BaseContainer with id=700,
so i suppose this is where the values are stored, after they have been set.
if they have not been set, op[c4d.ID_USERDATA, 1] seems to return the default value from the description.
but its kind of useless, because you need to iterate the description anyway to be sure to get all values
problem there is that if you iterate the description there are also ids for groups, separators (and other stuff?)
which are not (changeable) values, so you have to filter these out.
ok, I think I figured it out :
op[c4d.USERDATA, id] is the same as op.GetData()[c4d.USERDATA][id]
the UserData values are stored in a sub BaseContainer of op.GetData() with the id c4d.USERDATA=700
so to store all values of a BaseList2D into a HyperFile :
interesting is that even though the UserData in the GUI shows 0 for a freshly added integer
op.GetData()[c4d.USERDATA] doesnt have it unless you actually have pressed enter in the input field in the GUI.
so op.GetData()[c4d.USERDATA] is NOT reliable to have all values
for a freshly added id :
op[c4d.USERDATA,17] # 0
op.GetData()[c4d.USERDATA] # nuthin'
anyway, topic solved, i guess...
(where can you set that yourself? its not in the topic tools)