template<typename PointT> void pcl::CropHull<PointT>::applyFilter3D (std::vector<int> &indices) { // see comments in applyFilter3D (PointCloud& output) for (size_t index = 0; index < indices_->size (); index++) { size_t crossings[3] = {0,0,0}; Eigen::Vector3f rays[3] = { Eigen::Vector3f(0.264882f, 0.688399f, 0.675237f), Eigen::Vector3f(0.0145419f, 0.732901f, 0.68018f), Eigen::Vector3f(0.856514f, 0.508771f, 0.0868081f) }; for (size_t poly = 0; poly < hull_polygons_.size (); poly++) for (size_t ray = 0; ray < 3; ray++) crossings[ray] += rayTriangleIntersect (input_->points[(*indices_)[index]], rays[ray], hull_polygons_[poly], *hull_cloud_); if (crop_outside_ && (crossings[0]&1) + (crossings[1]&1) + (crossings[2]&1) > 1) indices.push_back ((*indices_)[index]); else if (!crop_outside_) indices.push_back ((*indices_)[index]); } }
template<typename PointT> void pcl::CropHull<PointT>::applyFilter3D (PointCloud &output) { // This algorithm could definitely be sped up using kdtree/octree // information, if that is available! for (size_t index = 0; index < indices_->size (); index++) { // test ray-crossings for three random rays, and take vote of crossings // counts to determine if each point is inside the hull: the vote avoids // tricky edge and corner cases when rays might fluke through the edge // between two polygons // 'random' rays are arbitrary - basically anything that is less likely to // hit the edge between polygons than coordinate-axis aligned rays would // be. size_t crossings[3] = {0,0,0}; Eigen::Vector3f rays[3] = { Eigen::Vector3f (0.264882f, 0.688399f, 0.675237f), Eigen::Vector3f (0.0145419f, 0.732901f, 0.68018f), Eigen::Vector3f (0.856514f, 0.508771f, 0.0868081f) }; for (size_t poly = 0; poly < hull_polygons_.size (); poly++) for (size_t ray = 0; ray < 3; ray++) crossings[ray] += rayTriangleIntersect (input_->points[(*indices_)[index]], rays[ray], hull_polygons_[poly], *hull_cloud_); if (crop_outside_ && (crossings[0]&1) + (crossings[1]&1) + (crossings[2]&1) > 1) output.push_back (input_->points[(*indices_)[index]]); else if (!crop_outside_) output.push_back (input_->points[(*indices_)[index]]); } }
int main(int argc, char **argv) { Vec3f v0(-1, -1, -5); Vec3f v1( 1, -1, -5); Vec3f v2( 0, 1, -5); const uint32_t width = 640; const uint32_t height = 480; Vec3f cols[3] = {{0.6, 0.4, 0.1}, {0.1, 0.5, 0.3}, {0.1, 0.3, 0.7}}; Vec3f *framebuffer = new Vec3f[width * height]; Vec3f *pix = framebuffer; float fov = 51.52; float scale = tan(deg2rad(fov * 0.5)); float imageAspectRatio = width / (float)height; Vec3f orig(0); for (uint32_t j = 0; j < height; ++j) { for (uint32_t i = 0; i < width; ++i) { // compute primary ray float x = (2 * (i + 0.5) / (float)width - 1) * imageAspectRatio * scale; float y = (1 - 2 * (j + 0.5) / (float)height) * scale; Vec3f dir(x, y, -1); dir.normalize(); float t, u, v; if (rayTriangleIntersect(orig, dir, v0, v1, v2, t, u, v)) { // [comment] // Interpolate colors using the barycentric coordinates // [/comment] *pix = u * cols[0] + v * cols[1] + (1 - u - v) * cols[2]; // uncomment this line if you want to visualize the row barycentric coordinates //*pix = Vec3f(u, v, 1 - u - v); } pix++; } } // Save result to a PPM image (keep these flags if you compile under Windows) std::ofstream ofs("./out.ppm", std::ios::out | std::ios::binary); ofs << "P6\n" << width << " " << height << "\n255\n"; for (uint32_t i = 0; i < height * width; ++i) { char r = (char)(255 * clamp(0, 1, framebuffer[i].x)); char g = (char)(255 * clamp(0, 1, framebuffer[i].y)); char b = (char)(255 * clamp(0, 1, framebuffer[i].z)); ofs << r << g << b; } ofs.close(); delete [] framebuffer; return 0; }