Welcome to od|forum

Register now to gain access to all of our features. Once registered and logged in, you will be able to contribute to this site by submitting your own content or replying to existing content. You'll be able to customize your profile, receive reputation points as a reward for submitting content, while also communicating with other members via your own private inbox, plus much more! This message will be removed once you have signed in.

ch3

Efficient way to instance/copy geometry onto points

I fracture an object into an arbitrary amount of pieces and I want to copy these multiple times onto points. Pieces and points have an attribute (name or pieceId) to make the associations between the two.

A copySop node works, but it's rather slow once I use the stamp expression to determine which piece needs to be copied to each point.

I also tried a forEach node, that loops through the points based  on their pieceId as an input parameter. Inside I filter the corresponding piece and then copy it to all the points that have the specific pieceId. Even though the forEach node also uses the stamp expression, it is slightly faster as it's calling it once per group rather once per point.

The instance node at object level wouldn't work, as I have an arbitrary amount of pieces within the SOP level.

 

Ideally I was looking for a node similar to transformPieces, but have the ability to duplicate the pieces of the input geometry and populate all the points.

 

Is there maybe another more efficient way I could copy or instance geometry onto points?

Or maybe a VEX function to select and copy geometry?

 

 

 

thanks

 

 

 

 

Share this post


Link to post
Share on other sites

Are you using packed geometry? if your geometry is packed it will copy your pieces to the points a lot faster than just doing it normally. They go over the difference in times in the Bullet Master Class. you might want to check that out if you haven't already.

 

Share this post


Link to post
Share on other sites

oh yeah I forgot to mentioned that the pieces are indeed packed. I think I've watched this video, but I will take another look in case I am missing something out.

thank you

Share this post


Link to post
Share on other sites

Hopefully someone else can figure out exactly what your looking for because my knowledge of Houdini is very basic.

 

The only thing I can think of to speed things up is to break it up into multiple copies and merge them together later?

 

sorry I'm not more help

Edited by rolfcoppter

Share this post


Link to post
Share on other sites

so post a hip to see exactily what you want to achieve. Anyway the fastest way would be a wrangle cause its much faster than a foreach sop.

Let me see the file and I'll give it a try.

Share this post


Link to post
Share on other sites

Follyx is it possible to copy geometry or primitives with VEX? I agree that would probable be faster than anything else.

 

 

So in the attached hip file I have a sphere that breaks apart.

 

On the left 4 branches I place the pieces onto the points and with a trailSop I create a copy of each shard for every frame. That works, but ideally I want to place the trailSOP before instancing/copying the packed geometry on to the points, like the 4 branches on the right side, because I want to further manipulate the points. Of course two of them on the right side don't work.

 

 

Any other ideas?

 

thank you so much

 

instancing_01.hip

Share this post


Link to post
Share on other sites

Or to simplify my question, is there a way to instance geometry without using stamping, the way maya does it with particles? Where a node instances a selection of geometry based on the objectIndex attribute of a particle system.

 

thank you

Share this post


Link to post
Share on other sites

Copy the full shattered sphere to the trailed points and set the id attribute via template attributes on the copy sop.

Follow this with a wrangle to delete the unwanted pieces via the id attribute.

 

This is reasonably fast (under a second to cook for around 20k objects).

Share this post


Link to post
Share on other sites

Wow, that's interesting.... this approach is indeed much faster than anything else. I would never thought about it.

Thanks for the suggestion. I will let you know if I find anything else on the topic.

Share this post


Link to post
Share on other sites

Another way is to instance during rendertime but you wrote that you want to modify the points afterwards...

Share this post


Link to post
Share on other sites

I think Packed primitives with Copy sop is more than enough. Which is much faster and easy to edit

Share this post


Link to post
Share on other sites

Another way is to instance during rendertime but you wrote that you want to modify the points afterwards...

Actually for the time being I don't need to modify the points afterwards, but it's important for me to be able to preview the result and modify the simulation in an interactive way.

 

 

I think Packed primitives with Copy sop is more than enough. Which is much faster and easy to edit

So when copying a selection of packed primities on to points, how do you select which primitive will go on each point? The only way I know so far is using stamping which is rather slow.

 

 

 

 

On the other side I manage to find a better way. The instance node seems to be the fastest, but the problem is the various pieces need to exist at object level with a transform, which could be rather painful to build and manage hundreds of different pieces. So what I did was to export all my packed primitives into a single frame alembic archive and create an hierarchy using a pathAttribute. Then I imported the alembic file, which automatically creates and manages the hierarchy under one alembic node and re-constructed the necessary path at the point's instance attribute to determine which piece of geometry should go on each point. So far this works really well, but I still need to see how well it translates to arnold archive for rendering in maya.

 

