PDA

View Full Version : finding a point identifier's index as asInt()



rom
10-09-2007, 06:57 AM
Hi all,:thumbsup:
I am writing a custom binary exporter for modeler in order to synchronize
mesh data between lightwave and a game engine.

have a working version.
however ...

while looping polygons
and their assosiated points
i am having trouble
finding the absolute index of a point identifier,(as an integer)
within the context of all the points in the object.

I am able to retrieve the point identifier
and get the position data of the point.

i need a method to retieve the point index of a point identifier
in the context of the global point array.

I searched the docs and not been able to find the answer
it's probably staring me in the face

please see commented code for what i am trying to achieve
hope some one can point me in the right direction
:help:


//-----------------------------------------
// LScript Modeler template
//
// custom binary exporter

@version 2.2
@warnings
@script modeler

// global values go here
mesh;

//_______________________________
// this is causing massive overhead
// need to find better way of getting point index
getPointIndex : point // TAGGED FOR FACTOR OUT
{

for(i=1;i<=pointcount();i++ )
{
if(point == mesh.points[i])
{
return i;
}
}


return 0;
}

main
{

editbegin();

mesh = Mesh(1); // just layer 1 for now

pntCnt = pointcount();
polyCount = mesh.polygonCount(1);


// create the custom .bin file at the same path as the object filename

filename = string(mesh.filename,".bin");
file = File(filename,"wb") || error("can't create file");
file.close();
file = File(filename,"rb+") || error("cant open file");

// file header
file.writeInt(pntCnt);
file.writeInt(polyCount);


// write out points
file.offset(64,FROMSTART);
for(i=1;i <= pntCnt;i++)
{
lastPntPos = pointinfo(mesh.points[i]);
file.writeVector(lastPntPos);
}


// write polys :
// for now asuming mesh is trippled
// i need an int[3] of point indices referencing the global point array ?
p=1;
foreach(poly, polyCount )
{
v=1;
thisPoly = mesh.polygons[p];
pi=1;


pointIndices;

foreach(point , thisPoly.pointCount)
{
//triPoints;
thisPoint = thisPoly.points[pi];

// here i need index referencing the global point array.

// as poly count increases
// using getPointIndex() SEE getPointIndex : point
// is geometrically more expensive

// TAGGED TO FACTOR OUT
file.writeInt( getPointIndex( thisPoint ) );

// i would like to do as in next comment

// foreach(index ,pointIndices)
//{
// file.writeInt(index);
//}
pi++;
}
p++;
}



file.close();
editend();


reqbegin("<Requester Title>");

c0 = ctlinteger("Integer Control",1);
c1 = ctlnumber("Number Control",1.0);
c2 = ctlstring("String Control","my string");
c3 = ctlcheckbox("Checkbox Control",true);
c4 = ctlpopup("Popup control",1,@"Item 1","Item 2","Item 3"@);
c5 = ctlchoice("Choice Control",1,@"X","Y","Z"@);

//return if !reqpost();
//ureturn if !reqopen("keepOpen");
// get requester control values here

reqend();

// processing code goes here

}

art
10-09-2007, 07:02 AM
Maybe there are better ways of doing it (i'll leave it to others for comment), but I'll give you the first idea that came to my mind. You could store all polygon IDs with their corresponding index in an array, sort by polygon IDs. Update your getPointIndex function to perform a binary search on the array. Should be considerably faster.

rom
10-09-2007, 07:31 AM
Thanx for the quick response art !
I am quite new to LScript and am unfamiliar with doing a binary searches
on arrays.
elaboration would be helpfull...:bowdown:

art
10-09-2007, 08:05 AM
Its a general search algorithm and there are plenty of resources available (including sample code, etc). It is similar to the popular "guessing game", for example: Guess a number between 1 and 100.

is it bigger than 50? yes (search between 51 and 100)
is it bigger than 75? yes (search between 76 and 100)
is it bigger than 87? no (search between 76 and 87)
is it bigger that 81? yes (search between 82 and 87)
and so on.

So you wil get the answer in 6 or so "guesses" instead of 82+. There is some overhead involved (+ one time sort) but for sufficiently large array it is faster than a linear search.

Try starting here:

http://en.wikipedia.org/wiki/Binary_search

Most of the sample code floating around should be easy to implement in lscript. The prerequisite is that the array must be sorted. I never used lscript's built in sort commands and i am not sure if you can use them in this case. What you need to do it sort a pair of numbers (ID and index) by ID.
Of course there are many of sort algorithms available, some better some worse, some easier to implement some not.

Depending on how often you plan to use your plugin and how heavy is the geometry this could be worth investing some time into.

faulknermano
10-10-2007, 08:40 PM
here's another idea, you can try storing a vertex map of the selection type (or even weight type). go through your object vertices once based on point index and "tagging" it. then on your point id routine simply use the the VMap() to get at the value.

LightFreeze
10-11-2007, 12:27 AM
its a pain trying to find a command you don`t know the name of, as I found out when I needed this a while ago :)


A new indexOf() method can be applied to string, linear array and binary block data types. This
method can be used to locate data within these indexable types. The method returns the index
where the specified data is found. If it is not found, then a value of zero (0) is returned.
In the case of character strings, the provided search value is treated as a displayable character:
...
s = "val1:15:3.14";
ndx = s.indexOf(':'); // returns 5
...
For linear arrays, the value provided must match an element in both type and value in order
to be considered a successful match. Not all data types are supported for searching.
Searches through binary data will treat the provided integer value as an unsigned character,
and should be in the range 0 to 255.
By default, searches begin at the initial index offset of one (1). You can specify a beginning
offset other than one by providing the integer offset before the search value.
...
s = "val1:15:3.14";
ndx = s.indexOf(':'); // returns 5
ndx = s.indexOf(ndx + 1,':'); // returns 8

art
10-11-2007, 06:57 AM
here's another idea, you can try storing a vertex map of the selection type (or even weight type). go through your object vertices once based on point index and "tagging" it. then on your point id routine simply use the the VMap() to get at the value.

That's a great tip. I'll keep in in mind too :)