Skip to content

Instantly share code, notes, and snippets.

@gr4ph0s
Last active November 14, 2021 17:47
Show Gist options
  • Save gr4ph0s/1bc0075ce733afb8b6678531a37f065b to your computer and use it in GitHub Desktop.
Save gr4ph0s/1bc0075ce733afb8b6678531a37f065b to your computer and use it in GitHub Desktop.
Exemple for get / set VertexMap inside c4d through python.
# coding: utf-8
"""
Exemple for get / set VertexMap inside c4d through python.
Show an exemple of GetLowlevelDataAddressR / GetLowlevelDataAddressW
"""
__author__ = 'Adam Maxime - Graphos <gr4ph0s(at)hotmail.fr>'
__version__ = '1.0'
import c4d
import array
def vertex_map_to_list(vertex_map):
# vertex_map => c4d.Tvertexmap
buffer = vertex_map.GetLowlevelDataAddressR()
if buffer is None: return None
floatArray = array.array('f')
floatArray.fromstring(buffer)
weight_list = floatArray.tolist()
return weight_list
def list_to_vertex_map(op, weight_list):
# op => c4d.BaseObject or c4d.Tvertexmap
# weight_list => list
if not op: return None
vertex_tag = None
# if it's a baseObject we create a vertex_map
if isinstance(op, c4d.BaseObject):
vertex_tag = c4d.VariableTag(c4d.Tvertexmap, op.GetPointCount())
op.InsertTag(vertex_tag)
else:
vertex_tag = op
# Check the list filled into the function get correct point number
if len(weight_list) != vertex_tag.GetDataCount(): return None
# Get the write buffer array
buffer = vertex_tag.GetLowlevelDataAddressW()
if buffer is None: return None
# Transle list to float array
floatArray = array.array('f')
floatArray.fromlist(weight_list)
data = floatArray.tostring()
buffer[:len(data)] = data
return True
def set_pt_weight(vertex_map, pt_id, pt_weight):
# vertex_map => c4d.Tvertexmap
# pt_id => int
# pt_weight => float
if not vertex_map: return None
# Check the pt_id filled is correct
if pt_id > vertex_map.GetDataCount() or pt_id < 0: return None
# Get the write buffer array
buffer = vertex_map.GetLowlevelDataAddressW()
if buffer is None: return None
# Translate float into Bytseq float
floatArray = array.array('f')
floatArray.append(pt_weight)
data = floatArray.tostring()
# float get a size of 4. Since pt_id are ordered we just have to make pt_id*4 to get the start of the array
buffer[pt_id*4: pt_id*4+4] = data
return True
def main():
# Get User data
vertex_map = op[c4d.ID_USERDATA, 1]
# Check if filled data are valid
if not vertex_map: return
if not vertex_map.CheckType(c4d.Tvertexmap): return
# Get all the weight
weight_list = vertex_map_to_list(vertex_map)
# Change value inside the list
for i, value in enumerate(weight_list):
weight_list[i] = 0.75
# Set all the weights with the previous modification of the list
list_to_vertex_map(vertex_map, weight_list)
# Set the weight of a particular pt_id
set_pt_weight(vertex_map, 0, 0.25)
c4d.EventAdd()
@donovankeith
Copy link

Thanks for this. I found it really helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment