How to separate Overlapping Primitives

   5866   7   1
User Avatar
Member
16 posts
Joined: June 2017
Offline
Hi

I was trying to separate overlapping primitives and wanted to do it via bounding box. So basically have it move away from each other and then I want to try to reverse the result back to what it was originally still overlapping.

I tried doing the exploded view but I found some objects still where overlapping(intersecting).

Is there a node that already does this or a recommendation of somewhere I could start. I am still learning Vex in Houdini.

Thanks
Imran
User Avatar
Member
149 posts
Joined: Oct. 2015
Offline
Hello
Maybe you could share a Hip file !?
That's not easy to figure what you're trying to do !
If it's a kind of “organic” figure you could try the detangle node
if they are really overlaping you could use polydoctor or clean node for fixing it
if they are more intersecting sometime a boolean could do a watertight stuff
one again , sharing the Hip file is the best !

Ben
User Avatar
Member
16 posts
Joined: June 2017
Offline


Hi

I don't have a file yet. Tried a few things like the exploded view but it doesn't move things out of there way and they are still tend to intersect a little.

I am trying to separate each piece so I can run some deformations on each one. My findings so far are if a run some kind of capture node it bleeds into the other objects (if they are not separated). I also tried a for loop but that I find very slow (to run a capture and other deformers).

Essentially if i can make sure they are not touching, when I run the deformers (or anything) then return them to there original position (intersecting/overlapping) .

Thanks
Imran
Edited by im_a - Sept. 22, 2019 13:52:29

Attachments:
OVerlappingObjects.PNG (271.0 KB)

User Avatar
Member
149 posts
Joined: Oct. 2015
Offline
Hello
In this case you could use a connectivity node that create an attribute per connected piece
and use this attribute in a wrangle to move piece appart the way you want
and bring it back to rest position after that > v@P=v@rest on the last wrangle
Edited by Benjamin Lemoine - Sept. 23, 2019 00:08:57

Attachments:
SharedScreenshot.jpg (234.4 KB)

User Avatar
Member
16 posts
Joined: June 2017
Offline
Thanks Ben

That works really well. I am going to go thru some vex stuff to figure out the distance between each piece. Also I didn't know about the rest node.

-Imran
User Avatar
Member
8 posts
Joined: Sept. 2019
Offline

/*
Because of my interest in VEX (very new here), am happy to practice it.
Little research has been done for learning purposes :)
But i stopped at detecting points... so it does not push.. just detects.
Happy Learning (c) kodbitz(at)gmail.com

1. Connect Geometry that have multiple connected parts to Connectivity OP
2. Connectivity OP
2.1 change type from default Points to Primitives
2.2 change Attribute to 'parts' or '$OS' and rename operator to 'parts'
3. Create Attribute Wrangle OP
3.1 Change 'Run Over' to 'Detal'
4. Paste VEX code to VEXpression
*/

string
parts_name = 'parts', // name for attribute created with connectivity operator
output_base_group_name = parts_name,
target_attribute_class = 'prim'; // parts are for primitives so we work with them

int
source = 0, // source object
/*
by using 'uniquevals',
return the set of unique values across all values for an int or string attribute
get array of unique (no duplicates) attribute values for our attribute
named 'parts' that was created by connectivity operator
https://www.sidefx.com/docs/houdini/vex/functions/uniquevals.html
*/
parts_attrib_list[] = uniquevals(source, target_attribute_class, parts_name),
parts_total_count = len(parts_attrib_list), // amount of objects (connected geometries)
points_total_count = @numpt; // amount of all points in input source

