I had some fun trying to recreate @Sholmedal‘s Python Tag Vertex Map tools which he showed at his presentation at IBC 2014. I ended up with some different Python Tags.

N.B. This post is kind of obsolete now since you can do all kind of crazy stuff with fields in R20. I’ll keep this here anyway for learning purposes.

Falloff setup
This setup creates weight values to the Vertex Map. Control position with a Null.

import c4d
from c4d import utils as u

def main():
    vertexMap = op[c4d.ID_USERDATA,1] # Get Vertex Map tag
    mind = op[c4d.ID_USERDATA,2] # User Data: Minumum distance
    maxd = op[c4d.ID_USERDATA,3] # User Data: Maximum distance
    spline = op[c4d.ID_USERDATA,4] # User Data: Remap spline
    
    obj = vertexMap.GetObject() # Get object that Vertex Map uses
    pts = obj.GetAllPoints() # Get object's all points
    null = op.GetObject() # Get null object that Python Tag uses
    null[c4d.NULLOBJECT_RADIUS] = maxd # Set null's radius
    nullPosition = null.GetMg().off # Get null's position vector
    array = [0.0] # Initialize list
    if len(array) != len(pts): # If array is not same size as object's point count
        diff = len(pts) - len(array) # Get difference
        array.extend([0.0]*diff) # Extend array
    for i in xrange(len(pts)): # Iterate through points
        point = pts[i] # Get point
        distance = (nullPosition - point).GetLength() # Calculate distance
        value = u.RangeMap(distance,mind,maxd,1,0,False,spline) # Remap value
        array[i] = u.Boxstep(0,1,value) # Clamp value between zero and one
    vertexMap.SetAllHighlevelData(array) # Set the data for the Vertex Map

vertex_map_python_tag_falloff.c4d

Math
Combine two Vertex Maps together with different math operations, like add, substract and intersect.

import c4d
import operator as o

def main():
    # User data
    tagA = op[c4d.ID_USERDATA,1] # Get Vertex Map tag A
    tagB = op[c4d.ID_USERDATA,2] # Get Vertex Map tag B
    tagC = op[c4d.ID_USERDATA,3] # Get Output Vertex Map tag
    func = op[c4d.ID_USERDATA,4] # Math operation selection
    invert = op[c4d.ID_USERDATA,5] # Invert checkbox
    
    dataA = tagA.GetAllHighlevelData() # Get Vertex Map A's data
    dataB = tagB.GetAllHighlevelData() # Get Vertex Map B's data
    if func == 0: # If add
        dataC = map(o.add, dataA, dataB) # Add A and B
    elif func == 1: # If substract B from A
        dataC = map(o.sub, dataA, dataB) # Subtract B from A
    elif func == 2: # If substract A from B
        dataC = map(o.sub, dataB, dataA) # Subtract A from B
    elif func == 3: # If intersection
        dataC = map(o.mul, dataB, dataA) # Intersection
    if invert == True: # If invert checkbox is ticked
        for i in range(0, len(dataA)): # Loop through array
            dataC[i] = 1-dataC[i] # Invert value
    tagC.SetAllHighlevelData(dataC) # Set the data for the Vertex Map

vertex_map_python_tag_math.c4d

Remap
With this you can remap source data with a spline to something different.

import c4d
from c4d import utils as u

def main():
    source = op[c4d.ID_USERDATA,1] # User Data: Source Vertex Map tag
    target = op[c4d.ID_USERDATA,3] # User Data: Output Vertex Map tag
    spline = op[c4d.ID_USERDATA,4] # User Data: Remap spline
    sourceData = source.GetAllHighlevelData() # Get Vertex Map data
    array = [0.0] # Initialize list
    if len(array) != len(sourceData): # If array is not same size as sourceData list
        diff = len(sourceData) - len(array) # Get difference
        array.extend([0.0]*diff) # Extend array
    for i in xrange(0, len(sourceData)): # Iterate through data
        value = u.RangeMap(sourceData[i],0,1,0,1,False,spline) # Remap data
        array[i] = u.Boxstep(0,1,value) # Clamp value between zero and one
    target.SetAllHighlevelData(array) # Set the data for the output Vertex Map

vertex_map_python_tag_remap.c4d

Decay
With this you can decay source Vertex Map.

import c4d

array = [0.0] # Initialize global list
def main():
    global array # Get access to global list
    source = op[c4d.ID_USERDATA,1] # User Data: Source Vertex Map tag
    target = op[c4d.ID_USERDATA,3] # Data Data: Output Vertex Map tag
    decay = op[c4d.ID_USERDATA,2] # User Data: Amount of decay in percentage
    sourceData = source.GetAllHighlevelData() # Get source Vertex Map data

    if len(array) != len(sourceData): # If array is not same size as sourceData list
        diff = len(sourceData) - len(array) # Get difference
        array.extend([0.0]*diff) # Extend array
    for i in xrange(0, len(sourceData)): # Iterate through data
        array[i] = array[i]+sourceData[i] # Value is prev value + source value
        if array[i] > 1: # If value is over '1'
            array[i] = 1.0 # Clamp value to '1'
        if array[i] > 0: # If value is over '0'
            array[i] = array[i]-decay # Decay value
        if array[i] < 0: # If value is below '0'
            array[i] = 0.0 # Clamp value to '0'
    target.SetAllHighlevelData(array) # Set the data for the output Vertex Map

vertex_map_python_tag_decay.c4d

Cinema 4D, Python, Tag