PDA

View Full Version : Find Locators within bounding area


JellyFire
10-23-2007, 01:09 PM
Hey, been thinking about doing this in the api, but i'll have to learn it first : P
So for the mean time i'll just stick to mel:
What I want to do is create a box, pul out it's corners to set a ground plane, scaleY to get influence area and then run a script to select all locators within the box....

I know how to find out if a certain locator is within the box, but this could become crazy if I have 1k locators in a scene and only have 10 inside of the box...

Is there a better way of doing it?
The objective is to pin Cones to each locator to aid in cleaning a track.

Thanks for any advice.
Christian

tbaypaul
10-23-2007, 06:10 PM
partitioning space is just a time consuming thing to do....and to do it with mel is about as brute force as you can go........to speed up the process data structures are usually kept.....like binary space partitioning for your ray tracer.

so....if you precomputed an int floor of the locator coordinates then you could eliminate locators in cells outside the bounding volume....you could presort your locators in a way.

so given 5 locators with vector positions... <<1.02,1.22,1.45>>,....,<<1.23,1.54,1.06>> all larger then 1.0 and less then 2.0 their floors are all 1's so they are in cell 1,1,1
if the bounding volume's min and max x,y,z are <<3.4,2.4,4.4>> and <<4.4,3.6,5.6>> then you can exclude all 5 locators because they are in cell 1 1 1 and the bounding volume isn't even close....you need all cells from cell 3,2,4 to cell 5,4,6 and you can exclude all the others in addition to cell 1,1,1.

but it is expensive to keep that data around a maya scene....
if there is a naming convention to the locators you could try to leverage strings....

JellyFire
10-23-2007, 07:27 PM
:eek:


Ooooooooooooohhhhhhh, K. :D
What it's for is taking a pftrack/boujou/3de track, and then specifying it's ground plane and adding cones to each locator on the ground plane...

Think i'm gonna have to wait a bit for this one..
For the minute I have a script that works of selected locators, so that'll just have to do...

Thanks for the mind boggle though. (I got it, but think it's too complicated for what I want).
Christian

ThirdRail
10-30-2007, 02:24 AM
you really don't need a space partioning algorithm to handle this.

Bad news:
You know where the locators are and unfortunately you are going to have to do what you were afraid of, test each locator position.

Good news:
you can break this down into a 2d solution since you are only concerned with locators on the ground plane (if I'm understanding you correctly). Finding a point inside an 2D area is simpler than finding a point in a volume (obvious...I know).

Simply cast a ray from your locator origin to a location that you are absolutely sure is outside of the volume (ex extend your box endpoints in both dimensions). If you have intersected a plane of the bounding box an even number of times, the locator is OUTSIDE of the bounding area. If you intersect a plane an odd number of times, you know the point is INSIDE the bounding volume. What's great about this trick is that it not only works for your square bounding volume but also for irregular shaped volumes (like a horseshoe shape or circles).

teacup
10-30-2007, 03:56 PM
Maybe I'm missing something, but why can't you just query each locator to see if it's within the box? As long as it's a standard box aligned to world (pretty normal for a marquee type selection) then its a very simple calculation.

I did a quick test with a scene with 8000 locators, and it takes under a second to do a selection based on a box.

Here's the quick script I wrote to test.

string $locators[] = `listTransforms "-type locator"`;
string $usrSel[] = `ls -sl`;

print `size($locators)`;

float $bbox[] = `exactWorldBoundingBox $usrSel[0]`;

string $inBox[] = {};

for ( $o in $locators )
{
float $x = `getAttr ($o + ".translateX")`;
float $y = `getAttr ($o + ".translateY")`;
float $z = `getAttr ($o + ".translateZ")`;

if ( $x < $bbox[0] || $x > $bbox[3] ) continue;
if ( $y < $bbox[1] || $y > $bbox[4] ) continue;
if ( $z < $bbox[2] || $z > $bbox[5] ) continue;

$inBox[`size($inBox)`] = $o;
}

select $inBox;

tbaypaul
10-30-2007, 04:36 PM
oh, that is funny.....I guess someone should have tested the brute force method first....though I do like the 2d simplification too...

CGTalk Moderation
10-30-2007, 04:36 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.