feat: 3D constraint solver for assembly (coincident/concentric/distance)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file constraint_solver.h
|
||||
* @brief 3D constraint solver for assembly
|
||||
*
|
||||
* Iterative relaxation solver for spatial constraints between assembly nodes.
|
||||
* Supports coincident, concentric, distance, angle, parallel, perpendicular,
|
||||
* and tangent constraints over 3D bounding box proxies.
|
||||
*
|
||||
* @ingroup brep
|
||||
*/
|
||||
#include "vde/brep/assembly.h"
|
||||
#include "vde/core/point.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/// Constraint type for 3D assembly solving
|
||||
enum class Constraint3D {
|
||||
Coincident, ///< Face-face alignment (coplanar, opposite normals)
|
||||
Concentric, ///< Axis-axis alignment
|
||||
Distance, ///< Fixed distance between faces
|
||||
Angle, ///< Fixed angle between faces
|
||||
Parallel, ///< Face normals parallel
|
||||
Perpendicular, ///< Face normals perpendicular
|
||||
Tangent ///< Face tangent contact
|
||||
};
|
||||
|
||||
/// A single constraint between two assembly nodes
|
||||
struct ConstraintEntry {
|
||||
int node_a; ///< Index into a flattened node list (or 0-based child index)
|
||||
int node_b; ///< Index of the node that moves to satisfy constraint
|
||||
Constraint3D type;
|
||||
double value = 0.0; ///< Distance or angle value (radians for Angle)
|
||||
};
|
||||
|
||||
/// Solve a system of 3D constraints on an assembly using iterative relaxation.
|
||||
///
|
||||
/// Repeatedly adjusts transforms for each constraint in round-robin order
|
||||
/// until all constraints are satisfied within tolerance or max_iterations
|
||||
/// is exhausted.
|
||||
///
|
||||
/// @param assembly Target assembly (root children are the constrained nodes)
|
||||
/// @param constraints Ordered list of constraints to satisfy
|
||||
/// @param max_iterations Maximum number of relaxation passes (default 100)
|
||||
/// @param tolerance Convergence tolerance (default 1e-6)
|
||||
/// @return true if all constraints satisfied within tolerance
|
||||
[[nodiscard]] bool solve_constraints(
|
||||
Assembly& assembly,
|
||||
const std::vector<ConstraintEntry>& constraints,
|
||||
int max_iterations = 100,
|
||||
double tolerance = 1e-6);
|
||||
|
||||
/// Apply a single coincident (mate) constraint: align the closest opposing
|
||||
/// faces of node_a and node_b so they are coplanar.
|
||||
///
|
||||
/// @return The correction transform that was applied to node_b
|
||||
[[nodiscard]] core::Transform3D apply_coincident(
|
||||
const AssemblyNode& node_a, AssemblyNode& node_b);
|
||||
|
||||
/// Apply a single concentric constraint: align the bounding-box-estimated
|
||||
/// cylinder axes of node_a and node_b.
|
||||
///
|
||||
/// @return The correction transform that was applied to node_b
|
||||
[[nodiscard]] core::Transform3D apply_concentric(
|
||||
const AssemblyNode& node_a, AssemblyNode& node_b);
|
||||
|
||||
/// Apply a distance constraint: set the closest-approach gap between
|
||||
/// the bounding boxes of node_a and node_b to @p distance.
|
||||
///
|
||||
/// @return The correction transform that was applied to node_b
|
||||
[[nodiscard]] core::Transform3D apply_distance(
|
||||
const AssemblyNode& node_a, AssemblyNode& node_b, double distance);
|
||||
|
||||
} // namespace vde::brep
|
||||
Reference in New Issue
Block a user