Jump to content

xyzdist function check


Recommended Posts

in a primitive wrangle i have a bunch of line segments as input and i want to use the xyzdist function to find the nearest point on the closest geo. So starting with one line segment each time i want to test against all of the rest segments, so not including its self. The problem is xyzdist(0,@P) means 0 and @P could be the same line. how can i make a condition to avoid that?

xyzdist.hip

Link to comment
Share on other sites

28 minutes ago, philpappas said:

in a primitive wrangle i have a bunch of line segments as input and i want to use the xyzdist function to find the nearest point on the closest geo. So starting with one line segment each time i want to test against all of the rest segments, so not including its self. The problem is xyzdist(0,@P) means 0 and @P could be the same line. how can i make a condition to avoid that?

xyzdist.hip

I initially tried to do this using the a group expression in the xyzdist, maybe you could still do that

But this works.

xyzdist.hipnc

Link to comment
Share on other sites

34 minutes ago, ColecloughGeorge said:

I initially tried to do this using the a group expression in the xyzdist, maybe you could still do that

But this works.

xyzdist.hipnc

so a for loop is necessary to distinguish the primitive calculating from the rest. thats a bummer i thought you would need to create an array of every primitive except the one currently processing and update that array each time in a primitive wrangle, but i couldnt think of a way to feed the array to the xyzdist function. looks like you can only feed it the node inputs but you cant process that beforehand?

the for loop works though,i'll try the group method you mentioned its probably the simplest way to go keeping everything clean inside a wrangle. i'll post it here if i get it to work. thanks

 

xyzdist.hipnc

Edited by philpappas
  • Like 1
Link to comment
Share on other sites

29 minutes ago, philpappas said:

so a for loop is necessary to distinguish the primitive calculating from the rest. thats a bummer i thought you would need to create an array of every primitive except the one currently processing and update that array each time in a primitive wrangle, but i couldnt think of a way to feed the array to the xyzdist function. looks like you can only feed it the node inputs but you cant process that beforehand?

the for loop works though,i'll try the group method you mentioned its probably the simplest way to go keeping everything clean inside a wrangle. i'll post it here if i get it to work. thanks

 

xyzdist.hipnc

Yeah unfortunately you have to pass a geometry to xyzdist and to edit a geometry that isnt input 0 in a wrangle, you have to use sops.

I think you can use python to edit two input geometries at once and it has a similar function geometry.nearestPrim()

However I am unsure how to do this.

Link to comment
Share on other sites

yeah looping over all primitives like this, even using groups is going to be very expensive.

One optimization, is giving it a maximum search range (which will speed up the function a lot)
if you have more or less similar expected distances.

float  xyzdist(<geometry>geometry, vector origin, int &prim, vector &uv, float maxdist)

or

float  xyzdist(<geometry>geometry, string primgroup, vector origin, int &prim, vector &uv,float maxdist)

https://www.sidefx.com/docs/houdini/vex/functions/xyzdist.html

generally what I would do is:

int outPr;
float range = chf("range");
vector outUV;

float dist = xyzdist(1, v@P, outPr, outUV, range+0.001);
if(dist > range)
	return;//or continue if in loop

Alternatively, if you are dealing with reaaaly large amounts of geo,
I would suggest just resampling your primitives, saving the primitive number to those new points,
and check the nearest points, instead of using xyzdist() 

 

 

Link to comment
Share on other sites

On 8.8.2019 at 4:56 PM, philpappas said:

nice! i'm trying to execute this for 100.000 prims though, the previous method with the for loop wouldnt finish in my lifetime even if i compiled that which i did. could there be a better method than xyzdist for this operation?

did you have a look at the file i've attached above? it doesn't use loops but ad hoc groups in the xyzdist() function as well as a max search radius to speed up the search. even though xyzdist() is slower when using groups it shouldn't take ages for 100000 lines ...

Link to comment
Share on other sites

On 8/11/2019 at 2:39 AM, petz said:

did you have a look at the file i've attached above? it doesn't use loops but ad hoc groups in the xyzdist() function as well as a max search radius to speed up the search. even though xyzdist() is slower when using groups it shouldn't take ages for 100000 lines ...

yes it worked pretty good. there is some lag but not the houdini crash kind of lag!

Link to comment
Share on other sites

On 8/10/2019 at 2:18 PM, acey195 said:

Alternatively, if you are dealing with reaaaly large amounts of geo,
I would suggest just resampling your primitives

i thought this would be a big no no if i'm already dealing with huge amount of geo. resampling would explode my pc, no?

Link to comment
Share on other sites

26 minutes ago, philpappas said:

i thought this would be a big no no if i'm already dealing with huge amount of geo. resampling would explode my pc, no?

Well, resampling will indeed increase the usage of RAM, and GPU if you are display it,
but in terms of calculation, using nearpoints() is a way faster (lighter on the CPU) operation than xyzdist()

Also, you could set your resample node's parameter "Create Only Points" (destroying the primitives for the calculation)
which will greatly lower the GPU and a bit of the RAM usage.

It of course matters, what kind of fidelity you need for this, if you really need 0.001m accuracy this method is of course not going to work.
Though, there are certain work-arounds, like measuring the distance to the 2 closest points (instead of 1) and using some geometry math,
to find out where along that edge, lies the actual closest position.

Link to comment
Share on other sites

22 minutes ago, acey195 said:

what kind of fidelity you need for this

to get some perspective on the amount of geo, i should mention that i'm trying to process an OSM file. if you take a look at the file posted you can see the basis of what i'm trying to do, but multiply that by tens of thousands of city blocks.

Link to comment
Share on other sites

On 12-8-2019 at 3:59 PM, philpappas said:

to get some perspective on the amount of geo, i should mention that i'm trying to process an OSM file. if you take a look at the file posted you can see the basis of what i'm trying to do, but multiply that by tens of thousands of city blocks.

ok, had some time to actually at the file, what I suggested earlier should work for your case, since you are only checking the center of every primitive, once.
So for the final code, I would just do this:

int outPr;
float maxdist = chf("radius");
vector outUV; //to use the range overflow of the xyzdist() you also have to query the primitive and uv for some reason
string grp = sprintf("!%d", @primnum);

f@test = xyzdist(0, grp, @P, outPr, outUV, maxdist + 0.001);

if(@test<maxdist){
    s@near = "close";
    }

with a lot more primitives, its going to be more costly of course, but probably still less than putting it in a loop.
That said, with a very large amount of geometry, you may have to do the calculation in multiple steps,
so not every primitive has to check Every other primitive, but just the ones that are close.

Also, you could add an heuristic, resampling all primitives, adding a center point to all edges and check those first with a nearpoint() expression,
then afterwards, doing the xyzdist() for all the remaining primitives.
That way you could greatly optimize all the plots that have similarly sized buildings next to each other,
as those points will in a lot of cases, nicely line up with the center of the neighbouring primitive in that case,
if you are really afraid about performance.

Edited by acey195
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...