Thanks for the preliminary feedback.
I'll wait patiently
Posts made by datamilch
-
RE: Docked Dialog Problem with width of CUSTOMGUI_FILENAME
-
Docked Dialog Problem with width of CUSTOMGUI_FILENAME
hi there,
i'm working on a command plugin with gedialog, that i want to dock in the layout.
one of the gui elements is AddCustomGui c4d.CUSTOMGUI_FILENAME.
the paths that are stored can be quite long.
the problem is, that the dialog wants to show the complete string, which makes the dialog extremely wide.
this only happens when the dialog is docked. then i can not scale the dialog smaller then the length of the string/filename.
if the dialog is not docked i can scale it smaller and the overflowing string is hidden.
sadly AddCustomGui has no properties initw and inith. i tried some combinations of flags but had no success.
am i missing something?i could place the element in a scrollgroup, but then the "open document" button might be hidden in the part that is scrolled away.
any other options or workarouds?cheers, sebastian
here is the code
import c4d, typing ID_PLUGIN_CMD: int = 1025245 class MainDialog(c4d.gui.GeDialog): ID_GRP_MAIN = 1000 ID_TEXT_1 = 1001 ID_TEXT_2 = 1002 extra_long_str = "this is some realy looooooooooooooooooooooooooooooooong text" def __init__(self) -> None: super().__init__() def InitValues(self) -> bool: return super().InitValues() def CreateLayout(self) -> bool: self.SetTitle("My Dialog") self.GroupBegin(id=self.ID_GRP_MAIN, flags=c4d.BFH_SCALEFIT, cols=1) self.GroupSpace(spacex=5, spacey=5) self.GroupBegin(id=0, flags=c4d.BFH_SCALEFIT, cols=2) self.AddStaticText(0, c4d.BFH_LEFT, name="path", initw=0 ) bc = c4d.BaseContainer() self.AddCustomGui(self.ID_TEXT_1, c4d.CUSTOMGUI_FILENAME, '' ,c4d.BFH_SCALEFIT, 0, 0, bc,) self.AddStaticText(0, c4d.BFH_LEFT, name="text", initw=0 ) self.AddEditText(self.ID_TEXT_2, c4d.BFH_FIT, 20,10 ) self.GroupEnd() self.GroupEnd() self.SetString( id=self.ID_TEXT_1, value=self.extra_long_str ) self.SetString( id=self.ID_TEXT_2, value=self.extra_long_str ) return super().CreateLayout() def Command(self, cid: int, msg: c4d.BaseContainer) -> bool: return super().Command(cid, msg) class DialogManagerCommand (c4d.plugins.CommandData): dialog: typing.Optional[MainDialog] = None def Execute(self, doc: c4d.documents.BaseDocument) -> bool: if self.dialog is None: self.dialog = MainDialog() if self.dialog.IsOpen() and not self.dialog.GetFolding(): self.dialog.SetFolding(True) else: self.dialog.Open(c4d.DLG_TYPE_ASYNC, ID_PLUGIN_CMD, -2, -2, defaultw=300, defaulth=200) return True def RestoreLayout(self, secret: any) -> bool: if self.dialog is None: self.dialog = MainDialog() return self.dialog.Restore(ID_PLUGIN_CMD, secret) def GetState(self, doc: c4d.documents.BaseDocument) -> int: result: int = c4d.CMD_ENABLED if self.dialog: if self.dialog.IsOpen() and not self.dialog.GetFolding(): result |= c4d.CMD_VALUE return result def RegisterPlugin() -> bool: return c4d.plugins.RegisterCommandPlugin( id=ID_PLUGIN_CMD, str="filename_test_01", info=c4d.PLUGINFLAG_SMALLNODE, icon=None, help="", dat=DialogManagerCommand()) def main(): if not RegisterPlugin(): raise RuntimeError( f"Failed to register {DialogManagerCommand} plugin." ) if __name__ == '__main__': main()
-
RE: Message from Object or Tag to CommandData/GeDialog Plugin
oh well ... tried option B) as planned.
a python tag tracks the dirty status of some objects and starts a c4d.SpecialEventAdd(). this is received as a core message in my dialog. but when i go looking for the dirty objects, they are not dirty anymore.
my workaround for now is, to have a str userdata on the pyhon tag. once the tag detects a dirty object, it writes its name into the str userdata. my dialog can then read the name of the object and find it. feels quite cumbersome but works for now.would there be a better/more hidden way to store the data?
-
Message from Object or Tag to CommandData/GeDialog Plugin
hi there,
i have a bunch of objects with userdata. then i have a GeDialog plugin with mostly the identical userdata. the dialog plugin is intended to control the objects from one common panel. but there might be cases, where the objects are adjusted direktly, so the dialog needs to be updated. i'm looking for a solution for this case.
A)
am i correct, the change of DIRTYFLAGS_DATA can not be tracked from GeDialog directly via the message system? i could only track things, that trigger a global event?
i suppose it could be done with a timer, that checks the doc/objects every few millyseconds, but that feels very unprecise.B)
with a python tag i can easily track the dirty status of objects, but from what i've read here, i can not send data (list of dirty objects) direkcly to the dialog/command plugin. i can just call my dialog and make it aware to look and find the dirty objects.C)
there also seems to be c4d.GePluginMessage() and PluginMessage(). but i never found a clear statement, which plugin types are supported. i never even got c4d.GePluginMessage() to return True, which made me doubt myself a bit.so i would try to go with option B).
any objections or completly different suggestions?
cheers sebastian -
RE: use thicken generator inside a python generator
hi @i_mazlov,
ok, good to know.
i also tried to insert the thicken generator into a temp_doc, activating the selections and executing passes. but that didn't work either. -
RE: MCOMMAND_SELECTALL and MCOMMAND_SELECTINVERSE not working?
@i_mazlov Thanks!
makes sens. seems i only used the forgiving commands until now.the code is run in a python generator. so by returning the object, it will be inserted into the scene.
-
MCOMMAND_SELECTALL and MCOMMAND_SELECTINVERSE not working?
hi there,
i was shifting around some selections and noticed that some modeling commands seem to have no effect.
MCOMMAND_SELECTALL
MCOMMAND_SELECTINVERSE
i realize i can use SelectAll on the BaseSelect. and i could surely build a loop, to invert the selection. but why are these commands there? they even return true, despite doing nothing.this is my code and a demo file:
import c4d doc: c4d.documents.BaseDocument op: c4d.BaseObject def main() -> c4d.BaseObject: obj = op[c4d.ID_USERDATA,1].GetClone() bs_points = obj.GetPointS() #bs_points.SelectAll( obj.GetPointCount()-1 ) # will select all points c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTALL, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) # not working c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTSHRINK, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) c4d.utils.SendModelingCommand( c4d.MCOMMAND_SELECTINVERSE, [ obj ], c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc) # not working bc = c4d.BaseContainer() bc[c4d.MDATA_CONVERTSELECTION_LEFT] = 0 # 0 = points bc[c4d.MDATA_CONVERTSELECTION_RIGHT] = 1 # 1 = edges bc[c4d.MDATA_CONVERTSELECTION_TOLERANT] = False # tolerant conversion res = c4d.utils.SendModelingCommand( c4d.MCOMMAND_CONVERTSELECTION, [ obj ], bc=bc, doc=doc) res = c4d.utils.SendModelingCommand( c4d.MCOMMAND_EDGE_TO_SPLINE, [ obj ], doc=doc) return obj
-
RE: use thicken generator inside a python generator
circumvented the problem by generating 3 thicken objects - one for each surface part (shell, start cap, end cap). then created selection tags and stitched everything together with a connector object.
-
use thicken generator inside a python generator
hi there,
the thicken generator object is a super cool and powerful tool. i'd like to use it inside of a python generator object, to create some more complex geometry. for this i need some of the selection options of the thicken generator. but activating e.g. 'shell' selection from within the python generator will mess up the output geometry of the thicken object and not generate any polygon selection tag. see attached c4d file.
after converting the python generator you have access to the built hierarchy and the generated thicken generator. when you select it and then try to activate some selection options ther will be no selection tags created. so it looks like something in the thicken generator is broken/uncomplete, when it is created within a python generator object.
is there any way to make this work, or is this a special case/limitation?def main() -> c4d.BaseObject: source_obj = c4d.BaseObject( 5170 ) source_obj[c4d.PRIM_CYLINDER_CAPS] = False thicken = c4d.BaseObject( 1060179 ) source_obj.InsertUnder( thicken ) thicken[c4d.SOLIDIFYGENERATOR_SELECTION_POLYGON_BOUNDARY] = 1 # does not create tag, will mess up (delete) geo of the selected polys return thicken
-
RE: issue with inserting fieldlayers in r2024
hi ilia @i_mazlov,
thaks for the advice about threading and the dummy document and the fishy part.I continued testing the last days and noticed that it seems to work, when i insert a clone of the fieldlayer.
-
issue with inserting fieldlayers in r2024
hi there,
I'm having a weird issue with fieldlayers in r2024.
I want to add a layer to a fieldlist. In r2023 it worked quite fine. Now I get a reference Error.
But when I print anything, the error is not raised.
In my example I use a python generator, but it seems to happen with a python tag, too.
Or am I using/inserting the fieldlayers wrong?cheers sebastian
python generator :
import c4d def main() -> c4d.BaseObject: obj = c4d.BaseObject(c4d.Ocube) res = c4d.utils.SendModelingCommand( c4d.MCOMMAND_MAKEEDITABLE, [obj], c4d.MODELINGCOMMANDMODE_ALL, doc = doc ) if not res: print("error") else: obj = res[0].GetClone() vertex_tag = obj.MakeVariableTag( c4d.Tvertexmap, len(obj.GetAllPoints()) ) vertex_tag.SetName( "vertex_highlight_reinforce" ) vertex_tag[c4d.ID_TAGFIELD_ENABLE] = 1 fields = vertex_tag[c4d.ID_TAGFIELDS] f_layer_1 = c4d.modules.mograph.FieldLayer( c4d.FLquantize ) fields.InsertLayer( f_layer_1 ) vertex_tag[c4d.ID_TAGFIELDS] = fields #print ("") # with print active, no error will be raised return obj
results in the following error:
ReferenceError: the object 'c4d.modules.mograph.FieldLayer' is not alive -
RE: Create folder in Volume Builder
hi @i_mazlov,
thanks for the answer. good to know about this status / limitation.
for my current case I found a solution without folders.. -
RE: fieldlayer with variable tag
found the solution ... the corresponding type is called: FLweight
-
fieldlayer with variable tag
hi there,
I'm trying to achieve the following:
A python generator that creates an object with a vertex map (A). vertex map (A) is then inserted in a second vertex map (B) to be able to blur (A) with the mode 'average'. (If there is another way to blur a vertex map directly in (A) this would be great, too) You can see my test-setup without the python generator in the screenshot and it works so far.Now with python I have to create fieldlayers with the correct type to make it work. But it looks like the Variable Tag is missing in the list of types. I hope it's not a limitation of of the api.
My test-file is attached. Here is the code of the generator:
from typing import Optional import c4d doc: c4d.documents.BaseDocument # The document evaluating this python generator op: c4d.BaseObject # The python generator hh: Optional["PyCapsule"] # A HierarchyHelp object, only defined when main is executed def main() -> c4d.BaseObject: null = c4d.BaseObject( c4d.Onull ) circle = c4d.BaseObject( c4d.Osplinecircle ) circle[c4d.PRIM_CIRCLE_RADIUS] = 150 cube = c4d.BaseObject( c4d.Ocube ) cube[c4d.PRIM_CUBE_SUBX] = cube[c4d.PRIM_CUBE_SUBY] = cube[c4d.PRIM_CUBE_SUBZ] = 40 vertex_tag = cube.MakeTag( c4d.Tvertexmap ) vertex_tag[c4d.ID_TAGFIELD_ENABLE] = 1 fields = c4d.FieldList() fields.Flush() f_layer_1 = c4d.modules.mograph.FieldLayer( c4d.FLspline ) f_layer_1.SetLinkedObject( circle ) f_layer_1[1009] = 1 # distance mode = radius f_layer_1[1003] = 50 # radius f_layer_1[1005007] = 99 # inner offset fields.InsertLayer( f_layer_1 ) vertex_tag[c4d.ID_TAGFIELDS] = fields displacer = c4d.BaseObject( c4d.Odisplacer ) shader = c4d.BaseShader( c4d.Xcolor ) displacer.InsertShader( shader ) displacer[c4d.ID_MG_SHADER_SHADER] = shader fields_displace = c4d.FieldList() fields_displace.Flush() f_layer_2 = c4d.modules.mograph.FieldLayer( c4d.FLpolygonobject ) # should be type variable tag f_layer_2.SetLinkedObject( vertex_tag ) fields_displace.InsertLayer( f_layer_2 ) displacer[c4d.FIELDS] = fields_displace circle.InsertUnderLast( null ) cube.InsertUnderLast( null ) displacer.InsertUnder( cube ) return null
-
Create folder in Volume Builder
hi there,
i am trying to add a folder/group to the object list of a volume builder.
but i have no idea how. there is nothing in the the documentation and no examples either.
is this even possible?as an alternative i could probably nest multiple volume builders, but folders would be more elegant i think.
the current test code:
def main() -> None: # create objects null = c4d.BaseObject( c4d.Onull ) cube = c4d.BaseObject( c4d.Ocube ) hole = c4d.BaseObject( c4d.Ocylinder ) hole[c4d.PRIM_CYLINDER_HEIGHT] = 300 # create volume builder vb = c4d.BaseObject( c4d.Ovolumebuilder ) vm = c4d.BaseObject( c4d.Ovolumemesher ) # insert into scene doc.InsertObject( null ) cube.InsertUnderLast( null ) hole.InsertUnderLast( null ) vm.InsertUnderLast( null ) vb.InsertUnderLast( vm ) # insert into volume builder vb.AddSceneObject( cube ) vb.AddSceneObject( hole ) vb.SetBoolMode( 1, c4d.BOOLTYPE_DIFF ) c4d.CallCommand(100004748) # unfold all c4d.EventAdd() return if __name__ == '__main__': main()
-
RE: Accessing Parameters of Filters in a Volume Builder
Oh shit! I just realized the filters exist as objects in c4d ... * facepalm *
I suppose this will resolve my problems for now.Should I delete the topic?
-
Accessing Parameters of Filters in a Volume Builder
Hi there,
I'd like to access some parameters of the filters in a Volume Builder, like 'dilate and erode > offset' or the fields parameter of the smooth filter. But I don't know how.
There is nothing really in the documentation or the forum.The only thing related filters, that I found, was 'volume.SendVolumeCommand()' but suppose, this is not meant to be used with the volume builder.
VolumeBuilder.GetSettingsContainerForIndex() will return None for filter layers - but that's also what the documentation says. I attached a file to demonstrate this.def main() -> None: settings = op.GetObject() volume_builder = settings[c4d.ID_USERDATA,1] for i in range( volume_builder.GetInputObjectCount() ): bc = volume_builder.GetSettingsContainerForIndex(i) print (bc) # returns: None # the filter layer <c4d.BaseContainer object at 0x0000024296092D40> # the cube object
When I drag the parameter, that I want to change, in the console it is called 'SDFDilateandErode[c4d.ID_VOLUMEFILTER_RESHAPE_OFFSET]' but again, I have no idea how to access it.
Help would be much appreciated.
-
RE: Prevent material preview update
hi @ferdinand,
thanks for the information.
found a workaround, that is good enough so far. I use the 3d-gradient in texture space and transform the texture tag matrix as I need it. the change in color will not occur that often. -
RE: Set value of a fieldlayer parameter
hi @ferdinand,
this solved it, thanks! I suspected, that I would have to write back the data, as in many other cases. but I didn't know how exactly.As for the executable code: will do so, next time!
cheers Sebastian -
Set value of a fieldlayer parameter
good morning
I'd like to change a parameter of a fieldlayer (the radius - see attached image), but I have no luck.
I'm able to access the value, but I did not find a way to set it.
the forum search wasn't successful either, or I did not know what to look for.maybe some similar situations had been covered before.
some hints would be nice.# his is how i access the value: fields = emboss_generator[c4d.ID_USERDATA,4] f_layer = fields.GetLayersRoot().GetFirst() print ( f_layer[1002] ) # prints 7.0 # tried setting the parameter with: f_layer[1002] = .5 # or f_layer.SetParameter(1002, 0.5, c4d.DESCFLAGS_GET_NONE ) print ( f_layer[1002] ) # it will print 0.5 # but the value will not be set in the fieldlist