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.
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 groupif (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.
Vex snippet:
// Display points as sprite spheresif ( chi("visualize_spheres")){ setdetailattrib(geoself(), "gl_spherepoints", 1);}// Set init colorsetpointattrib(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
Brutforce method to remove points (Slowest with large pointcloud)
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
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)
float searchRadius = 0.00001;int foundPoints[] = pcfind(1, "P", @P, searchRadius, 1);
if (len(foundPoints) > 0) { @Cd = set(1,0,0); removepoint(0, @ptnum);}