Skip to content

Point cloud

XYZdist

Distance-Based Layered Point Selection

This operation involves selecting points within a specific range of distances from a reference geometry or surface. By calculating the distance between points and the reference, you can group points into layers based on their proximity. This technique is useful for creating layered effects or isolating specific regions of a point cloud for further manipulation.

Select point by layer

Point.wrangle
vector pos = @P;
int prim;
vector uvw;
float dist = xyzdist(1, pos, prim, uvw);
vector surface_pos = primuv(1, "P", prim, uvw);
vector offset = pos - surface_pos;
float min_offset = chf("min");
float max_offset = chf("max");
float offset_length = length(offset);
// Create point group
if (offset_length > min_offset && offset_length < max_offset) {
@group_selected_layer = 1;
@Cd = set(1, 0, 0);
}

Pcfind

Remove points by distance and number of neighbors

Next example shows how to remove points by distance and number of neighbors. Useful for cleaning pointclouds after different simulations when single spare points are not needed.

Remove points by distance

Vex snippet:

Point.wrangle
// Display points as sprite spheres
if ( chi("visualize_spheres")){
setdetailattrib(geoself(), "gl_spherepoints", 1);
}
// Set init color
setpointattrib(geoself(), "Cd", @ptnum, set(0,0.6,1), "set");
vector p1 = point(0, "P", 0);
float min_dist = ch("min_radius");
int min_near_points = chi("min_near_points");
int handle = pcopen(0, "P", @P, min_dist, min_near_points);
float radius = pcnumfound( handle) / float(min_near_points);
if ( radius < 1) {
setpointattrib(geoself(), "Cd", @ptnum, set(radius,0,0), "set");
// Remove points if true
if ( chi("remove_points") ) {
removepoint(0, @ptnum);
}
}

Remove redudant single points by pscale

Remove redudant single points which has large pscale between points with smaller pscale around them.

if ( chi("visualize_spheres")){
setdetailattrib(geoself(), "gl_spherepoints", 1);
}
setpointattrib(geoself(), "Cd", @ptnum, set(0,0.6,1), "set");
float search_dist = chf("search_distance");
int min_neighbour_points = chi("min_neighbor_points");
float min_pscale_main_pt = chf("min_pscale_main_point");
float min_pscale_neighbor = chf("min_pscale_neighbor");
float max_pscale_neighbor = chf("max_pscale_neighbor");
float pscale_current = @pscale;
if (pscale_current > min_pscale_main_pt) {
int closept[] = pcfind_radius(
0, "P", "pscale", min_pscale_neighbor, @P, search_dist, min_neighbour_points
);
int neighbor_count = 0;
foreach (int pt; closept) {
float pscale_neighbor = point(0, "pscale", pt);
if (pscale_neighbor < max_pscale_neighbor) {
neighbor_count++;
}
}
if (neighbor_count >= min_neighbour_points) {
setpointattrib(geoself(), "Cd", @ptnum, set(1,0,0), "set");
if ( chi("remove_points")) {
removepoint(0, @ptnum, 1);
}
}
}

Remove point intersection by pscale:

Detect point intersection by pscale and remove points

if ( chi("visualize_spheres")){
setdetailattrib(geoself(), "gl_spherepoints", 1);
}
setpointattrib(geoself(), "Cd", @ptnum, set(0,0.6,1), "set");
float min_pscale_neighbor = chf("min_pscale_neighbor");
float dist[];
int pts[] = pcfind_radius(0,'P','pscale',min_pscale_neighbor,@P,@pscale/2,chi('maxPt'),dist);
foreach(int i;int pt;pts){
if(pt == @ptnum) continue;
float pscale2 = point(0,'pscale',pt);
if( (((pscale2+@pscale)/2) > dist[i]) && (pscale2<@pscale) ){
setpointattrib(geoself(), "Cd", @ptnum, set(1,0,0), "set");
if ( chi("remove_points")) {
removepoint(0, @ptnum, 1);
}
}
}

Remove points which have the same position

remove points with the same P

Brutforce method to remove points (Slowest with large pointcloud)

Point.wrangle
int ptcount = npoints(1);
i@num = ptcount;
vector pos1 = @P;
for( int i=0; i < ptcount; ++i){
vector pos2 = point(1, "P", i);
if ( pos1 == pos2 ){
@Cd = set(1,0,0);
removepoint(0, @ptnum);
}
}

PcOpen method to remove points

Point.wrangle
int handle = pcopen(1, "P", @P, 0.00001, 1);
if (pcnumfound(handle) > 0) {
@Cd = set(1,0,0);
removepoint(0, @ptnum);
}

PcFind method to remove points (fastest one)

Point.wrangle
float searchRadius = 0.00001;
int foundPoints[] = pcfind(1, "P", @P, searchRadius, 1);
if (len(foundPoints) > 0) {
@Cd = set(1,0,0);
removepoint(0, @ptnum);
}