@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.
@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.
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
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.
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
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.
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
hi @i_mazlov,
thanks for the answer. good to know about this status / limitation.
for my current case I found a solution without folders..
found the solution ... the corresponding type is called: FLweight
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
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()
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?
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.
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.
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
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
Hi there,
is it possible to prevent rendering/update of the material preview of a standard c4d material?
I know it's possible for redshift materials in the preferences .. but I found nothing similar for standard c4d materials.
why I want to do this:
I need some visual feedback while working in the editor window. So when two objects are in a special constellation, the material turns red (it will be more complex with the final plugin). Currently I use a python tag to check the conditions and update the material. This works fine so far.
Now when the condition is met and the material is set to red, the rendering of the material preview is triggered. This rendering interrupts my dragging motion of the selected object and freezes the viewport for the time of the rendering. Once it has finished the viewport is updated again and shows the object at the correct position of the mouse. The rendering only takes about 1 sec, but it is an irritating interruption - even more when it occurs multiple times while dragging the object. So I'd like to prevent this.
For now my only idea is to prevent the material updates, but I'm open to other suggestions.
Another solution might be to have two separate materials and switch between the two. But ultimately I'd like to update a gradient shader (more or less continuously), so switshing is no option there.
If needed, I can prepare a demo scene ...
cheers sebastian
hi @m_adam,
hope it's ok that i reply in this old thread.
so the fastest way of doing
mg.off.x = 9.9
would be something like
off = mg.off
off.x = 9.9
mg.off = off
or might there be a shorter/cleaner way?
with longer variable names and more variables the code can become a bit unclear ...
hi @ferdinand,
thanks for the confirmation. i found a way to avoid calling setmode for now.
concerning your PS:
thats interesting, i have to pay attention to that. always had the feeling, that i could print feedback while it is running. and if there were errors in the script, it would only raise them when the running script was alble to reach these lines. e.g. after a few seconds.
or sometimes i get the errors only if an if-contition is fulfilled. so i was surprised, that it would hang instantly, even though i expected it to run at least some stuff in the beginning.
i think only syntax errors are displayed instantly.
not sure if we are talking about the same thing though.
all in all, i feel lucky that hangs occure rarely for me.
thanks again!
hi there,
i'm writing a modeling script which is quite complex at this point. now i'm experiencing very strange instant hangs of c4d when executing the script.
it was super hard to pinpoint. took me some hours.
please tell me i'm not stupid and this thing is real! ... and hopefully solvable.
a new doc with a null and an active python tag (empty) + the execution of the following script in the scripts-manager = instant hang (at least for me)
if i deactivate the python tag, the script will work.
import c4d
def main():
print ("started")
doc = c4d.documents.GetActiveDocument()
doc.SetMode(c4d.Mpolygons)
doc.SetMode(c4d.Medges)
print("ok")
return
if __name__=='__main__':
main()
when it hangs, it doesen't
what's even stranger:
the original script was obviously longer, and the file had lots of objects,
so i was incrementally reducing the script and the objects to find the bug.
while boiling down the setup, there were stages, when the script worked randomly.
then there was a stage, where it would run with 2 active python tags, but with 3 it would definitly hang.
when it hangs, it doesn't even print "started". ... my working original script would run for about 3-4 seconds, but when i added the faulty line of code, the script would hang instantly after hitting the execute button. it would not run anything at all. so i imagine there could be an error compiling the script or somehing like that.
i'd be super grateful if someone could confirm this or even tell me, what is going on.
cheers sebastian
@i_mazlov thanks ilia!!!
ok that was truly obvious
actually had to use 'c4d.documents.GetActiveDocument()' to make it work in my case ...