Jump to content
Netvudu

Non-overlapping Copies

Recommended Posts

Alrighty, how about this:

Solve for ONE box being stacked on something else. Rinse and Repeat.

So: Add a single point on the floor. Use the Ray SOP to shoot the point upwards moving the point to "Farthest Collision" - or make a ground plane and add a point high in the air and ray it downward to the nearest collision. (This first point will strike the floor in either solution.) Copy your box to the point location. One crate, on top of the tallest thing.

Now repeat in a ForEach SOP (with "Merge Results" ON).

..

This is a rudimentary solution so far.... You could improve the stacking logic from there... like sending four corner points instead of one point and so be able to have tilted boxes.

Now you might be ready to stack arbitrary objects, not just boxes... perhaps scatter the points on (the underside of) the geometry and and project these points up, take the oriented bounding box of the transformed points (in the Box SOP) and use the button poly as target transform.

You might be able to built a little StackAnObject HDA which can stack one of any object vertically on another. This HDA would be able to go inside a ForEach.

Sounds fun to try out! But I gotta go... if you have trouble trying something like this, write in here!

Jason.

Share this post


Link to post
Share on other sites

mrrrmmm...some stuff looks doable and some other looked like greek to me :blink: Will have to try it. I

Edited by Netvudu

Share this post


Link to post
Share on other sites

Ah the Ray SOP, a fearsome engine in the Houdini toolset. :ph34r:

Fiddle with those concepts, perhaps when you see it in action the dreams will come.

Share this post


Link to post
Share on other sites

Nice one petz! Very smartly!

This is actually very common question: about non-overlapping copies. There are some ways to do it with particles collision detection. Also Chops could be possibly helpful here.

Here is a brief code for Vex Sop. It generally does the same what petz did with foreach loop but in code thus it's x times faster. That does matter for a big geometry. (Maybe someone can fix it. Don't treat it as a VEX reference ;) ).

sop
 nearestPoint()
 { 
	 float dist;
	 int i;

	 // Get the longest possible distance:
	 vector min, max;
	 getbbox(min, max);
	 dist = distance(min, max);

	 // Loop through all other points to check if
	 // there are no closer than that:

	 for (i = 0; i < Npt; i++) {

		 // Compute distance to next point:

		 vector neighbour;
		 import("P", neighbour, 0, i);

		 // If not the same point compute distance:
		 if ( neighbour != P ) { 
			 float tmpdist = distance(P, neighbour);

			 // If found point closer than before,
			 // overwrite distance attribute:

			 if ( tmpdist <  dist ) {
				 dist = tmpdist;
				 addattribute("distance", dist);
			 }
		 }
	 }				   
 }

Using point cloud method would speed up it even more, because of search radius of that. Code is also nicer:

sop
 nearestPointPC(string pointcloud="")
 { 
		 vector tmpdist;
	 vector min, max;
	 getbbox(min, max);
	 float dist = distance(min, max);

	 int handle = pcopen(pointcloud, "P", P, dist, 2);  

	 while (pciterate(handle) ) {
		 vector pos;
		 pcimport(handle, "P", pos);
		 if ( P != pos ) { 
			 pcimport(handle, "point.distance", tmpdist);
			 addattribute("distance", tmpdist);
		 }
	 }			
 }

"pointcloud" parameter can be pointed to the input SOP with a syntax like:

op:/`opinputpath(".",0)`

Hope this could be helpful for someone on that trip!

cheers,

sy.

Edited by SYmek
  • Like 2

Share this post


Link to post
Share on other sites

I know this is an old post, but I wanted to thank Symek. I updated the code to be used in a vex wrangle, in case this helps anyone.

vector tmpdist;
vector min;
vector max;
getbbox(min, max);
float dist = distance(min, max);

int handle = pcopen(geoself(), "P", @P, 1, chi("max_pts"));

while (pciterate(handle)){
    vector pos;
    pcimport(handle, "P", pos);
    if (@P != pos) {
        pcimport(handle, "point.distance", f@distance);
        }
}

f@pscale = f@distance / 2;

 

 

Share this post


Link to post
Share on other sites

Here is another thread on the topic leveraging the found_overlap attribute for RBDs.

 

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

×