thank again

Share this post


Link to post
Share on other sites

I created a tool for faster instancing. Most of the tool is written in VEX.

It can instance live node from network and file from disk.

It's ultra fast compare to copy SOP. You will notice huge difference on more 100,000 points. 

File attached. Check and let me know if you have any difficulty.

copy_instancing.hipnc

pbInstance.hda.tar.gz

1 person likes this

Share this post


Link to post
Share on other sites

Actually for the time being I don't need to modify the points afterwards, but it's important for me to be able to preview the result and modify the simulation in an interactive way.

 

 

So when copying a selection of packed primities on to points, how do you select which primitive will go on each point? The only way I know so far is using stamping which is rather slow.

 

 

 

 

On the other side I manage to find a better way. The instance node seems to be the fastest, but the problem is the various pieces need to exist at object level with a transform, which could be rather painful to build and manage hundreds of different pieces. So what I did was to export all my packed primitives into a single frame alembic archive and create an hierarchy using a pathAttribute. Then I imported the alembic file, which automatically creates and manages the hierarchy under one alembic node and re-constructed the necessary path at the point's instance attribute to determine which piece of geometry should go on each point. So far this works really well, but I still need to see how well it translates to arnold archive for rendering in maya.

 

thank again

Use "switch" sop to assign desired packed primitive to selective points, Always use bounding box in case of large number of instances. If you want to visualize,use a proxy geometry which may also packed primitive. In mantra "Set Declare materials" to "Save All SHOPS" if you used any textures for packed primitives.

Share this post


Link to post
Share on other sites

I created a tool for faster instancing. Most of the tool is written in VEX.

It can instance live node from network and file from disk.

It's ultra fast compare to copy SOP. You will notice huge difference on more 100,000 points. 

File attached. Check and let me know if you have any difficulty.

 

Thank you for these files. I took a look and it was interesting to see how this approach works as well. I was surprised to see you were using stamping as I thought that's the main bottleneck. But after further tests I noticed something else that I wasn't expecting.

As I am generating my pieces with a voronoi fracture, it's hard to separate them in order to use a switch node with stamping. So instead a switch, I delete all packedPrimitives apart one. The selection is done with stamping. Initially I was doing this using a wrangle node thinking that it would be the most optimized method, but for some reason the delete node with an expression works much much faster. In my test scene with 500 points, the wrangle node runs at about 3.5fps, where the delete node at 14fps. A bit strange, as in the past I have found that deleting points with a wrangle node is a lot faster than the delete node.

 

 

 

wrangle VEX code:

if( @pieceId != ch("id") )
    removepoint(0, @ptnum);

Delete expression (delete non-selected)

$PIECEID == ch("pId")

Share this post


Link to post
Share on other sites

the "ch" function in your wrangle is likely slowing down your vex code.  try a full-fledged vop network with a parm for your id and see if it's any faster.

 

i would also see if a 2-step delete is faster than deleting point-by-point.  so instead of doing a removepoint() do "i@delete = 1" and then have a blast sop delete all points in the group "@delete==1"

Share this post


Link to post
Share on other sites

You can also write voronoi fracture pieces to disk. If you want, I can modify it as well.

Edited by pbarua

Share this post


Link to post
Share on other sites

the "ch" function in your wrangle is likely slowing down your vex code.  try a full-fledged vop network with a parm for your id and see if it's any faster.

 

i would also see if a 2-step delete is faster than deleting point-by-point.  so instead of doing a removepoint() do "i@delete = 1" and then have a blast sop delete all points in the group "@delete==1"

 

Yeah using a VOP-SOP and a Param input seems to be faster. But now my scene crashes a lot. I am not sure if I am using the removePoint node the right way. I understand it deletes the point number you feed into it, but how do you tell it not to delete the point it's processing at the current cycle? Right now if I don't want to delete the current point, I set it to -1, which I am not sure it's the right way.

 

I've attached the file with my various tests.

 

thanks again

instancing.hip

2 people like this

Share this post


Link to post
Share on other sites

Use "switch" sop to assign desired packed primitive to selective points, Always use bounding box in case of large number of instances. If you want to visualize,use a proxy geometry which may also packed primitive. In mantra "Set Declare materials" to "Save All SHOPS" if you used any textures for packed primitives.

 

A little trick I do because sometimes there's WAY too many SHOPS in the file to be worth taking the compilation hit...just make a little script that goes through all of the shop_materialpath values, makes a point or sphere or whatever you want for each, and attaches every single SHOP the asset needs to these placeholders. Then you either set them to phantom, scale them down to microscopic, etc., but having them in your scene with force Mantra to compile those SHOPS at render time and make them available to the packed objects.

Edited by Kardonn

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now