# remove primitives that are not perfect rectangles

## Recommended Posts

I need to get rid of all primitives that:

• have more or less than 4 points,
• and of those that have 4 points, I need to delete the primitives that are not perfect rectangles (they don't need to be squares, I just need to get rid of the "distorted" rectangles

Edited by anicg

##### Share on other sites

Hi,

you can use primpoints() for example.

p.s.

or use min_angle threshold ...

remove_prim_by_pointcount_minangle.hipnc

Edited by Aizatulin

##### Share on other sites

Hi, you can do something like this inside a Primitive Wrangle and use the deviation parameter (from 0 to 1) to remove quad primitives based on how much one of its edges can deviate from the average edge length:

```float deviation = ch("deviation");

int count = primvertexcount ( 0, @primnum );
if ( count != 4 )
removeprim ( geoself ( ), @primnum, 1 );
else
{
int isclosed = primintrinsic ( geoself ( ), "closed", @primnum );
if ( isclosed )
{
int pts [ ] = primpoints ( geoself ( ), @primnum );
float edgelen [ ] = { };
for ( int i = 0; i < len ( pts ) - 1; ++i )
{
vector p0 = point ( geoself ( ), "P", pts [ i ] );
vector p1 = point ( geoself ( ), "P", pts [ i + 1 ] );

append ( edgelen, distance2 ( p0, p1 ) );
}

float perim = primintrinsic ( geoself ( ), "measuredperimeter", @primnum );
perim *= perim;

float avgperim = perim / count;
foreach ( float elen; edgelen )
{
if ( abs ( elen - avgperim ) / avgperim < deviation )
{
removeprim ( geoself ( ), @primnum, 1 );
break;
}
}
}
}```

• 1

##### Share on other sites

Hi Mani,

a rectangle is defined by having four corners with rectangular angles. So first get rid of non-quads in a primitive wrangle:

```if(primvertexcount(0, i@primnum) != 4){
removeprim(0, i@primnum, 1);
}```

Then create vertex attributes with the direction from one vertex to the next (and the number of the next vertex):

```int num_vtx = primvertexcount(0, i@primnum);
int index_curr = vertexprimindex(0, i@vtxnum);
int index_next = (index_curr + 1) % num_vtx;
int vtx_next = primvertex(0, i@primnum, index_next);

int pt_curr = vertexpoint(0, i@vtxnum);
int pt_next = vertexpoint(0, vtx_next);
vector pos_curr = point(0, 'P', pt_curr);
vector pos_next = point(0, 'P', pt_next);
vector dir = normalize(pos_next - pos_curr);

v@dir = dir;
i@vtx_next = vtx_next;```

Lastly you would filter out primitives by their inner angle between consecutive vertices:

```float tol = chf('tolerance');

int vtx[] = primvertices(0, i@primnum);
foreach(int vt; vtx){
int vtx_next = vertex(0, 'vtx_next', vt);
vector dir_0 = vertex(0, 'dir', vt);
vector dir_1 = vertex(0, 'dir', vtx_next);
float angle = dot(dir_0, dir_1);
if(abs(angle) > tol){
removeprim(0, i@primnum, 1);
break;
}
}```

• 1

##### Share on other sites

and what about, after removing non-quads, just testing (in loop per prim) whether the perimeter of a primitive (using measure SOP) is equal to a distance between any two points multiplied by 4? does it make sense?

## Create an account

Register a new account