
manually re-selecting and re-rotating than re-scaling every single one of these handplaced objects are...well, I'm WAY too lazy for that.
thanks guys

id_property_name = "custom_id" # This is the property that contain the ID of your geos
# create the items
ctx = ix.cmds.CreateContext("bake", "project:/")
ptc = ix.cmds.CreateObject("ptc", "GeometryParticleContainer", str(ctx))
scat = ix.cmds.CreateObject("scatterer", "SceneObjectScatterer", str(ctx))
ids_property = ix.cmds.CreateObject("extract_property", "TextureExtractProperty", str(ctx))
rotation_property = ix.cmds.CreateObject("extract_property", "TextureExtractProperty", str(ctx))
scale_property = ix.cmds.CreateObject("extract_property", "TextureExtractProperty", str(ctx))
# Set items'attrs values
ix.cmds.SetValues([str(ids_property) + ".property_name"], ["id"])
ix.cmds.SetValues([str(rotation_property) + ".property_name"], ["rotate"])
ix.cmds.SetValues([str(scale_property) + ".property_name"], ["scale"])
ix.cmds.SetValues([str(scat) + ".geometry_support"], [str(ptc)])
ix.cmds.SetValues([str(scat) + ".scatter_input_mode"], ["2"])
ix.cmds.SetValues([str(scat) + ".scatter_rotation"], ["1", "1", "1"])
ix.cmds.SetValues([str(scat) + ".geometry_id_attribute"], [id_property_name])
# Assign extract properties to the scatterer
ix.cmds.SetTexture([str(scat) + ".scatter_scale"], str(scale_property))
ix.cmds.SetTexture([str(scat) + ".scatter_input"], str(ids_property))
ix.cmds.SetTexture([str(scat) + ".scatter_rotation"], str(rotation_property))
sel = ix.selection
count = sel.get_count()
# These variables will allow extraction of data from the objets
pos = ix.api.GMathVec3f()
t = ix.api.GMathVec3d()
r = ix.api.GMathVec3d()
s = ix.api.GMathVec3d()
positions = ix.api.GMathVec3fVector()
# The ressources properties that will be injected in the ptc
ids = ix.api.ResourceProperty("id")
rotation = ix.api.ResourceProperty("rotate")
scaling = ix.api.ResourceProperty("scale")
# init the properties
ids.init(ix.api.ResourceProperty.TYPE_UINT_32, 1, count)
rotation.init(ix.api.ResourceProperty.TYPE_FLOAT_32, 3, count)
scaling.init(ix.api.ResourceProperty.TYPE_FLOAT_32, 3, count)
# Grab the datas
for i in range(count):
item = sel[i]
mat = item.get_module().get_global_matrix()
# About positions
ix.api.GMathMatrix4x4d.extract_translation(mat, t)
for j in range(3):
pos[j] = t[j]
positions.add(pos)
# About rotation
ix.api.GMathMatrix4x4d.compute_euler_angles(mat, r)
for j in range(3):
rotation.set_float(i, r[j], j)
# About scale
ix.api.GMathMatrix4x4d.extract_scaling(mat, s)
for j in range(3):
scaling.set_float(i, s[j], j)
# About id
id_attr = item.attribute_exists(id_property_name)
if id_attr:
ids.set_int(i, id_attr.get_long())
# Fille the particle container with the data previously grabed
ix.api.IOHelpers.set_particles(ptc, positions)
properties = ix.api.ResourcePropertyArray(3)
properties[0] = ids
properties[1] = rotation
properties[2] = scaling
ix.api.IOHelpers.set_particles_properties(ptc, properties)
if ix.selection.get_count() > 0 and ix.selection[0].is_kindof("SceneObjectScatterer"):
scat = ix.selection[0]
scat_module = scat.get_module()
t = ix.api.GMathVec3d()
r = ix.api.GMathVec3d()
s = ix.api.GMathVec3d()
ctx = ix.cmds.CreateContext(scat.get_name() + "_exploded", str(scat.get_context()))
for i in range(scat_module.get_instances().get_count()):
instance_id = scat_module.get_instances()[i]
source = scat_module.get_base_objects()[instance_id].get_object()
instance = ix.cmds.CopyItemsTo([str(source)], str(ctx))[0]
mat = scat_module.get_instance_matrix(i)
ix.api.GMathMatrix4x4d.extract_translation(mat, t)
ix.api.GMathMatrix4x4d.compute_euler_angles(mat, r)
ix.api.GMathMatrix4x4d.extract_scaling(mat, s)
ix.cmds.SetValues([str(instance) + ".translate"], [str(t[0]), str(t[1]), str(t[2])])
ix.cmds.SetValues([str(instance) + ".rotate"], [str(r[0]), str(r[1]), str(r[2])])
ix.cmds.SetValues([str(instance) + ".scale"], [str(s[0]), str(s[1]), str(s[2])])
else:
ix.log_warning("You have to select a Scatterer")