Different Motext Letters on Cloner Vertexes



I’m trying to get a poly object’s vertex index numbers and put them in a Motext object that is cloned with a Mograph Cloner onto each vertex of the poly object, so I can see the vertex index numbers when rendered.
How can I change each of the cloned Motext objects to read the different vertex numbers? Right now all the Motext numbers are the same because of what was entered into the Text field of the Motext object.



Sounds like would need a scripted solution, but you can make multiple text children which the cloner could index through ( very manual process though! especially if your talking a large amount of points )


what Brian said.
Although you can limit the amount of manual work.

Fastest setup I can think of :

  • put multiple Copies of your MoText under the Cloner ( at least as many as there’s Vertex Points )
  • The Cloner puts 1 Clone onto each vertex point so it takes care of the counting.
  • Use a Hierarchy Node to loop through the MoText Objects and input the index number into the Text field of each corresponding MoText.

If you put a lot more copies under the Cloner than you actually need you can even add Points to the Mesh or keep the Object Parametric and the changes in Point Count automatically get reflected by the MoText Objects, until you run out of copies ( in which case you would need to add more copies) .

I’m sure you get the picture.

In case of doubt,
check out this quick setup :

hope this helps,


aww yes nice, iterating through the hierarchy to populate the text input fields will definitely remove a lot of the manual work I was thinking. slick. still are you talking 100 points or 50,000 points?


To manage more Points it may be a good idea to use Per Anders’ Clone-Info-hierarchy with simple Text Objects. An Extrude Nurbs parenting the Reference of the Hierarchy allows you to quickly enable / disable the geometry as needed for faster preview.

It also auto-generates the exact number of Text Objects you need, on the fly.
Check out this example with an animated Point Count


It takes a bit more preparation to set up, but it’s far more flexible.

hope this helps,


My guess is using a Generator would be more efficient.
See code example for use in a PyGenerator.
As I have no experience with the FontData, I made a simple
hack to do font selection from a MoText object placed as a child
of the generator.
[edited code]

# moNUMBERS example tcastudios.com©2012
# moNUMBERS must have a MoText Object as a child for Font control.
# Place the moNUMBERS Generator as a child of a PointObjects or
# a Correction Deformer.

import c4d

def main():
    p = c4d.BaseObject(c4d.Onull)
    poly = op.GetUp()
    if not poly or (not poly.CheckType(c4d.Opoint) and not poly.CheckType(1024542)):
        return p
    mo  = op.GetDown()
    if not mo or not mo.CheckType(1019268):
        return p
    mo[c4d.PRIM_TEXT_TEXT] = ''
    pcount = poly.GetPointCount()
    point  = poly.GetAllPoints()
    for i in xrange(pcount):
        nr = c4d.BaseObject(1019268)
        nr[c4d.PRIM_TEXT_FONT]          = mo[c4d.PRIM_TEXT_FONT]
        nr[c4d.PRIM_TEXT_ALIGN]         = mo[c4d.PRIM_TEXT_ALIGN]
        nr[c4d.PRIM_TEXT_HEIGHT]        = mo[c4d.PRIM_TEXT_HEIGHT]
        nr[c4d.PRIM_TEXT_TEXT]          = str(i)
    return p


very nice, Lennart.

I was playing with a variable Point Count and animated Points, and at first I ran into some problems with real time updating the Generator, but turned out to be nothing that unchecking Optimize Cache couldn’t fix .

Also had some issues with Effectors in Point Mode (for moving the Reference Object’s Points), since they also affected the MoText Letters, but rearranging the hierarchy and the route in your code fixed that as well.

This is definitely flexible, and super easy to setup.
Nice and clean.

great stuff !



I see, then maybe this would be more efficient.
Still needs a MoTex object as a child for font control
but also a UserData Linkfield for a Cloner or Matrix Object.
This way the resulting mo numbers are free to be placed
according to the Cloner and its effectors etc.


# motexCLONE example tcastudios.com©2012
# motexCLONE must have a MoText Object as a child for font control.
# Add a UserData LinkField for Cloner/Matrix Object.

import c4d
from c4d import gui
from c4d.modules import mograph as mo

def MoCheck(obj):
    md = mo.GeGetMoData(obj)
    if md == None: return None,None,None
    clist  = []

    marr   = md.GetArray(c4d.MODATA_MATRIX)
    farr   = md.GetArray(c4d.MODATA_FLAGS)
    ccount = len(marr) # Initial Clone count
    for i in xrange(ccount):
        if ((farr[i]&(c4d.MOGENFLAG_CLONE_ON)) and (not (farr[i]&(c4d.MOGENFLAG_DISABLE)))): #Only if the clone is visible
            clist.append(marr[i]) # Add Clone Matrix to the list
        else: ccount -= 1 # Adjust Clone count

    return len(marr),ccount,clist

