mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-14 19:31:14 +00:00
Conflicts were only in include lists (CadDocument.cpp, SketchEngine.cpp); both sides' includes are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QK4VgguuCAk2hZLWgcjJb9
62 lines
3.1 KiB
C++
62 lines
3.1 KiB
C++
#ifndef slic3r_SketchInference_hpp_
|
|
#define slic3r_SketchInference_hpp_
|
|
|
|
#include "libslic3r/Point.hpp"
|
|
#include "libslic3r/CAD/SketchEngine.hpp"
|
|
#include <math.h>
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <cmath>
|
|
|
|
namespace Slic3r {
|
|
|
|
// Result of snapping a free cursor point onto the most relevant inference target
|
|
// among the committed sketch entities and the sketch origin. This is the backbone
|
|
// that lets geometry self-constrain as it is drawn: the GUI records the returned
|
|
// target at click time and, once the entity it belongs to exists, emits the
|
|
// matching constraint (Coincident onto an endpoint/centre, Fix onto the origin,
|
|
// PointOnObject onto an edge) so the relation survives a re-solve.
|
|
struct InferenceSnap {
|
|
enum class Kind { None, Endpoint, Center, Midpoint, OnEdge, Origin };
|
|
Kind kind{Kind::None};
|
|
int entity{-1}; // hit entity index (-1 = origin/none)
|
|
SketchPointRole role{SketchPointRole::P0}; // which point of `entity` (Endpoint/Center)
|
|
Vec2d point{0, 0}; // snapped coordinate (== query when None)
|
|
|
|
bool snapped() const { return kind != Kind::None; }
|
|
};
|
|
|
|
// Snap `query` onto the best inference target within `tol` plane units. Priority,
|
|
// highest first: Endpoint, Center, Origin, Midpoint, OnEdge. Construction entities
|
|
// participate (you constrain to them too). Returns {None, query} when nothing is in
|
|
// range. Pure — no GUI / GL dependencies, so it is unit-testable in libslic3r.
|
|
InferenceSnap infer_point_snap(const std::vector<SketchEntity>& entities,
|
|
const Vec2d& query, double tol,
|
|
bool include_origin = true);
|
|
|
|
// Relational inference for an in-progress segment anchor->tip. If its direction is
|
|
// within `ang_tol_rad` of an axis, returns Horizontal or Vertical (the constraint to
|
|
// auto-emit on the committed segment); std::nullopt otherwise. Degenerate (near-zero
|
|
// length) segments return nullopt.
|
|
// One angular tolerance for every "is this relation already true?" inference, so a pair of
|
|
// lines that reads as horizontal to one rule cannot read as not-quite-parallel to the other.
|
|
inline constexpr double kSketchInferAngleTol = 3.0 * M_PI / 180.0;
|
|
|
|
std::optional<SketchConstraintType>
|
|
infer_axis_constraint(const Vec2d& anchor, const Vec2d& tip, double ang_tol_rad = kSketchInferAngleTol);
|
|
|
|
// Relational constraints to auto-emit for a newly drawn entity `new_ei` against the
|
|
// entities already in the sketch. Pure, no GUI/GL dependencies, unit-testable.
|
|
//
|
|
// Deliberately conservative: every rule requires the relation to be ALREADY TRUE within
|
|
// tolerance, so an inferred constraint never moves geometry the user drew — it only pins a
|
|
// relation that is visibly there. Returns an empty vector when nothing qualifies.
|
|
std::vector<SketchEntityConstraintDef>
|
|
infer_relations(const std::vector<SketchEntity>& entities, int new_ei,
|
|
double ang_tol_rad = kSketchInferAngleTol,
|
|
double len_tol_frac = 0.01);
|
|
|
|
} // namespace Slic3r
|
|
|
|
#endif // slic3r_SketchInference_hpp_
|