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).
I have a list of thousands of points where I'd like to add a brightness value to each of them to drive material emission and instance spheres onto the points. I've been reading posts like this and this--how would you approach this type of task in python?
I can setup a cloner object in multi instance mode but I'm not clear if it's possible to pass the brightness values to the (invisible) motagdata tag... Would a python generator be a better way to go?
Hello @tom_01,
Thank you for reaching out to us.
Would a python generator be a better way to go?
It depends a bit on how this question is meant. In general, it is not advisable to try to recreate a MoGraph cloner implementation from scratch in Python, as the result would likely not be very fast. But if you want to just write a thin wrapper, i.e., a generator which uses a MoGraph cloner in its output to simplify a specific setup, there is nothing which prevents you from doing this.
The rest of your question is unfortunately a bit ambiguous. It is unclear to me:
If you want to go route 2, I do not really understand what the question is. If you want to go route 3, this can be almost entirely done with out of the box MoGraph.
Which will give you a set of Sphere clones cloned onto Target where the luminance of each clone is driven by the effector Random. You now just have to replace steps 7 and 8, the random effector, with a custom Python effector setup which sets the color of a clone depending on your data. Find an example which does that at the end of this posting.
Cheers, Ferdinand
The result:
The file: vertexmap_clones.c4d The code:
"""Example for driving the color of clones with a vertex map. """ import c4d op: c4d.BaseObject # The python effector def main() -> bool: """Executed by Cinema 4D to evaluate the clones of the cloner. This code assumes the Python effector to be in "Full Control" mode. """ # Get the MoData from the cloner and and the vertex map which has been linked in the user data # of the Python effector. moData: c4d.modules.mograph.MoData = c4d.modules.mograph.GeGetMoData(op) if moData is None: return False vertexMap: c4d.VariableTag = op[c4d.ID_USERDATA, 1] if not isinstance(vertexMap, c4d.VariableTag): return False # Get the data, the weights, from the vertex map and bail if they do not match the number of # clones. weights: list[float] = vertexMap.GetAllHighlevelData() if len(weights) != moData.GetCount(): return False # We now simply write the weights as an array of vectors. This works because in this setup the # clones are cloned onto the same mesh for which the vertex map has been generated for. The # vertex map and clones therefore share an index order, i.e., both the n-th weight and clone # will have been constructed for the same vertex. # # If necessary, this relation could also be given up (to for example use vertex maps/input data # which has not been generated for the same mesh), but then one would have to perform closest # element lookups which are quite expensive to do. colors: list[c4d.Vector] = [c4d.Vector(w, w, w) for w in weights] # Write the data as the color array into the clone data. moData.SetArray(c4d.MODATA_COLOR, colors, False) return True
Hi Ferdinand. Thank you for the thorough response. Apologies for the ambiguity on my part.
For a test project I wanted to fetch star coordinates (for ~100K–1M+ stars) and their brightness values. Then instance Redshift spheres onto them with a material where the brightness of each point is piped into the material's emission.
This was a test project to get started with python. I also wanted to see if c4d has a way of working with points and attributes. I don't think the real-world (galaxy?) data is available, but ideally each star would also have a radius, which would drive the sphere scales/sizes.
I'm familiar with cloner/effector/field setups, but I was looking for a programatic approach. I don't know how to pass specific values to each point (brightness in this case) and then to clones with effectors/fields.