-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mesh upsampler #274
base: dev
Are you sure you want to change the base?
Mesh upsampler #274
Conversation
max_area_->setSingleStep(0.005); | ||
max_area_->setDecimals(4); | ||
form_layout->addRow(new QLabel("Max Area (m^2)", this), max_area_); | ||
layout->addLayout(form_layout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed if you create this layout with this
as the argument
layout->addLayout(form_layout); |
std::vector<pcl::PolygonMesh> modify(const pcl::PolygonMesh& mesh) const override; | ||
|
||
protected: | ||
double max_area_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double max_area_; | |
const double max_area_; |
midpoint.x = 0.5f * (v_start.x + v_end.x); | ||
midpoint.y = 0.5f * (v_start.y + v_end.y); | ||
midpoint.z = 0.5f * (v_start.z + v_end.z); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
midpoint.x = 0.5f * (v_start.x + v_end.x); | |
midpoint.y = 0.5f * (v_start.y + v_end.y); | |
midpoint.z = 0.5f * (v_start.z + v_end.z); | |
midpoint.getVector3fMap() = 0.5f * (v_start.getVector3fMap() + v_end.getVector3fMap()); |
pcl::PointXYZ v0 = vertices[idx0]; | ||
pcl::PointXYZ v1 = vertices[idx1]; | ||
pcl::PointXYZ v2 = vertices[idx2]; | ||
|
||
// Compute area of triangle | ||
Eigen::Vector3f p0(v0.x, v0.y, v0.z); | ||
Eigen::Vector3f p1(v1.x, v1.y, v1.z); | ||
Eigen::Vector3f p2(v2.x, v2.y, v2.z); | ||
|
||
float area = 0.5f * ((p1 - p0).cross(p2 - p0)).norm(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to simplify just a little
pcl::PointXYZ v0 = vertices[idx0]; | |
pcl::PointXYZ v1 = vertices[idx1]; | |
pcl::PointXYZ v2 = vertices[idx2]; | |
// Compute area of triangle | |
Eigen::Vector3f p0(v0.x, v0.y, v0.z); | |
Eigen::Vector3f p1(v1.x, v1.y, v1.z); | |
Eigen::Vector3f p2(v2.x, v2.y, v2.z); | |
float area = 0.5f * ((p1 - p0).cross(p2 - p0)).norm(); | |
pcl::PointXYZ v0 = vertices[idx0]; | |
pcl::PointXYZ v1 = vertices[idx1]; | |
pcl::PointXYZ v2 = vertices[idx2]; | |
// Compute area of triangle | |
Eigen::Vector3f e1 = (v1.getArray3fMap() - v0.getArray3fMap()); | |
Eigen::Vector3f e2 = (v2.getArray3fMap() - v0.getArray3fMap()); | |
float area = 0.5f * (e1.cross(e2).norm(); |
|
||
namespace noether | ||
{ | ||
class UpsamplingMeshModifier : public MeshModifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to call this something a little more specific like AreaBasedUpsamplingMeshModifier
? I could also see another implementation of this upsampler that looks at edge length rather than area which would need a differentiated class name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also make another instance of this based on PCL mesh subdivision using VTK
// Helper function to get or create midpoint | ||
uint32_t getOrCreateMidpoint(uint32_t idx_start, | ||
uint32_t idx_end, | ||
std::vector<pcl::PointXYZ, Eigen::aligned_allocator<pcl::PointXYZ>>& vertices, | ||
std::map<std::pair<uint32_t, uint32_t>, uint32_t>& edge_midpoints) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this to the source file; seems pretty specific to this class
pcl::PointCloud<pcl::PointXYZ> new_cloud; | ||
new_cloud.points = vertices; | ||
|
||
pcl::PolygonMesh output_mesh; | ||
pcl::toPCLPointCloud2(new_cloud, output_mesh.cloud); | ||
output_mesh.polygons = final_faces; | ||
output_mesh.header = mesh.header; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will remove all other extraneous data from the mesh (e.g., color, normals, curvature, etc.). It's probably worth looking a little more into preserving that information for the newly generated midpoints. It seems like it should be possible by adding the midpoints to the end of the vertex list and interpolating the extraneous data based on its two edge endpoints. Then you could use this function to cull the unreferenced vertices. You can also used functions like pcl::concatenate
and pcl::concatenateFieldsto combine two
pcl::PCLPointCloud` objects (i.e., the original mesh vertices and the newly added midpoints)
The primary motivation for this was to fix an issue with the ROI selection mesh modifier in snp_tpp that would perform poorly with sparse meshes, but this felt better suited to go here.
This takes a single parameter (Max alllowed area) and continually subdivides all triangles greater than this area until all triangles on the mesh are the right size.
The mesh goes from this:
To this;
Resulting in a toolpath going from this:
To this: