Jump to content

remove primitives that are not perfect rectangles


anicg

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
Link to comment
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;
            }
        }
    }
}

 

  • Like 1
Link to comment
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;
    }
}

 

keep_rect_quads.hipnc

  • Like 1
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...