philpappas Posted August 7, 2019 Share Posted August 7, 2019 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 Quote Link to comment Share on other sites More sharing options...
Lucy Coleclough Posted August 7, 2019 Share Posted August 7, 2019 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 Quote Link to comment Share on other sites More sharing options...
philpappas Posted August 7, 2019 Author Share Posted August 7, 2019 (edited) 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 August 7, 2019 by philpappas 1 Quote Link to comment Share on other sites More sharing options...
Lucy Coleclough Posted August 7, 2019 Share Posted August 7, 2019 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. Quote Link to comment Share on other sites More sharing options...
petz Posted August 7, 2019 Share Posted August 7, 2019 you can exclude the current prim in the xyzdist() function by using groups. i've attached an example. hth. petz xyzdist_1.hipnc 4 Quote Link to comment Share on other sites More sharing options...
philpappas Posted August 8, 2019 Author Share Posted August 8, 2019 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? Quote Link to comment Share on other sites More sharing options...
acey195 Posted August 10, 2019 Share Posted August 10, 2019 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() Quote Link to comment Share on other sites More sharing options...
petz Posted August 10, 2019 Share Posted August 10, 2019 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 ... Quote Link to comment Share on other sites More sharing options...
philpappas Posted August 12, 2019 Author Share Posted August 12, 2019 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! Quote Link to comment Share on other sites More sharing options...
philpappas Posted August 12, 2019 Author Share Posted August 12, 2019 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? Quote Link to comment Share on other sites More sharing options...
acey195 Posted August 12, 2019 Share Posted August 12, 2019 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. Quote Link to comment Share on other sites More sharing options...
philpappas Posted August 12, 2019 Author Share Posted August 12, 2019 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. Quote Link to comment Share on other sites More sharing options...
acey195 Posted August 13, 2019 Share Posted August 13, 2019 (edited) 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 August 13, 2019 by acey195 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.