/*start main iteration through each connected geometry*/
 foreach (int part; parts_attrib_list){
    int
    rest_parts_attrib_list[],
    parts_prim_id_list[],
    part_prim_points_id_list[];

     
    foreach (int part_id; parts_attrib_list) {
        if(part_id != part) push(rest_parts_attrib_list, part_id); 
        else { /* else make data for current part */
            /*
            by using 'findattribval',
            find a primitive that has a certain attribute value
            get array of ids for primitives that current connected geometry (int part) have
            notes: if we do not use last argument of function named 'which', function returns array at once.
            https://www.sidefx.com/docs/houdini/vex/functions/findattribval.html
            */
            parts_prim_id_list = findattribval(source, target_attribute_class, parts_name, part);
            foreach (int prim_id; parts_prim_id_list) push(part_prim_points_id_list, primpoints(source, prim_id));
        }
    }
    foreach (int rest_part_id; rest_parts_attrib_list){
        /*construct group name for current point*/
        string output_intersaction_group_name = concat(output_base_group_name, '_', itoa(part), '_', itoa(rest_part_id));
        /*same as for parts_prim_id_list but for rest parts*/
        int rest_parts_prim_id_list[] = findattribval(source, target_attribute_class, parts_name, rest_part_id);
        // group + primpoints for each rest geo

        /* extra task >>
        prepare groups for future use with 'xyzdist':
        'xyzdist' accepts group creation by providing string as it would be SOP selector like;
        so we convert int array to string with space as delimiter
        */
        string
        part_temp_array[],
        delimiter = ' ';
        /*
        1. convert integer to string
        2. transfer data from int array into temporary string array
        */
        foreach (int prim_id; rest_parts_prim_id_list) push(part_temp_array, itoa(prim_id));
        /*
        3. join temporary array with space delimiter
        */
        string part_xyzdist_group_string = join(part_temp_array, delimiter);
        /* << end of extra task */

        /*start iteration through points of current part*/
        foreach (int point_id; part_prim_points_id_list){
            vector point_position = point(source, 'P', point_id); // get point position

            /*initialize for export from xyzdist()*/
            vector prim_xyzdist_uv; // uv will be set by xyzdist()
            int prim_xyzdist_id; // id will be set by xyzdist()

            /*
            execute xyzdist() to find the distance of a point to a geometry with:
            1. our group from extra task
            2. current point position
            3. provide where results will be exported to: prim_xyzdist_uv, prim_xyzdist_id       
            https://www.sidefx.com/docs/houdini/vex/functions/xyzdist.html
            */
            xyzdist(source, part_xyzdist_group_string, point_position, prim_xyzdist_id, prim_xyzdist_uv);
            // from here prim_xyzdist_uv and prim_xyzdist_id are filled with data and ready to use

            vector
            /*
            get primitive position at the given uv coordinates
            https://www.sidefx.com/docs/houdini/vex/functions/primuv.html
            */
            prim_position = primuv(source, 'P', prim_xyzdist_id, prim_xyzdist_uv),
            /*
            get normal at uv location
            https://www.sidefx.com/docs/houdini/vex/functions/prim_normal.html
            */
            prim_normals = normalize(prim_normal(source, prim_xyzdist_id, prim_xyzdist_uv.x, prim_xyzdist_uv.y)),
            /*get position difference between current point and primirive*/
            point_vs_prim = normalize(point_position - prim_position);

            float point_vs_prim_angle = degrees(atan2(length(cross(point_vs_prim, prim_normals)), dot(point_vs_prim, prim_normals)));

            int
            /*out kind of filter*/
            point_vs_prim_angle_limit = 90,
            /*checking rule*/
            can_set_group = point_vs_prim_angle_limit < point_vs_prim_angle ? 1 : 0;
            /*set group by rule above with constructed name*/
            setpointgroup(source, output_intersaction_group_name, point_id, can_set_group, 'set');
            
            /*extra tasks*/
            if(can_set_group){
                // if group can be set
            } else {
                // if group can not be set
            }
        

        } 
    }

 }

Attachments:
houdini_detail_wrangle_search_intersaction.PNG (338.8 KB)

User Avatar
Member
16 posts
Joined: June 2017
Offline
kodbitz
Image Not Found

/*
Because of my interest in VEX (very new here), am happy to practice it.
Little research has been done for learning purposes :)
But i stopped at detecting points... so it does not push.. just detects.
Happy Learning (c) kodbitz(at)gmail.com

1. Connect Geometry that have multiple connected parts to Connectivity OP
2. Connectivity OP
2.1 change type from default Points to Primitives
2.2 change Attribute to 'parts' or '$OS' and rename operator to 'parts'
3. Create Attribute Wrangle OP
3.1 Change 'Run Over' to 'Detal'
4. Paste VEX code to VEXpression
*/

string
parts_name = 'parts', // name for attribute created with connectivity operator
output_base_group_name = parts_name,
target_attribute_class = 'prim'; // parts are for primitives so we work with them

int
source = 0, // source object
/*
by using 'uniquevals',
return the set of unique values across all values for an int or string attribute
get array of unique (no duplicates) attribute values for our attribute
named 'parts' that was created by connectivity operator
https://www.sidefx.com/docs/houdini/vex/functions/uniquevals.html
*/
parts_attrib_list[] = uniquevals(source, target_attribute_class, parts_name),
parts_total_count = len(parts_attrib_list), // amount of objects (connected geometries)
points_total_count = @numpt; // amount of all points in input source

