PDA

View Full Version : Coffee Script: Deleteing small objects.


mogh
03-01-2010, 07:08 AM
Hi all,

UPDATE: Working Script at the bottom ....

My goal is to make a script which deletes small objects from a sczene.

I managed to copy paste myself a script from PerAnders wonderfull Wiki (http://www.per-anders.net/w/index.php). I guess I am stuck at the point how to get the min value and compare it hence i get tripple values (vector i guess).

the output is e.g.
[260.1234456,90.123456,45.123456]
how do i compeare this with a value ?

i marked the problem zone down in the code
thanks for your help in advance.

here is the script so far


getNextObject(op)
{
if (!op) return null;

if (op->GetDown()) return op->GetDown();

while (!op->GetNext() && op->GetUp()) op = op->GetUp();
return op->GetNext();
}


//Class for finding the bounding box of a set of points

class MinMax
{
var min;
var max;
public:
Init();
AddPoint(p);

GetMin();
GetMax();
GetMp();
GetRad();
GetSize();
}

MinMax::Init()
{
min = vector(MAXREAL);
max = vector(MINREAL);
}

MinMax::AddPoint(p)
{
if (p.x < min.x) min.x = p.x;
if (p.x > max.x) max.x = p.x;

if (p.y < min.y) min.y = p.y;
if (p.y > max.y) max.y = p.y;

if (p.z < min.z) min.z = p.z;
if (p.z > max.z) max.z = p.z;
}

MinMax::GetMin()
{
return min;
}

MinMax::GetMax()
{
return max;
}

MinMax::GetMp()
{
return (min + max) * 0.5;
}

MinMax::GetRad()
{
return (max - min) * 0.5;
}

MinMax::GetSize()
{
return (max - min);
}


//------------------------------------
// Function for Getting the size of an object
class GetSize
{
var bb;
public:
Init(op, global); //Object, Bool. Return bool
GetBounds(); //Return Bounding box
}

GetSize::Init(op, global)
{
if (!op || !op->IsInstanceOf(Opoint)) return false;

bb = new(MinMax);
if (!bb) return false;
bb->Init();

var padr = op->GetPoints();
var pcnt = op->GetPointCount();
var i;

if (global)
{
var mg = op->GetMg();
for (i = pcnt - 1; i >= 0 ; --i)
{
bb->AddPoint(mg->GetMulP(padr[i]));
}
}
else
{
for (i = pcnt - 1; i >= 0 ; --i)
{
bb->AddPoint(padr[i]);
}
}

return true;
}

GetSize::GetBounds()
{
return bb;
}


main(doc, op)
{

//Get the first object in the document
var myobject = doc->GetFirstObject();
if (!myobject) return false;

while (myobject)
{
//Do something to "myobject" here

var cl = new(GetSize);

//Get the objects size in global space, for local set second argument to false
if (!cl || !cl->Init(myobject, true)) return false;

// println("Object Scale");
// println(myobject->GetScale());


var bb = cl->GetBounds();
if (!bb) return false;

// println("Object Size and Bounds");

// print("Min :: ");
// println(bb->GetMin());

// print("Max :: ");
// println(bb->GetMax());

print("Radius :: ");
println(bb->GetRad());

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// what to do here ????

if (bb->GetRad() <= 150 ){
println ("Object to small delete me");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// print("Size :: ");
// println(bb->GetSize());

// print("Mid Point :: ");
// println(bb->GetMp());

myobject = getNextObject(myobject);
}

return true;
}

Mallard
03-01-2010, 01:26 PM
Hi Jan :)

it seems to me that the script calculates the bounding box via its extreme points by getting the smallest value of each coordinate and the highest. "Min" and "Max" are those extreme points given as vector (x,y,z) in space. The "size" of the box can then be thought of as the diagonal line between those points which is equivalent to subtracting the min vector from the max vector. In your script the "radius" seems to be defined by the outer sphere of the BB - it's given by half of that size.

If it's this radius what you're interested in, you thus might want to use the absolute value of the vector given by sqrt(x*x + y*y + z*z)

Best,

Andre

mogh
03-02-2010, 05:35 AM
Thanks andre' for the heads up,
I have one more thing to dive deeper into that script,

How do i access the single values of this Vector bb->GetRad() ? it seems i get it only in a package and i don't know how to go on further at this point ....

I would like to make some simple comparesion between numbers in the end and delete objects that are below a certain "size" (i guessed the radius would be the universall vallue here ).

thanks in advance
regards mogh

Mallard
03-02-2010, 06:56 AM
Hi Jan,

I'm not quite into the COFFEE syntax but one should be able to access the vector's components straightforwardly like bb->GetRad().x and so on. In your script it looks like bb->GetSize() gives you the maximum diameter of the object whereas GetRad() gives the half of that. So if you want to compare the radius to some maximum value I think you should do something like this:


var rv = bb->GetRad();
var r = sqrt(rv.x * rv.x + rv.y * rv.y + rv.z * rv.z); // absolute value of the vector which is it's length
if(r <= 150)
{
// do stuff
}

mogh
03-02-2010, 01:44 PM
Thanks for your help Andre' next real real life Coffee is on me, I have a working script now. Ill test it some days and the post it here again.

regards mogh

Mallard
03-02-2010, 02:04 PM
next real real life Coffee is on me

ah, I'll take your word on that ;)

mogh
03-15-2010, 09:23 PM
So as promissed here it is with dialog and Icon. pretty neet if you have a big CAD imprt with lots of small things you wont see in a render anyway and slows your scene down.

I am working on a more enhanced version, as soon as i wrapped my head around layers.

over and out mogh

mogh
03-20-2010, 11:09 PM
http://www.defcon-x.de/wp-content/uploads/2008/08/cad_clean.png

http://www.defcon-x.de/c4d/c4d-scripts

I did push myself to make an all in One Solution to my daily work hussle, and by accident I got better at Coffee coding hehe.

feel free to report any bugs.

greetings mogh

CGTalk Moderation
03-20-2010, 11:09 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.