def main():
    p     = c4d.BaseObject(c4d.Onull)
    cl    = op[c4d.ID_USERDATA,1] # <--- UserData LinkField for Cloner/Matrix Object
    if not cl or (not cl.CheckType(1018544) and not cl.CheckType(1018545)):
        return p
    mot  = op.GetDown()
    if not mot or not mot.CheckType(1019268):
        return p
    mot[c4d.PRIM_TEXT_TEXT] = ''

        pdata = MoCheck(cl)

        return p
    for i in xrange(pdata[1]):
        nr = c4d.BaseObject(1019268)
        nr[c4d.PRIM_TEXT_FONT]          = mot[c4d.PRIM_TEXT_FONT]
        nr[c4d.PRIM_TEXT_ALIGN]         = mot[c4d.PRIM_TEXT_ALIGN]
        nr[c4d.PRIM_TEXT_HEIGHT]        = mot[c4d.PRIM_TEXT_HEIGHT]
        nr[c4d.PRIM_TEXT_TEXT]          = str(i)

    return p


That works nicely, Lennart, and it’s a lot more practical to control the positioning of the clones with Mograph indeed, but alas, that was not what I meant. :wink:

I was thinking about deforming the Reference Mesh.

Let me walk you through my reasoning :
This is the "normal" hierarchical setup :
- Primitive
-- Correction Deformer
---- Python Generator
------ moText

If I now want to deform the shape of my Primitive, for example with a Random Effector set to Point Deformation,  I would place the Random Effector under the Primitive, right before the Correction Deformer.

Ayayay... That deforms the Generator as well, though !! :(

So to fix this I would alter the hierarchy to something like
-- Primitive
---- Random Effector
---- Correction Deformer
-- Python Generator
---- moText

Now the Correction Deformer can read the Deformation nicely, but the Python Generator doesn't get deformed.
In moNUMBERS I would only need to edit the poly line to something like    "poly = op.GetPred().GetDown().GetNext()"
and I am good to go.

This is no longer easily possible with motexCLONE :(


(learning tons from your examples.)


Fantastic guys!

@Brian: I probably won’t be using more than a handful of vertices, so I can go the manual route if I have to.

@douwe: Great! This will work just fine. I’m partial to your solution that uses Per’s Null generator. Thanks.

@Lennart: This solution looks very interesting! More Python to study :slight_smile:

This is an example of why this is such a great forum.
Thanks guys


Yip. That works, douwe.

That’s the first thing I tried when I got Lennart’s PyGenerator working was to put a deformer in there. I also tried a stop tag and that didn’t work. I wonder if it has anything to do with the fact that the MoText objects are not inserted into the hierarchy and just remain in the generator.


Class, pay attention! :slight_smile:

The second example solves all that.
Simply add a Matrix object in Object Mode to the scene.
Have your mesh as Object source.
Then put the Matrix into the linkfield of the PyGenerator,
-not- as a child of anything, done!..

The second, less ideal, solution would be to use a linkfield for
the mesh in my first example, for keeping it outside the hierarchy,
but then you’re into making your own “clone to deformed mesh” mess (using GetCashe/DeformCache etc.)



Of course you’re right, Lennart.

It took me a good night’s sleep to realize that motexCLONE doesn’t require the same hierarchical structure as its predecessor.

No need for a Correction Deformer. No need for the Generator to be a Child of the mesh.
No need for adapting the route to the mesh in the code.

It works right out-of-the-box.

Lesson learned.
you’re a clever fellow, Lennart. (and it’s amazing how fast you work)



Aaaah, beautiful! The Matrix object works perfectly, Lennart.

I’m getting an error when I use the Cloner object in the link field instead of the Matrix object. The error is “TypeError: an integer is required”.

Thanks Teach! Nothing like a well deserved rap on the knuckles to get a student going in the morning :wink:


That’s only because you’re using a Cloner Object without a Child. It needs something to clone. Simply feeding it a Null will do.



That’s it, douwe. It works now. Thanks!


I can’t get this to work at all. Any chance someone could post an example file?



mmm… you should have all the info you need. where do you get stuck ?



Here’s what I came up with, JDP. Seems to be working nicely.


Nice to see you here again JDP.
It’s been a while.

Not sure what version you have. But this does not work in R12. Only in R13.
There’s a ton of little things Maxon added in R13 that most people wouldn’t even know about. So it’s very easy to make things that don’t work in R12 now. That seem like they should work in both versions. But don’t.