Isotropix Forums

Convert HandPlaced/CloneStamped objects into a Scatter obje?

General Discussion about Isotropix and CG related topics

Convert HandPlaced/CloneStamped objects into a Scatter obje?

Unread postby ryder » Sat Aug 04, 2018 5:15 pm

Hi guys,so i know this sound super weird. :D but i was wondering is there a way to convert Hand-Placed or CloneStamped regular objects into a Scatter object? Sometimes i really need to GLOBALLY add some Variation to these Hand-Placed objs, and scatter object had the perfect tool for that.and than whats cool is, I can than making multiple variations of my original HandPlaced Layout using just a couple of new scatter object.

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 ;)
ryder
 
Posts: 44
Joined: Sun Mar 17, 2013 5:08 am

Re: Convert HandPlaced/CloneStamped objects into a Scatter o

Unread postby dboude » Mon Aug 06, 2018 9:46 am

Hi,

I guess it's possible with python. The way to do that would be :

- First, give an ID to your source objects.
- Create a point cloud based on the position of your cloned objects and inject the ID and the orientation of the objects as a property in each point.
- Create a scatterer and list your source object with their corresponding ID.
- Set the point cloud as geometry support of the scatterer.
- Create two extract property nodes to drive the ID and the rotation of the scatterer.

Good luck ;)

Cheers !
Démian
Isotropix
Technical Artist - Clarisse Specialist
User avatar
dboude
 
Posts: 517
Joined: Mon Jul 03, 2017 11:51 am

Re: Convert HandPlaced/CloneStamped objects into a Scatter o

Unread postby bvaldes » Mon Aug 06, 2018 12:21 pm

hello,

This is a script that does what you want to:

python code

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)


How does it work:
You have to set an id on each of your items in the layout. This ID will help you to identify which geometry to scatter at the right place.
Let's take an example: For you layout you have scattered 125 box and 457 spheres. They have specific position, rotate and scale. To allow the script to know whre to scatter the box and the sphere, you have to add to all the spheres an id (the same) and another id for all the boxes.
The script will extract that id and set it on the point cloud. Then in the scatterer, you just have to add the source geometries of your layout and the scatter will setup the geometries at the right place.

If you use instance in the close stamp, you just have to change the custom ID attribute in the source object and all the instances will have the same. Then launch the script.
Else: selection all the same geometries and in the Attribute Editor change the custom id value. Then launch the script.

The first line of the script is to define the name of the attribute that will have the ID of your geo. By default is set it to "custom_id" but you can obviously set your own attribute.

Feel free to ask if you need help.
Regards
Benoit VALDES
Isotropix
Clarisse QA
User avatar
bvaldes
 
Posts: 265
Joined: Mon Sep 26, 2016 11:44 am

Re: Convert HandPlaced/CloneStamped objects into a Scatter o

Unread postby bruce » Mon Aug 06, 2018 12:42 pm

Perfect Benoit Thanks a lot !

to avoid any confusions, you need fisrt to add the custom_id number in the object you want to layout and in the scatterer you must just load this source object used with the clone stamp tool.
And now you can export this point cloud to Houdini !

Enjoy !
Bruce
Isotropix
Technical Artist - Clarisse Specialist
User avatar
bruce
 
Posts: 206
Joined: Fri May 20, 2016 12:11 pm

Re: Convert HandPlaced/CloneStamped objects into a Scatter o

Unread postby ryder » Tue Aug 07, 2018 4:09 pm

Damn you guys are killing it,like,seriously...
Benoit, thank you so much for the script, works like a charm :D

You guys ROCK! 8-)
ryder
 
Posts: 44
Joined: Sun Mar 17, 2013 5:08 am

Re: Convert HandPlaced/CloneStamped objects into a Scatter o

Unread postby bvaldes » Tue Aug 07, 2018 4:24 pm

Hi,

Yes, you're right, the sources geo of the scatterer have to have the translate attribute set to 0. This is because the scatterer apply the offset of the scattered geometries on the point cloud.

Happy that it worked, have fun and feel free to share your work with us :D
Regards
Benoit VALDES
Isotropix
Clarisse QA
User avatar
bvaldes
 
Posts: 265
Joined: Mon Sep 26, 2016 11:44 am


Return to General Discussion