Skip to content
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

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open

Mesh upsampler #274

wants to merge 2 commits into from

Conversation

marrts
Copy link
Contributor

@marrts marrts commented Oct 8, 2024

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:
Screenshot from 2024-10-07 22-15-21

To this;
Screenshot from 2024-10-07 22-15-27

Resulting in a toolpath going from this:
Screenshot from 2024-10-07 22-13-29

To this:
Screenshot from 2024-10-07 22-13-15

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);
Copy link
Member

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

Suggested change
layout->addLayout(form_layout);

std::vector<pcl::PolygonMesh> modify(const pcl::PolygonMesh& mesh) const override;

protected:
double max_area_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
double max_area_;
const double max_area_;

Comment on lines +124 to +126
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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());

Comment on lines +59 to +68
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();
Copy link
Member

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

Suggested change
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
Copy link
Member

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

Copy link
Member

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

Comment on lines +21 to +25
// 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;
Copy link
Member

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

Comment on lines +92 to +98
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;
Copy link
Member

@marip8 marip8 Oct 23, 2024

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 twopcl::PCLPointCloud` objects (i.e., the original mesh vertices and the newly added midpoints)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants