Object Aligned Bounding Box (OBB) Subdivision

   1349   4   0
User Avatar
Member
5 posts
Joined: July 2018
Offline
Implemented Houdini SOP to subdivide input primitive using OBB. Good for Parcel subdivision while creating procedural city layout.
Referred paper by Müller and Team [www.cs.purdue.edu]
Road side check is not added to the SOP as specified in the paper. Current approach check min area as the base condition for recursion.

Works only on ZX plane

Refer the video for implementation detail:
User Avatar
Member
172 posts
Joined: May 2021
Offline
This is great! I really enjoyed this paper as well and also Tom Kelly's PhD is worth checking out if you haven't seen that:
Unwritten procedural modeling with the straight
skeleton.
[theses.gla.ac.uk]
PHENOM(enological) DESIGN;
Experimental phenomenology (study of experience) is a category of philosophy evidencing intentional variations of subjective human experiencing where both the independent and dependent variable are phenomenological. Lundh 2020
User Avatar
Member
5 posts
Joined: July 2018
Offline
Hi PHENOM DESIGN, Thanks for the paper. I have gone through the paper and attempted to create the Skeleton based parcel generation. But in the paper I am not able to to find logic to create "logical streets" which is very essential for &-strip creation. I tried searching for this crucial information. But not able to find. I want to split streets to create logical street procedurally so that user can avoid identifying streets manually
User Avatar
Member
172 posts
Joined: May 2021
Offline
Ok, for street-level logic, I have in the past, developed economic lore based on resources in the landscape and used that for path planning of transportation based on attributes. I grew the cities and the zones over small time frames, layed the road network logic. I did not "lay the concrete" so my ability to help my be limited on the very detailed street modules you will need to develop.

Since then the newer Labs settlement tools have really codified and standardized this process. So I would definitely make use of the great tools there. Pegasus Project tutorials could help explain the steps for that:

https://www.sidefx.com/tutorials/project-pegasus-roads-tracks-and-rivers/ [www.sidefx.com]

Here are some paper resources, let me know if you would like more direct technical advice or enjoy the freedom research references provide in implementation. There was a ton of tools added to Houdini for Matrix Resurrections for street logic.

https://smartcodecentral.com/ [smartcodecentral.com]

https://www.cs.purdue.edu/cgvlab/urban/urban-procedural-modeling.html [www.cs.purdue.edu]

https://www.sci.utah.edu/~chengu/street_sig08/street_project.htm [www.sci.utah.edu]

https://cgg.mff.cuni.cz/~benes/PMoURN/data/ProceduralModellingOfUrbanRoadNetworks.pdf [cgg.mff.cuni.cz]

https://cgl.ethz.ch/Downloads/Publications/Papers/2001/p_Par01.pdf [cgl.ethz.ch]

https://repository.rit.edu/cgi/viewcontent.cgi?article=6536&context=theses [repository.rit.edu]

https://www.media.mit.edu/publications/cityscope/ [www.media.mit.edu]

https://aber.apacsci.com/index.php/cd/article/viewFile/1940/2087 [aber.apacsci.com]
PHENOM(enological) DESIGN;
Experimental phenomenology (study of experience) is a category of philosophy evidencing intentional variations of subjective human experiencing where both the independent and dependent variable are phenomenological. Lundh 2020
User Avatar
Member
5 posts
Joined: July 2018
Offline
Pasting entire vex code of compute_data_from_obb detail_wrangler referred in the OBB video:

int closest_point = -1;
float min_distance = 1e10;  // Large initial value

// Get the minimum bounding box coordinates
vector bbox_min = getbbox_min(0);

// Loop through all points to find the one closest to bbox_min
int num_points = npoints(0);

for (int i = 0; i < num_points; i++)
{
    vector pt_pos = point(0, "P", i);  // Get the position of the point
    float distance = length(pt_pos - bbox_min);  // Calculate the distance to bbox_min

    if (distance < min_distance)
    {
        min_distance = distance;
        closest_point = i;  // Update the closest point index
    }
}
i@closest_point = closest_point;

f@minLength = 1e10; // Initialize with a large number
f@maxLength = 0.0;  // Initialize with a small number

// Initialize direction vectors
v@minDir = {0, 0, 0}; 
v@maxDir = {0, 0, 0};

float allLength[] = array();
vector allDir[] = array();
if(closest_point >= 0 ) {
    vector pos0 = point(0, "P", closest_point);
    int neighPoints[] = neighbours(0, closest_point);
    
    for(int i=0; i<len(neighPoints); ++i) {
        vector pos1 = point(0, "P", neighPoints[i]);
        vector direction = pos1 - pos0;
        float length = length(direction);
        vector unit_direction = normalize(direction);
        append(allLength, length);
        append(allDir, unit_direction);
    }
    
    if(allLength[0] < allLength[1]) {
        f@minLength = allLength[0];
        v@minDir = allDir[0];
        f@maxLength = allLength[1];
        v@maxDir = allDir[1];
    } else if (allLength[0] > allLength[1]) {
        f@minLength = allLength[1];
        v@minDir = allDir[1];
        f@maxLength = allLength[0];
        v@maxDir = allDir[0];    
    } else {
        f@minLength = allLength[0];
        v@minDir = allDir[0];
        f@maxLength = allLength[1];
        v@maxDir = allDir[1];    
    }
}
Edited by bvr.holla - Sept. 20, 2024 08:36:04
  • Quick Links