Skip to content

Conversation

Copy link

Copilot AI commented Nov 8, 2025

Implements region-growing algorithm to split DEMMeshConnected into convex patches based on face normal angle thresholds. Patches enable future mesh-based contact force optimization.

Changes

Core functionality (src/DEM/MeshUtils.cpp)

  • SplitIntoConvexPatches(angle_threshold_deg): Groups adjacent triangles with normals differing by less than threshold
  • SetPatchIDs(patch_ids): Allows manual specification of patch assignments for each triangle
  • Helper functions for face normal computation, angle calculation, and adjacency mapping
  • Region-growing implementation: O(n·m) where n=triangles, m=avg neighbors
  • Default initialization: All triangles assigned to patch 0 on mesh load (assumes convex mesh)

Data model (src/DEM/BdrsAndObjs.h)

  • m_patch_ids: Per-triangle patch assignment (defaults to all 0s)
  • num_patches: Total patch count (defaults to 1)
  • patches_explicitly_set: Flag indicating if patches were explicitly set vs. using default
  • Accessors: GetPatchIDs(), GetNumPatches(), ArePatchesExplicitlySet()
  • Updated Clear() to reset patch data to defaults

Test demo (src/demo/DEMdemo_MeshPatch.cpp)

  • Validates default patch behavior (single patch 0)
  • Tests automatic splitting at multiple angle thresholds (10°-90°)
  • Demonstrates manual patch ID assignment
  • Tests sphere meshes and edge cases
  • Reports patch statistics and distribution

Usage

Default behavior (assumes convex mesh):

auto mesh = std::make_shared<DEMMeshConnected>("mesh.obj");
// By default: all triangles in patch 0
assert(mesh->GetNumPatches() == 1);

Automatic splitting:

size_t num_patches = mesh->SplitIntoConvexPatches(30.0f);  // 30° threshold
const auto& patch_ids = mesh->GetPatchIDs();  // One ID per triangle

Manual patch assignment:

std::vector<int> custom_patches = {0, 0, 1, 1, 2, 2, ...};
mesh->SetPatchIDs(custom_patches);  // Manually specify patches

Lower thresholds yield more patches (stricter convexity); higher thresholds yield fewer patches. Patches are non-overlapping and cover the entire mesh.

Original prompt

As the start of the mesh redesign, we need a utility that splits the mesh (a DEMMeshConnected object) into "patches". Each patch represents a part of this 3D surface mesh that can be considered convex. No overlap between patches and all patches combine to be the full original surface mesh. This is useful later in the related contact force calculation. You can do that by splitting the mesh by a certain user-supplied threshold angle, or some other smart way. Then DEMMeshConnected will have some ways to hold this split patch information in it (although at this point it does not use this info yet). You can create a test demo for this functionality (but keep in mind that this demo later will be used to test many things we add later in this effort), but no need to add extensive documentation for this method except for some comments.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits November 8, 2025 14:26
Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
Copilot AI changed the title [WIP] Add utility to split mesh into convex patches Add mesh patch splitting for convex decomposition Nov 8, 2025
Copilot AI requested a review from Ruochun November 8, 2025 14:36
Copilot finished work on behalf of Ruochun November 8, 2025 14:36
@Ruochun
Copy link
Collaborator

Ruochun commented Nov 8, 2025

@copilot One improvement needed: The default patch info should be present, and that should be "all mesh is one patch", aka we assume the mesh is convex if the user does not do anything. And we should allow a method to let the user manually supply patch info, as a vector of integers that manually specifies the patch ID for each triangle.

Co-authored-by: Ruochun <24469442+Ruochun@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 8, 2025

@copilot One improvement needed: The default patch info should be present, and that should be "all mesh is one patch", aka we assume the mesh is convex if the user does not do anything. And we should ...

Implemented both improvements in commit 7b7b740:

  1. Default patch info: Meshes now initialize with all triangles in patch 0 (assuming convex). The m_patch_ids vector is populated with zeros when a mesh is loaded.

  2. Manual patch setting: Added SetPatchIDs(const std::vector<int>& patch_ids) method that:

    • Validates input size matches triangle count
    • Ensures all patch IDs are non-negative
    • Automatically calculates num_patches from max ID

The API now uses patches_explicitly_set flag and ArePatchesExplicitlySet() method to distinguish between default (single patch) and explicitly set patches. Demo updated to test all three scenarios: default, automatic splitting, and manual setting.

Copilot AI changed the title Add mesh patch splitting for convex decomposition Add mesh patch splitting with default convex assumption and manual patch assignment Nov 8, 2025
Copilot finished work on behalf of Ruochun November 8, 2025 17:30
@Ruochun Ruochun marked this pull request as ready for review November 10, 2025 10:25
@Ruochun Ruochun merged commit 937020d into Redesign_mesh_hierarchy Nov 10, 2025
@Ruochun Ruochun deleted the copilot/split-mesh-into-patches branch November 10, 2025 10:25
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