/*start main iteration through each connected geometry*/
 foreach (int part; parts_attrib_list){
    int
    rest_parts_attrib_list[],
    parts_prim_id_list[],
    part_prim_points_id_list[];

     
    foreach (int part_id; parts_attrib_list) {
        if(part_id != part) push(rest_parts_attrib_list, part_id); 
        else { /* else make data for current part */
            /*
            by using 'findattribval',
            find a primitive that has a certain attribute value
            get array of ids for primitives that current connected geometry (int part) have
            notes: if we do not use last argument of function named 'which', function returns array at once.
            https://www.sidefx.com/docs/houdini/vex/functions/findattribval.html
            */
            parts_prim_id_list = findattribval(source, target_attribute_class, parts_name, part);
            foreach (int prim_id; parts_prim_id_list) push(part_prim_points_id_list, primpoints(source, prim_id));
        }
    }
    foreach (int rest_part_id; rest_parts_attrib_list){
        /*construct group name for current point*/
        string output_intersaction_group_name = concat(output_base_group_name, '_', itoa(part), '_', itoa(rest_part_id));
        /*same as for parts_prim_id_list but for rest parts*/
        int rest_parts_prim_id_list[] = findattribval(source, target_attribute_class, parts_name, rest_part_id);
        // group + primpoints for each rest geo

        /* extra task >>
        prepare groups for future use with 'xyzdist':
        'xyzdist' accepts group creation by providing string as it would be SOP selector like;
        so we convert int array to string with space as delimiter
        */
        string
        part_temp_array[],
        delimiter = ' ';
        /*
        1. convert integer to string
        2. transfer data from int array into temporary string array
        */
        foreach (int prim_id; rest_parts_prim_id_list) push(part_temp_array, itoa(prim_id));
        /*
        3. join temporary array with space delimiter
        */
        string part_xyzdist_group_string = join(part_temp_array, delimiter);
        /* << end of extra task */

        /*start iteration through points of current part*/
        foreach (int point_id; part_prim_points_id_list){
            vector point_position = point(source, 'P', point_id); // get point position

            /*initialize for export from xyzdist()*/
            vector prim_xyzdist_uv; // uv will be set by xyzdist()
            int prim_xyzdist_id; // id will be set by xyzdist()

            /*
            execute xyzdist() to find the distance of a point to a geometry with:
            1. our group from extra task
            2. current point position
            3. provide where results will be exported to: prim_xyzdist_uv, prim_xyzdist_id       
            https://www.sidefx.com/docs/houdini/vex/functions/xyzdist.html
            */
            xyzdist(source, part_xyzdist_group_string, point_position, prim_xyzdist_id, prim_xyzdist_uv);
            // from here prim_xyzdist_uv and prim_xyzdist_id are filled with data and ready to use

            vector
            /*
            get primitive position at the given uv coordinates
            https://www.sidefx.com/docs/houdini/vex/functions/primuv.html
            */
            prim_position = primuv(source, 'P', prim_xyzdist_id, prim_xyzdist_uv),
            /*
            get normal at uv location
            https://www.sidefx.com/docs/houdini/vex/functions/prim_normal.html
            */
            prim_normals = normalize(prim_normal(source, prim_xyzdist_id, prim_xyzdist_uv.x, prim_xyzdist_uv.y)),
            /*get position difference between current point and primirive*/
            point_vs_prim = normalize(point_position - prim_position);

            float point_vs_prim_angle = degrees(atan2(length(cross(point_vs_prim, prim_normals)), dot(point_vs_prim, prim_normals)));

            int
            /*out kind of filter*/
            point_vs_prim_angle_limit = 90,
            /*checking rule*/
            can_set_group = point_vs_prim_angle_limit < point_vs_prim_angle ? 1 : 0;
            /*set group by rule above with constructed name*/
            setpointgroup(source, output_intersaction_group_name, point_id, can_set_group, 'set');
            
            /*extra tasks*/
            if(can_set_group){
                // if group can be set
            } else {
                // if group can not be set
            }
        

        } 
    }

 }

This is great. I just found some videos I was going thru this week to get a starting understanding on Vex. This gives me nice head start.

Thanks
-Imran
User Avatar
Member
8 posts
Joined: Sept. 2019
Offline
im_a
This is great. I just found some videos I was going thru this week to get a starting understanding on Vex. This gives me nice head start.

Thanks
-Imran
From my memory the only vex course helped me to start was VEX Fundamentals [davidkahl-vfx.com] from David Kahl. He and 'Indie-Pixel [www.youtube.com]' only the guys who speak clean and in target without any missing detail.
  • Quick Links