forked from 1b-agent/opencadstudio-upstream
feat: node graph overlay; move to opencadcodec/opencadkernel/opencadgraph
The codec and kernel repositories and crates are renamed opencadcodec and opencadkernel. Inside OCS they are depended on under short keys, so code reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node graph engine). File-format and protocol spellings stay as they were: the ACIS product id `acadrust`, the ACADRUST_* switches and the plugin version keys `acadrust_version` / `acadrust_source`. A button left of MCP on the command line opens a translucent node graph over the viewport, with a palette of object, input, math, logic, list, text and geometry nodes added by click or drag. An object node owns drawing entities and its rows are the Properties panel's own rows for them: the single-object page is extracted from refresh_properties as entity_property_sections, values use the control protocol's property_json, and writes go through set_property_value with a property target override, so the panel, MCP and the graph share one read/write path. A list reaching an object row makes one entity per element. Each graph action is one undo step; the canvas pans and zooms. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
56c04408d6
commit
f537aff75c
430 files changed
+9925
-8540
No files matched your search
+150
-150
@@ -4,31 +4,31 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
use acadrust::entities::EntityType;
|
||||
use acadrust::types::{Handle, Vector3};
|
||||
use codec::entities::EntityType;
|
||||
use codec::types::{Handle, Vector3};
|
||||
|
||||
use cadkernel_constraints::constraints::angle_distance::L2LAngle;
|
||||
use cadkernel_constraints::constraints::bspline::{Coord as SplineCoord, PointOnBSpline};
|
||||
use cadkernel_constraints::constraints::circle_arc::{C2LDistance, P2CDistance, TangentCircumf};
|
||||
use cadkernel_constraints::constraints::conic::{
|
||||
use kernel_constraints::constraints::angle_distance::L2LAngle;
|
||||
use kernel_constraints::constraints::bspline::{Coord as SplineCoord, PointOnBSpline};
|
||||
use kernel_constraints::constraints::circle_arc::{C2LDistance, P2CDistance, TangentCircumf};
|
||||
use kernel_constraints::constraints::conic::{
|
||||
EqualMajorAxesConic, PointOnEllipse, TangentEllipseLine,
|
||||
};
|
||||
use cadkernel_constraints::constraints::curve_generic::{BoundedArcValue, CurveValue};
|
||||
use cadkernel_constraints::constraints::point_line::{
|
||||
use kernel_constraints::constraints::curve_generic::{BoundedArcValue, CurveValue};
|
||||
use kernel_constraints::constraints::point_line::{
|
||||
CenterOfGravity, Difference, Equal, EqualLineLength, MidpointOnLine, P2PDistance,
|
||||
Parallel as ParallelConstraint, Perpendicular as PerpendicularConstraint, PointOnLine,
|
||||
ProjectedDistance, ProjectedDistanceAlongLine, SymmetricLineDirections,
|
||||
};
|
||||
use cadkernel_constraints::constraints::Constraint;
|
||||
use cadkernel_constraints::geo::{
|
||||
use kernel_constraints::constraints::Constraint;
|
||||
use kernel_constraints::geo::{
|
||||
Arc as GArc, BSpline as GBSpline, Circle as GCircle, Conic as GConic, Ellipse as GEllipse,
|
||||
Line as GLine, Point as GPoint,
|
||||
};
|
||||
use cadkernel_constraints::solvers::dogleg::solve_dl;
|
||||
use cadkernel_constraints::solvers::lm::solve_lm;
|
||||
use cadkernel_constraints::solvers::SolveStatus;
|
||||
use cadkernel_constraints::system::System;
|
||||
use cadkernel_constraints::util::ParamId;
|
||||
use kernel_constraints::solvers::dogleg::solve_dl;
|
||||
use kernel_constraints::solvers::lm::solve_lm;
|
||||
use kernel_constraints::solvers::SolveStatus;
|
||||
use kernel_constraints::system::System;
|
||||
use kernel_constraints::util::ParamId;
|
||||
|
||||
use super::named_parameters::ParameterTable;
|
||||
use super::parametric_constraints::{
|
||||
@@ -37,7 +37,7 @@ use super::parametric_constraints::{
|
||||
};
|
||||
use super::{ChangeKind, Scene};
|
||||
|
||||
/// One referenced entity's geometry, registered into an `cadkernel_constraints::System`'s
|
||||
/// One referenced entity's geometry, registered into an `kernel_constraints::System`'s
|
||||
/// parameter store.
|
||||
#[derive(Clone)]
|
||||
enum EntityGeom {
|
||||
@@ -76,7 +76,7 @@ struct PolylineArc {
|
||||
}
|
||||
|
||||
impl EntityGeom {
|
||||
/// The `cadkernel_constraints::geo::Point` for a marker on this entity — `None` for
|
||||
/// The `kernel_constraints::geo::Point` for a marker on this entity — `None` for
|
||||
/// a marker this entity type/value doesn't support (see
|
||||
/// `parametric_constraints::resolve_point` for the same convention on the
|
||||
/// read side).
|
||||
@@ -188,7 +188,7 @@ fn as_circle_or_line(g: EntityGeom, reference: ParametricRef) -> CircleOrLine {
|
||||
/// they solve exactly one constraint in isolation, so they need that
|
||||
/// convention; a whole scope's constraint graph does not).
|
||||
fn register_entity(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
sys: &mut System,
|
||||
handle: Handle,
|
||||
) -> Option<EntityGeom> {
|
||||
@@ -256,7 +256,7 @@ fn register_entity_geom(
|
||||
return None;
|
||||
};
|
||||
let bulge = polyline.vertices[index].bulge;
|
||||
let shape = cadkernel::geom2d::BulgeArc::from_bulge(
|
||||
let shape = kernel::geom2d::BulgeArc::from_bulge(
|
||||
[source[index].x, source[index].y],
|
||||
[source[next].x, source[next].y],
|
||||
bulge,
|
||||
@@ -310,7 +310,7 @@ fn register_entity_geom(
|
||||
return None;
|
||||
};
|
||||
let bulge = polyline.vertices[index].bulge;
|
||||
let shape = cadkernel::geom2d::BulgeArc::from_bulge(
|
||||
let shape = kernel::geom2d::BulgeArc::from_bulge(
|
||||
[source[index].x, source[index].y],
|
||||
[source[next].x, source[next].y],
|
||||
bulge,
|
||||
@@ -388,7 +388,7 @@ fn register_entity_geom(
|
||||
}
|
||||
EntityType::Arc(a) => {
|
||||
// Full registration: center/radius, both angles, and real
|
||||
// start/end points seeded from acadrust's own `start_point`/
|
||||
// start/end points seeded from opencadcodec's own `start_point`/
|
||||
// `end_point` (already consistent with center/radius/angle at
|
||||
// registration time) — `solve_scope` adds the arc-rules
|
||||
// constraints that keep them that way under solving. See this
|
||||
@@ -422,8 +422,8 @@ fn register_entity_geom(
|
||||
}))
|
||||
}
|
||||
EntityType::Ellipse(el) => {
|
||||
// acadrust's `Ellipse` is center + major-axis vector (its length
|
||||
// is the major radius) + minor/major ratio; `cadkernel_constraints::geo::
|
||||
// opencadcodec's `Ellipse` is center + major-axis vector (its length
|
||||
// is the major radius) + minor/major ratio; `kernel_constraints::geo::
|
||||
// Ellipse` is center + one focus + minor radius. Converting:
|
||||
// minor_radius = major_radius * ratio, then the focus distance
|
||||
// c follows from a² = b² + c² (standard ellipse identity), and
|
||||
@@ -439,7 +439,7 @@ fn register_entity_geom(
|
||||
let unit_major = if major_radius > 1e-9 {
|
||||
el.major_axis.normalize()
|
||||
} else {
|
||||
acadrust::types::Vector3::UNIT_X
|
||||
codec::types::Vector3::UNIT_X
|
||||
};
|
||||
let focus1_point = el.center + unit_major * focus_dist;
|
||||
let center = GPoint::new(
|
||||
@@ -504,7 +504,7 @@ fn register_entity_geom(
|
||||
/// supported entity type, or (for a point ref) uses a marker that entity
|
||||
/// type doesn't support.
|
||||
fn resolve_ref(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
sys: &mut System,
|
||||
cache: &mut HashMap<Handle, EntityGeom>,
|
||||
r: ParametricRef,
|
||||
@@ -522,7 +522,7 @@ fn resolve_ref(
|
||||
/// midpoint markers are derived parameters so moving either parent geometry
|
||||
/// or another constrained object recomputes them in the same solve.
|
||||
fn resolve_constraint_point(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
sys: &mut System,
|
||||
cache: &mut HashMap<Handle, EntityGeom>,
|
||||
reference: ParametricRef,
|
||||
@@ -594,7 +594,7 @@ fn resolve_constraint_point(
|
||||
vec![segment.arc.start_angle, segment.arc.end_angle],
|
||||
vec![0.5, 0.5],
|
||||
)));
|
||||
let value = cadkernel_constraints::geo::Curve::value(
|
||||
let value = kernel_constraints::geo::Curve::value(
|
||||
&segment.arc,
|
||||
sys.store(),
|
||||
parameter_value,
|
||||
@@ -642,7 +642,7 @@ fn resolve_constraint_point(
|
||||
vec![0.5, 0.5],
|
||||
)));
|
||||
let point = {
|
||||
let value = cadkernel_constraints::geo::Curve::value(
|
||||
let value = kernel_constraints::geo::Curve::value(
|
||||
&arc,
|
||||
sys.store(),
|
||||
parameter_value,
|
||||
@@ -669,7 +669,7 @@ fn resolve_constraint_point(
|
||||
return None;
|
||||
}
|
||||
let parameter_value = (source.start_parameter + source.end_parameter) * 0.5;
|
||||
let value = cadkernel_constraints::geo::Curve::value(
|
||||
let value = kernel_constraints::geo::Curve::value(
|
||||
&ellipse,
|
||||
sys.store(),
|
||||
parameter_value,
|
||||
@@ -692,7 +692,7 @@ fn resolve_constraint_point(
|
||||
let from = curve.knots[curve.degree];
|
||||
let to = curve.knots[curve.poles.len()];
|
||||
let parameter_value = (from + to) * 0.5;
|
||||
let value = cadkernel_constraints::geo::Curve::value(
|
||||
let value = kernel_constraints::geo::Curve::value(
|
||||
&curve,
|
||||
sys.store(),
|
||||
parameter_value,
|
||||
@@ -721,7 +721,7 @@ fn resolve_constraint_point(
|
||||
|
||||
const PLANE_EPS: f64 = 1e-9;
|
||||
|
||||
fn is_world_z(normal: acadrust::types::Vector3) -> bool {
|
||||
fn is_world_z(normal: codec::types::Vector3) -> bool {
|
||||
normal.x.abs() <= PLANE_EPS
|
||||
&& normal.y.abs() <= PLANE_EPS
|
||||
&& (normal.z - 1.0).abs() <= PLANE_EPS
|
||||
@@ -802,7 +802,7 @@ fn entity_plane_z(entity: &EntityType) -> Option<f64> {
|
||||
z.is_finite().then_some(z)
|
||||
}
|
||||
|
||||
fn refs_share_supported_plane(document: &acadrust::CadDocument, refs: &[ParametricRef]) -> bool {
|
||||
fn refs_share_supported_plane(document: &codec::CadDocument, refs: &[ParametricRef]) -> bool {
|
||||
let mut plane_z = None;
|
||||
for reference in refs {
|
||||
let Some(entity) = document.get_entity(reference.entity) else {
|
||||
@@ -820,9 +820,9 @@ fn refs_share_supported_plane(document: &acadrust::CadDocument, refs: &[Parametr
|
||||
}
|
||||
|
||||
fn concentric_reference_geometry(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
reference: ParametricRef,
|
||||
) -> Option<(Vector3, cadkernel::space::Plane)> {
|
||||
) -> Option<(Vector3, kernel::space::Plane)> {
|
||||
let marker = reference.marker?;
|
||||
if marker != -3 && reference.segment_center_index().is_none() {
|
||||
return None;
|
||||
@@ -834,7 +834,7 @@ fn concentric_reference_geometry(
|
||||
}
|
||||
|
||||
fn concentric_refs_share_plane(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
refs: &[ParametricRef],
|
||||
) -> bool {
|
||||
let [first, second] = refs else {
|
||||
@@ -865,7 +865,7 @@ fn concentric_refs_share_plane(
|
||||
[first_center.x, first_center.y, first_center.z],
|
||||
[second_center.x, second_center.y, second_center.z],
|
||||
];
|
||||
let tolerance = cadkernel::space::coplanarity_tolerance(&points);
|
||||
let tolerance = kernel::space::coplanarity_tolerance(&points);
|
||||
parallel
|
||||
&& first_plane
|
||||
.distance_to(second_plane.origin)
|
||||
@@ -883,7 +883,7 @@ fn ref_is_driven(driven: &[ParametricRef], reference: ParametricRef) -> bool {
|
||||
}
|
||||
|
||||
fn apply_spatial_concentric_constraints(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
set: &ParametricConstraintSet,
|
||||
driven_refs: &[ParametricRef],
|
||||
initial_fixed_refs: &[ParametricRef],
|
||||
@@ -959,8 +959,8 @@ fn apply_spatial_concentric_constraints(
|
||||
}
|
||||
fixed.sort_unstable();
|
||||
fixed.dedup();
|
||||
let tolerance = cadkernel::space::coplanarity_tolerance(&points).max(MOVE_EPS);
|
||||
let Some(translations) = cadkernel::space::solve_rigid_point_coincidence(
|
||||
let tolerance = kernel::space::coplanarity_tolerance(&points).max(MOVE_EPS);
|
||||
let Some(translations) = kernel::space::solve_rigid_point_coincidence(
|
||||
handles.len(),
|
||||
&relations,
|
||||
&fixed,
|
||||
@@ -1016,7 +1016,7 @@ fn oriented_distance(target: f64, current_projection: f64) -> f64 {
|
||||
}
|
||||
|
||||
fn retained_tangent_side(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
retained_before: &HashMap<Handle, std::sync::Arc<EntityType>>,
|
||||
constraint: &ParametricConstraint,
|
||||
) -> Option<bool> {
|
||||
@@ -1039,9 +1039,9 @@ fn retained_tangent_side(
|
||||
.map(|index| curve.segments().into_iter().nth(index))
|
||||
.unwrap_or(Some(curve))
|
||||
};
|
||||
let circle_center = |curve: &cadkernel::geom2d::Curve| match curve {
|
||||
cadkernel::geom2d::Curve::Circle(circle) => Some(circle.centre),
|
||||
cadkernel::geom2d::Curve::Arc(arc) => Some(arc.centre),
|
||||
let circle_center = |curve: &kernel::geom2d::Curve| match curve {
|
||||
kernel::geom2d::Curve::Circle(circle) => Some(circle.centre),
|
||||
kernel::geom2d::Curve::Arc(arc) => Some(arc.centre),
|
||||
_ => None,
|
||||
};
|
||||
let (a, b) = (curve(*a)?, curve(*b)?);
|
||||
@@ -1073,7 +1073,7 @@ fn collapsed_by_solve(entity: &EntityType) -> bool {
|
||||
/// Ellipse likewise pins center + radmin, `focus1` being tied to `center`
|
||||
/// by the ellipse-rules `Difference` constraints.
|
||||
fn fixed_pin_params(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
sys: &mut System,
|
||||
cache: &mut HashMap<Handle, EntityGeom>,
|
||||
r: ParametricRef,
|
||||
@@ -1136,7 +1136,7 @@ fn fixed_pin_params(
|
||||
/// Builds the kernel equations for one constraint. Unsupported references or
|
||||
/// invalid dimensional targets produce no equations.
|
||||
fn build_constraint(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
sys: &mut System,
|
||||
cache: &mut HashMap<Handle, EntityGeom>,
|
||||
params: &ParameterTable,
|
||||
@@ -1874,7 +1874,7 @@ fn build_constraint(
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
// Smooth edits the endpoint controls through cadkernel's spatial
|
||||
// Smooth edits the endpoint controls through opencadkernel's spatial
|
||||
// NURBS operation after the ordinary 2D system has settled.
|
||||
ConstraintKind::Smooth => Vec::new(),
|
||||
ConstraintKind::RigidSet => {
|
||||
@@ -1957,25 +1957,25 @@ fn smooth_refs(refs: &[ParametricRef]) -> Option<(ParametricRef, ParametricRef,
|
||||
fn smooth_target_planar_curve(
|
||||
entity: &EntityType,
|
||||
curve_reference: ParametricRef,
|
||||
) -> Option<cadkernel::space::PlanarCurve> {
|
||||
) -> Option<kernel::space::PlanarCurve> {
|
||||
let planar = crate::entities::curve::entity_curve(entity)?;
|
||||
let Some(segment) = curve_reference.segment_index() else {
|
||||
return (!planar.is_closed()).then_some(planar);
|
||||
};
|
||||
let curve = planar.curve.segments().into_iter().nth(segment)?;
|
||||
Some(cadkernel::space::PlanarCurve::new(planar.plane, curve))
|
||||
Some(kernel::space::PlanarCurve::new(planar.plane, curve))
|
||||
}
|
||||
|
||||
fn smooth_endpoint_parameter(
|
||||
entity: &EntityType,
|
||||
endpoint_reference: ParametricRef,
|
||||
curve: &cadkernel::space::PlanarCurve,
|
||||
curve: &kernel::space::PlanarCurve,
|
||||
) -> Option<f64> {
|
||||
let marker = endpoint_reference.marker?;
|
||||
let endpoint = super::parametric_constraints::resolve_point(entity, marker)?;
|
||||
let endpoint = cadkernel::space::Vec3::new(endpoint.x, endpoint.y, endpoint.z);
|
||||
let start = cadkernel::space::Vec3::from(curve.point_at(0.0));
|
||||
let end = cadkernel::space::Vec3::from(curve.point_at(1.0));
|
||||
let endpoint = kernel::space::Vec3::new(endpoint.x, endpoint.y, endpoint.z);
|
||||
let start = kernel::space::Vec3::from(curve.point_at(0.0));
|
||||
let end = kernel::space::Vec3::from(curve.point_at(1.0));
|
||||
Some(if endpoint.distance(start) <= endpoint.distance(end) {
|
||||
0.0
|
||||
} else {
|
||||
@@ -1987,16 +1987,16 @@ fn smooth_target_jet(
|
||||
entity: &EntityType,
|
||||
endpoint_reference: ParametricRef,
|
||||
curve_reference: ParametricRef,
|
||||
) -> Option<cadkernel::space::CurveJet> {
|
||||
) -> Option<kernel::space::CurveJet> {
|
||||
if curve_reference.segment_index().is_none() {
|
||||
if let EntityType::Spline(spline) = entity {
|
||||
let endpoint = match endpoint_reference.marker {
|
||||
Some(0) => cadkernel::space::SplineEnd::Start,
|
||||
Some(1) => cadkernel::space::SplineEnd::End,
|
||||
Some(0) => kernel::space::SplineEnd::Start,
|
||||
Some(1) => kernel::space::SplineEnd::End,
|
||||
_ => return None,
|
||||
};
|
||||
let nurbs = crate::entities::spline::nurbs3(spline)?;
|
||||
return cadkernel::space::CurveJet::from_nurbs(&nurbs, endpoint);
|
||||
return kernel::space::CurveJet::from_nurbs(&nurbs, endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2006,10 +2006,10 @@ fn smooth_target_jet(
|
||||
let point = curve.point_at(parameter);
|
||||
let tangent = curve.tangent_at(parameter);
|
||||
match &curve.curve {
|
||||
cadkernel::geom2d::Curve::Line(_) => {
|
||||
cadkernel::space::CurveJet::linear(point, tangent)
|
||||
kernel::geom2d::Curve::Line(_) => {
|
||||
kernel::space::CurveJet::linear(point, tangent)
|
||||
}
|
||||
cadkernel::geom2d::Curve::Arc(arc) => cadkernel::space::CurveJet::circular(
|
||||
kernel::geom2d::Curve::Arc(arc) => kernel::space::CurveJet::circular(
|
||||
point,
|
||||
tangent,
|
||||
curve.plane.point_at(arc.centre),
|
||||
@@ -2018,32 +2018,32 @@ fn smooth_target_jet(
|
||||
}
|
||||
}
|
||||
|
||||
fn smooth_spline_plane(spline: &acadrust::entities::Spline) -> Option<cadkernel::space::Plane> {
|
||||
fn smooth_spline_plane(spline: &codec::entities::Spline) -> Option<kernel::space::Plane> {
|
||||
let source = if crate::entities::spline::uses_fit_method(spline) {
|
||||
&spline.fit_points
|
||||
} else {
|
||||
&spline.control_points
|
||||
};
|
||||
let origin = source.first()?;
|
||||
let origin_vector = cadkernel::space::Vec3::new(origin.x, origin.y, origin.z);
|
||||
let origin_vector = kernel::space::Vec3::new(origin.x, origin.y, origin.z);
|
||||
let along = source
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|point| cadkernel::space::Vec3::new(point.x, point.y, point.z) - origin_vector)
|
||||
.map(|point| kernel::space::Vec3::new(point.x, point.y, point.z) - origin_vector)
|
||||
.find(|vector| vector.length_squared() > 1.0e-24)?;
|
||||
let normal = source
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|point| cadkernel::space::Vec3::new(point.x, point.y, point.z) - origin_vector)
|
||||
.map(|point| kernel::space::Vec3::new(point.x, point.y, point.z) - origin_vector)
|
||||
.map(|vector| along.cross(vector))
|
||||
.find(|vector| vector.length_squared() > 1.0e-24)?;
|
||||
let plane = cadkernel::space::Plane::orthonormal(
|
||||
let plane = kernel::space::Plane::orthonormal(
|
||||
origin_vector.to_array(),
|
||||
along.to_array(),
|
||||
normal.to_array(),
|
||||
)?;
|
||||
let points: Vec<_> = source.iter().map(|point| [point.x, point.y, point.z]).collect();
|
||||
let tolerance = cadkernel::space::coplanarity_tolerance(&points);
|
||||
let tolerance = kernel::space::coplanarity_tolerance(&points);
|
||||
source
|
||||
.iter()
|
||||
.all(|point| plane.contains([point.x, point.y, point.z], tolerance))
|
||||
@@ -2053,7 +2053,7 @@ fn smooth_spline_plane(spline: &acadrust::entities::Spline) -> Option<cadkernel:
|
||||
fn smooth_entity_plane(
|
||||
entity: &EntityType,
|
||||
curve_reference: ParametricRef,
|
||||
) -> Option<cadkernel::space::Plane> {
|
||||
) -> Option<kernel::space::Plane> {
|
||||
if let EntityType::Spline(spline) = entity {
|
||||
return crate::entities::curve::entity_curve(entity)
|
||||
.map(|curve| curve.plane)
|
||||
@@ -2063,7 +2063,7 @@ fn smooth_entity_plane(
|
||||
}
|
||||
|
||||
fn smooth_refs_share_plane(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
source_ref: ParametricRef,
|
||||
target_curve_ref: ParametricRef,
|
||||
) -> bool {
|
||||
@@ -2081,7 +2081,7 @@ fn smooth_refs_share_plane(
|
||||
return false;
|
||||
};
|
||||
let points = [source_plane.origin, target_plane.origin];
|
||||
let tolerance = cadkernel::space::coplanarity_tolerance(&points);
|
||||
let tolerance = kernel::space::coplanarity_tolerance(&points);
|
||||
if let EntityType::Line(line) = target_entity {
|
||||
return source_plane
|
||||
.contains([line.start.x, line.start.y, line.start.z], tolerance)
|
||||
@@ -2093,8 +2093,8 @@ fn smooth_refs_share_plane(
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
cadkernel::space::Vec3::from(source_normal)
|
||||
.cross(cadkernel::space::Vec3::from(target_normal))
|
||||
kernel::space::Vec3::from(source_normal)
|
||||
.cross(kernel::space::Vec3::from(target_normal))
|
||||
.length()
|
||||
<= 1.0e-9
|
||||
&& source_plane.contains(target_plane.origin, tolerance)
|
||||
@@ -2102,7 +2102,7 @@ fn smooth_refs_share_plane(
|
||||
}
|
||||
|
||||
fn apply_smooth_constraints(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
set: &ParametricConstraintSet,
|
||||
results: &mut Vec<(Handle, EntityType)>,
|
||||
) {
|
||||
@@ -2130,8 +2130,8 @@ fn apply_smooth_constraints(
|
||||
continue;
|
||||
};
|
||||
let endpoint = match source_ref.marker {
|
||||
Some(0) => cadkernel::space::SplineEnd::Start,
|
||||
Some(1) => cadkernel::space::SplineEnd::End,
|
||||
Some(0) => kernel::space::SplineEnd::Start,
|
||||
Some(1) => kernel::space::SplineEnd::End,
|
||||
_ => continue,
|
||||
};
|
||||
let Some(target_jet) = smooth_target_jet(&target, target_ref, target_curve_ref) else {
|
||||
@@ -2140,7 +2140,7 @@ fn apply_smooth_constraints(
|
||||
let Some(curve) = crate::entities::spline::nurbs3(&spline) else {
|
||||
continue;
|
||||
};
|
||||
let Some(smoothed) = cadkernel::space::smooth_nurbs_endpoint(&curve, endpoint, target_jet)
|
||||
let Some(smoothed) = kernel::space::smooth_nurbs_endpoint(&curve, endpoint, target_jet)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
@@ -2163,7 +2163,7 @@ type SolveResult = (
|
||||
usize,
|
||||
Vec<(
|
||||
ConstraintId,
|
||||
cadkernel_constraints::diagnosis::RedundancyKind,
|
||||
kernel_constraints::diagnosis::RedundancyKind,
|
||||
)>,
|
||||
);
|
||||
|
||||
@@ -2236,7 +2236,7 @@ fn retain_segment_length(
|
||||
|
||||
/// Visit vertices and segments in stored drawing order, including the closing edge last.
|
||||
fn polyline_ref_order(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
reference: ParametricRef,
|
||||
) -> Option<(u64, usize)> {
|
||||
if !matches!(document.get_entity(reference.entity),
|
||||
@@ -2256,7 +2256,7 @@ fn polyline_ref_order(
|
||||
}
|
||||
|
||||
fn constraints_in_drawing_order<'a>(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
set: &'a ParametricConstraintSet,
|
||||
) -> Vec<&'a ParametricConstraint> {
|
||||
let mut constraints: Vec<_> = set.constraints.iter().collect();
|
||||
@@ -2316,7 +2316,7 @@ fn constrained_line_axes(constraints: &[&ParametricConstraint]) -> HashMap<Param
|
||||
/// Failed solves still return DOF/conflicts, but never write back geometry.
|
||||
/// Returns `None` when no supported geometry or smooth constraint can be built.
|
||||
fn solve_scope(
|
||||
document: &acadrust::CadDocument,
|
||||
document: &codec::CadDocument,
|
||||
drawing_params: &ParameterTable,
|
||||
set: &ParametricConstraintSet,
|
||||
driven_refs: &[ParametricRef],
|
||||
@@ -2944,7 +2944,7 @@ fn solve_scope(
|
||||
}
|
||||
|
||||
// Ellipse rules (same motivation as arc rules, different mechanism):
|
||||
// `cadkernel_constraints::geo::Ellipse` stores `focus1` as an absolute point, not an
|
||||
// `kernel_constraints::geo::Ellipse` stores `focus1` as an absolute point, not an
|
||||
// offset from `center`. If some constraint (e.g. Concentric) pulls only
|
||||
// on `center` and nothing references `focus1`/`radmin`, the solver
|
||||
// correctly leaves `focus1`'s *absolute* coordinates untouched — but
|
||||
@@ -3128,7 +3128,7 @@ fn solve_scope(
|
||||
// line's X after only a Horizontal constraint pins its Ys) is invisible
|
||||
// to `diagnose` entirely, undercounting DOF. Every such untouched free
|
||||
// param is unconstrained on its own, i.e. exactly 1 DOF each — added
|
||||
// back here rather than fixed in `cadkernel_constraints::diagnosis`, which correctly
|
||||
// back here rather than fixed in `kernel_constraints::diagnosis`, which correctly
|
||||
// has no opinion on params outside the `SubSystem` it was handed.
|
||||
let total_free: usize = cache
|
||||
.values()
|
||||
@@ -3158,10 +3158,10 @@ fn solve_scope(
|
||||
let mut dof = total_free.saturating_sub(touched_free);
|
||||
let mut conflicts: Vec<(
|
||||
ConstraintId,
|
||||
cadkernel_constraints::diagnosis::RedundancyKind,
|
||||
kernel_constraints::diagnosis::RedundancyKind,
|
||||
)> = Vec::new();
|
||||
for sub in &partitions {
|
||||
let diag = cadkernel_constraints::diagnosis::diagnose(sub, sys.store());
|
||||
let diag = kernel_constraints::diagnosis::diagnose(sub, sys.store());
|
||||
dof += diag.dof;
|
||||
if diag.redundant.is_empty() {
|
||||
continue;
|
||||
@@ -3179,7 +3179,7 @@ fn solve_scope(
|
||||
})
|
||||
.collect();
|
||||
for (row, kind) in
|
||||
cadkernel_constraints::diagnosis::classify_redundant(sub, sys.store(), &reportable)
|
||||
kernel_constraints::diagnosis::classify_redundant(sub, sys.store(), &reportable)
|
||||
{
|
||||
let row_constraint = &sub.constraints()[row];
|
||||
if let Some(&(_, id)) = owner.iter().find(|(rc, _)| Rc::ptr_eq(rc, row_constraint)) {
|
||||
@@ -3236,8 +3236,8 @@ fn solve_scope(
|
||||
let rotation = direction.y.atan2(direction.x);
|
||||
let aligned = matches!(
|
||||
text.horizontal_alignment,
|
||||
acadrust::entities::TextHorizontalAlignment::Aligned
|
||||
| acadrust::entities::TextHorizontalAlignment::Fit
|
||||
codec::entities::TextHorizontalAlignment::Aligned
|
||||
| codec::entities::TextHorizontalAlignment::Fit
|
||||
);
|
||||
let current_rotation = if aligned {
|
||||
text.alignment_point
|
||||
@@ -3451,7 +3451,7 @@ fn solve_scope(
|
||||
}
|
||||
(EntityType::Arc(a), EntityGeom::Arc(g)) => {
|
||||
// Center/radius/angles only — `start`/`end` are derived
|
||||
// (acadrust's `Arc` has no separate stored fields for them;
|
||||
// (opencadcodec's `Arc` has no separate stored fields for them;
|
||||
// `start_point()`/`end_point()` compute them from these
|
||||
// same four), so nothing further needs writing back for
|
||||
// them specifically.
|
||||
@@ -3478,10 +3478,10 @@ fn solve_scope(
|
||||
}
|
||||
}
|
||||
(EntityType::Ellipse(el), EntityGeom::Ellipse(g)) => {
|
||||
// Converting back to acadrust's center + major-axis-vector +
|
||||
// Converting back to opencadcodec's center + major-axis-vector +
|
||||
// minor/major-ratio parametrization — the inverse of
|
||||
// `register_entity`'s `Ellipse` arm. `rad_maj_at` (already
|
||||
// provided by `cadkernel_constraints::geo::Ellipse`) does the a²=b²+c²
|
||||
// provided by `kernel_constraints::geo::Ellipse`) does the a²=b²+c²
|
||||
// algebra; only the major-axis *direction* needs deriving
|
||||
// here, from the (possibly moved) focus relative to center.
|
||||
let (cx, cy) = (store.get(g.center.x), store.get(g.center.y));
|
||||
@@ -3493,7 +3493,7 @@ fn solve_scope(
|
||||
// circular — keep whatever direction it already had rather
|
||||
// than snapping to an arbitrary axis.
|
||||
let unit_major = if focus_dist > 1e-9 {
|
||||
acadrust::types::Vector3::new(fx - cx, fy - cy, 0.0).normalize()
|
||||
codec::types::Vector3::new(fx - cx, fy - cy, 0.0).normalize()
|
||||
} else {
|
||||
el.major_axis.normalize()
|
||||
};
|
||||
@@ -3604,8 +3604,8 @@ impl Scene {
|
||||
return Err("Smooth requires an open spline.");
|
||||
}
|
||||
let endpoint = match source_ref.marker {
|
||||
Some(0) => cadkernel::space::SplineEnd::Start,
|
||||
Some(1) => cadkernel::space::SplineEnd::End,
|
||||
Some(0) => kernel::space::SplineEnd::Start,
|
||||
Some(1) => kernel::space::SplineEnd::End,
|
||||
_ => return Err("Smooth requires a spline endpoint."),
|
||||
};
|
||||
let Some(_) = target_ref.marker else {
|
||||
@@ -3623,7 +3623,7 @@ impl Scene {
|
||||
let Some(curve) = crate::entities::spline::nurbs3(spline) else {
|
||||
return Err("The selected spline cannot be evaluated.");
|
||||
};
|
||||
if cadkernel::space::smooth_nurbs_endpoint(&curve, endpoint, target_jet).is_none() {
|
||||
if kernel::space::smooth_nurbs_endpoint(&curve, endpoint, target_jet).is_none() {
|
||||
return Err("The selected spline cannot satisfy curvature continuity.");
|
||||
}
|
||||
return Ok(());
|
||||
@@ -3941,23 +3941,23 @@ mod tests {
|
||||
ConstraintKind, ParametricConstraintSet, ParametricRef, ParametricScope,
|
||||
};
|
||||
use super::Scene;
|
||||
use acadrust::entities::EntityType;
|
||||
use acadrust::types::Vector3;
|
||||
use codec::entities::EntityType;
|
||||
use codec::types::Vector3;
|
||||
|
||||
fn spatial_circle(center: Vector3, radius: f64) -> acadrust::entities::Circle {
|
||||
fn spatial_circle(center: Vector3, radius: f64) -> codec::entities::Circle {
|
||||
let normal = Vector3::UNIT_Y;
|
||||
let (x, y, z) = crate::scene::view::transform::wcs_point_to_ocs(
|
||||
(center.x, center.y, center.z),
|
||||
(normal.x, normal.y, normal.z),
|
||||
);
|
||||
let mut circle = acadrust::entities::Circle::from_coords(x, y, z, radius);
|
||||
let mut circle = codec::entities::Circle::from_coords(x, y, z, radius);
|
||||
circle.normal = normal;
|
||||
circle
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn polyline_constraint_order_follows_stored_vertices_for_open_and_closed_polylines() {
|
||||
use acadrust::entities::{LwPolyline, LwVertex, Polyline2D, Vertex2D};
|
||||
use codec::entities::{LwPolyline, LwVertex, Polyline2D, Vertex2D};
|
||||
for closed in [false, true] {
|
||||
let mut scene = Scene::new();
|
||||
let points = [(8.0, 0.0), (4.0, 0.0), (4.0, 3.0), (0.0, 3.0)];
|
||||
@@ -3997,9 +3997,9 @@ mod tests {
|
||||
#[test]
|
||||
fn polyline_relations_follow_the_last_edge_without_swapping_reference_roles() {
|
||||
let mut scene = Scene::new();
|
||||
let mut polyline = acadrust::entities::LwPolyline::new();
|
||||
let mut polyline = codec::entities::LwPolyline::new();
|
||||
polyline.vertices = [(0.0, 0.0), (4.0, 0.0), (4.0, 3.0), (0.0, 3.0)]
|
||||
.into_iter().map(|(x, y)| acadrust::entities::LwVertex::from_coords(x, y)).collect();
|
||||
.into_iter().map(|(x, y)| codec::entities::LwVertex::from_coords(x, y)).collect();
|
||||
polyline.is_closed = true;
|
||||
let handle = scene.add_entity(EntityType::LwPolyline(polyline));
|
||||
let mut set = ParametricConstraintSet::new(ParametricScope::ModelSpace);
|
||||
@@ -4017,7 +4017,7 @@ mod tests {
|
||||
#[test]
|
||||
fn non_polyline_constraint_order_is_unchanged() {
|
||||
let mut scene = Scene::new();
|
||||
let line = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let line = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::ZERO, Vector3::new(4.0, 0.0, 0.0))));
|
||||
let mut set = ParametricConstraintSet::new(ParametricScope::ModelSpace);
|
||||
for marker in [1, 0] {
|
||||
@@ -4034,9 +4034,9 @@ mod tests {
|
||||
let mut results = Vec::new();
|
||||
for reverse in [false, true] {
|
||||
let mut scene = Scene::new();
|
||||
let mut polyline = acadrust::entities::LwPolyline::new();
|
||||
let mut polyline = codec::entities::LwPolyline::new();
|
||||
polyline.vertices = [(0.0, 0.0), (4.0, 0.0), (4.0, 3.0), (0.0, 3.0)]
|
||||
.into_iter().map(|(x, y)| acadrust::entities::LwVertex::from_coords(x, y)).collect();
|
||||
.into_iter().map(|(x, y)| codec::entities::LwVertex::from_coords(x, y)).collect();
|
||||
polyline.is_closed = closed;
|
||||
let handle = scene.add_entity(EntityType::LwPolyline(polyline));
|
||||
let mut constraints = vec![
|
||||
@@ -4053,13 +4053,13 @@ mod tests {
|
||||
for (kind, refs) in constraints { set.add(kind, refs, None); }
|
||||
let before = scene.document.get_entity(handle).unwrap().clone();
|
||||
let Some(EntityType::LwPolyline(polyline)) = scene.document.get_entity_mut(handle) else { panic!("polyline") };
|
||||
polyline.vertices[0].location = acadrust::types::Vector2::new(-1.0, -2.0);
|
||||
polyline.vertices[0].location = codec::types::Vector2::new(-1.0, -2.0);
|
||||
let solved = scene.solve_parametric_constraints_preview(
|
||||
&[handle], &[ParametricRef::point(handle, 0)], true, &[(handle, before)]);
|
||||
let entity = &solved.iter().find(|(h, _)| *h == handle).expect("connected vertices must move").1;
|
||||
let EntityType::LwPolyline(polyline) = entity else { panic!("polyline") };
|
||||
let points: Vec<_> = polyline.vertices.iter().map(|v| v.location).collect();
|
||||
assert_eq!(points[0], acadrust::types::Vector2::new(-1.0, -2.0));
|
||||
assert_eq!(points[0], codec::types::Vector2::new(-1.0, -2.0));
|
||||
assert!((points[0].y - points[1].y).abs() < 1e-7);
|
||||
assert!((points[1].x - points[2].x).abs() < 1e-7);
|
||||
assert!((points[2].y - points[3].y).abs() < 1e-7);
|
||||
@@ -4074,7 +4074,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn perpendicular_line_grips_distinguish_shared_corner_and_free_ends() {
|
||||
use acadrust::entities::Line;
|
||||
use codec::entities::Line;
|
||||
for (vertical, marker) in [(false, 0), (false, 1), (true, 1)] {
|
||||
let mut scene = Scene::new();
|
||||
let a = scene.add_entity(EntityType::Line(Line::from_points(
|
||||
@@ -4116,7 +4116,7 @@ mod tests {
|
||||
fn validation_rejects_unsupported_entity_shapes_and_planes() {
|
||||
let mut scene = Scene::new();
|
||||
let circle = scene.add_entity(EntityType::Circle(
|
||||
acadrust::entities::Circle::from_center_radius(Vector3::ZERO, 2.0),
|
||||
codec::entities::Circle::from_center_radius(Vector3::ZERO, 2.0),
|
||||
));
|
||||
assert!(scene
|
||||
.validate_parametric_constraint(
|
||||
@@ -4126,11 +4126,11 @@ mod tests {
|
||||
)
|
||||
.is_err());
|
||||
|
||||
let lower = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let lower = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(1.0, 0.0, 0.0),
|
||||
)));
|
||||
let upper = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let upper = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 1.0),
|
||||
Vector3::new(1.0, 0.0, 1.0),
|
||||
)));
|
||||
@@ -4146,7 +4146,7 @@ mod tests {
|
||||
#[test]
|
||||
fn validation_enforces_dimensional_value_domains() {
|
||||
let mut scene = Scene::new();
|
||||
let line = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let line = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(1.0, 0.0, 0.0),
|
||||
)));
|
||||
@@ -4161,7 +4161,7 @@ mod tests {
|
||||
Some(&DrivingValue::Literal(-1.0)),
|
||||
)
|
||||
.is_ok());
|
||||
let circle = scene.add_entity(EntityType::Circle(acadrust::entities::Circle::from_center_radius(
|
||||
let circle = scene.add_entity(EntityType::Circle(codec::entities::Circle::from_center_radius(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
1.0,
|
||||
)));
|
||||
@@ -4198,16 +4198,16 @@ mod tests {
|
||||
#[test]
|
||||
fn bulged_polyline_segment_registers_as_a_kernel_arc() {
|
||||
let mut scene = Scene::new();
|
||||
let mut polyline = acadrust::entities::LwPolyline::new();
|
||||
let mut polyline = codec::entities::LwPolyline::new();
|
||||
polyline.vertices = vec![
|
||||
acadrust::entities::LwVertex::with_bulge(
|
||||
acadrust::types::Vector2::new(0.0, 0.0),
|
||||
codec::entities::LwVertex::with_bulge(
|
||||
codec::types::Vector2::new(0.0, 0.0),
|
||||
1.0,
|
||||
),
|
||||
acadrust::entities::LwVertex::from_coords(10.0, 0.0),
|
||||
codec::entities::LwVertex::from_coords(10.0, 0.0),
|
||||
];
|
||||
let handle = scene.add_entity(EntityType::LwPolyline(polyline));
|
||||
let mut system = cadkernel_constraints::system::System::new();
|
||||
let mut system = kernel_constraints::system::System::new();
|
||||
let geometry = super::register_entity(&scene.document, &mut system, handle).unwrap();
|
||||
let segment = geometry.arc_segment(0).expect("expected an arc segment");
|
||||
|
||||
@@ -4218,11 +4218,11 @@ mod tests {
|
||||
#[test]
|
||||
fn ray_and_construction_line_constraints_solve_through_the_kernel() {
|
||||
let mut scene = Scene::new();
|
||||
let ray = scene.add_entity(EntityType::Ray(acadrust::entities::Ray::new(
|
||||
let ray = scene.add_entity(EntityType::Ray(codec::entities::Ray::new(
|
||||
Vector3::ZERO,
|
||||
Vector3::new(1.0, 1.0, 0.0),
|
||||
)));
|
||||
let xline = scene.add_entity(EntityType::XLine(acadrust::entities::XLine::new(
|
||||
let xline = scene.add_entity(EntityType::XLine(codec::entities::XLine::new(
|
||||
Vector3::new(5.0, 5.0, 0.0),
|
||||
Vector3::new(1.0, 1.0, 0.0),
|
||||
)));
|
||||
@@ -4261,11 +4261,11 @@ mod tests {
|
||||
#[test]
|
||||
fn one_edit_that_ripples_through_a_constraint_still_records_as_one_undo_step() {
|
||||
let mut scene = Scene::new();
|
||||
let a = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let a = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(10.0, 0.0, 0.0),
|
||||
)));
|
||||
let b = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let b = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 5.0, 0.0),
|
||||
Vector3::new(10.0, 5.0, 0.0),
|
||||
)));
|
||||
@@ -4309,11 +4309,11 @@ mod tests {
|
||||
#[test]
|
||||
fn erasing_a_constrained_entity_records_its_scope_for_undo() {
|
||||
let mut scene = Scene::new();
|
||||
let a = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let a = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(10.0, 0.0, 0.0),
|
||||
)));
|
||||
let b = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let b = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(10.0, 0.0, 0.0),
|
||||
Vector3::new(20.0, 5.0, 0.0),
|
||||
)));
|
||||
@@ -4387,16 +4387,16 @@ mod tests {
|
||||
#[test]
|
||||
fn preview_solve_preserves_parallel_spacing_through_tangent_radius() {
|
||||
let mut scene = Scene::new();
|
||||
let a = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let a = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(0.0, 10.0, 0.0),
|
||||
)));
|
||||
let b = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let b = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(2.0, 0.0, 0.0),
|
||||
Vector3::new(2.0, 10.0, 0.0),
|
||||
)));
|
||||
let circle = scene.add_entity(EntityType::Circle(
|
||||
acadrust::entities::Circle::from_center_radius(Vector3::new(1.0, 5.0, 0.0), 1.0),
|
||||
codec::entities::Circle::from_center_radius(Vector3::new(1.0, 5.0, 0.0), 1.0),
|
||||
));
|
||||
let mut set = ParametricConstraintSet::new(ParametricScope::ModelSpace);
|
||||
set.add(
|
||||
@@ -4468,11 +4468,11 @@ mod tests {
|
||||
#[test]
|
||||
fn rigid_set_preserves_relative_geometry_after_one_member_moves() {
|
||||
let mut scene = Scene::new();
|
||||
let a = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let a = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(10.0, 0.0, 0.0),
|
||||
)));
|
||||
let b = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let b = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 5.0, 0.0),
|
||||
Vector3::new(10.0, 5.0, 0.0),
|
||||
)));
|
||||
@@ -4517,11 +4517,11 @@ mod tests {
|
||||
#[test]
|
||||
fn implicit_midpoint_recomputes_with_its_parent_line() {
|
||||
let mut scene = Scene::new();
|
||||
let carrier = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let carrier = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(10.0, 0.0, 0.0),
|
||||
)));
|
||||
let anchor = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let anchor = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(7.0, 3.0, 0.0),
|
||||
Vector3::new(7.0, 8.0, 0.0),
|
||||
)));
|
||||
@@ -4553,7 +4553,7 @@ mod tests {
|
||||
fn spline_endpoint_participates_in_the_kernel_constraint_system() {
|
||||
let mut scene = Scene::new();
|
||||
let spline = scene.add_entity(EntityType::Spline(
|
||||
acadrust::entities::Spline::from_control_points(
|
||||
codec::entities::Spline::from_control_points(
|
||||
3,
|
||||
vec![
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
@@ -4563,7 +4563,7 @@ mod tests {
|
||||
],
|
||||
),
|
||||
));
|
||||
let anchor = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let anchor = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(9.0, 4.0, 0.0),
|
||||
Vector3::new(9.0, 7.0, 0.0),
|
||||
)));
|
||||
@@ -4594,11 +4594,11 @@ mod tests {
|
||||
#[test]
|
||||
fn smooth_constraint_recomputes_the_spline_after_its_target_moves() {
|
||||
let mut scene = Scene::new();
|
||||
let target = scene.add_entity(EntityType::Line(acadrust::entities::Line::from_points(
|
||||
let target = scene.add_entity(EntityType::Line(codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
Vector3::new(5.0, 0.0, 0.0),
|
||||
)));
|
||||
let mut spline = acadrust::entities::Spline::new();
|
||||
let mut spline = codec::entities::Spline::new();
|
||||
spline.degree = 3;
|
||||
spline.control_points = vec![
|
||||
Vector3::new(0.0, 0.0, 0.0),
|
||||
@@ -4606,7 +4606,7 @@ mod tests {
|
||||
Vector3::new(3.0, 2.0, 0.0),
|
||||
Vector3::new(5.0, 3.0, 0.0),
|
||||
];
|
||||
spline.knots = cadkernel::space::clamped_uniform_knots(3, 4);
|
||||
spline.knots = kernel::space::clamped_uniform_knots(3, 4);
|
||||
let spline = scene.add_entity(EntityType::Spline(spline));
|
||||
scene
|
||||
.parametric_constraint_set_mut(ParametricScope::ModelSpace)
|
||||
@@ -4630,27 +4630,27 @@ mod tests {
|
||||
};
|
||||
let curve = crate::entities::spline::nurbs3(spline).unwrap();
|
||||
let jet =
|
||||
cadkernel::space::CurveJet::from_nurbs(&curve, cadkernel::space::SplineEnd::Start)
|
||||
kernel::space::CurveJet::from_nurbs(&curve, kernel::space::SplineEnd::Start)
|
||||
.unwrap();
|
||||
assert!((jet.point[0] - 0.0).abs() < 1e-9);
|
||||
assert!((jet.point[1] - 1.0).abs() < 1e-9);
|
||||
assert!(jet.tangent[1].abs() < 1e-9, "jet={jet:?}");
|
||||
assert!(cadkernel::space::Vec3::from(jet.curvature).length() < 5e-3);
|
||||
assert!(kernel::space::Vec3::from(jet.curvature).length() < 5e-3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smooth_constraint_uses_the_selected_polyline_arc_curvature() {
|
||||
let mut scene = Scene::new();
|
||||
let mut target = acadrust::entities::LwPolyline::new();
|
||||
let mut target = codec::entities::LwPolyline::new();
|
||||
target.vertices = vec![
|
||||
acadrust::entities::LwVertex::with_bulge(
|
||||
acadrust::types::Vector2::new(0.0, 0.0),
|
||||
codec::entities::LwVertex::with_bulge(
|
||||
codec::types::Vector2::new(0.0, 0.0),
|
||||
1.0,
|
||||
),
|
||||
acadrust::entities::LwVertex::from_coords(10.0, 0.0),
|
||||
codec::entities::LwVertex::from_coords(10.0, 0.0),
|
||||
];
|
||||
let target = scene.add_entity(EntityType::LwPolyline(target));
|
||||
let mut spline = acadrust::entities::Spline::new();
|
||||
let mut spline = codec::entities::Spline::new();
|
||||
spline.degree = 3;
|
||||
spline.control_points = vec![
|
||||
Vector3::new(2.0, 1.0, 0.0),
|
||||
@@ -4658,7 +4658,7 @@ mod tests {
|
||||
Vector3::new(4.0, 3.0, 0.0),
|
||||
Vector3::new(5.0, 3.0, 0.0),
|
||||
];
|
||||
spline.knots = cadkernel::space::clamped_uniform_knots(3, 4);
|
||||
spline.knots = kernel::space::clamped_uniform_knots(3, 4);
|
||||
let spline = scene.add_entity(EntityType::Spline(spline));
|
||||
scene
|
||||
.parametric_constraint_set_mut(ParametricScope::ModelSpace)
|
||||
@@ -4679,12 +4679,12 @@ mod tests {
|
||||
};
|
||||
let curve = crate::entities::spline::nurbs3(spline).unwrap();
|
||||
let jet =
|
||||
cadkernel::space::CurveJet::from_nurbs(&curve, cadkernel::space::SplineEnd::Start)
|
||||
kernel::space::CurveJet::from_nurbs(&curve, kernel::space::SplineEnd::Start)
|
||||
.unwrap();
|
||||
assert!(cadkernel::space::Vec3::from(jet.point).length() < 1.0e-9);
|
||||
assert!(kernel::space::Vec3::from(jet.point).length() < 1.0e-9);
|
||||
assert!(jet.tangent[0].abs() < 1.0e-9, "jet={jet:?}");
|
||||
assert!(
|
||||
(cadkernel::space::Vec3::from(jet.curvature).length() - 0.2).abs() < 2.0e-4,
|
||||
(kernel::space::Vec3::from(jet.curvature).length() - 0.2).abs() < 2.0e-4,
|
||||
"jet={jet:?}"
|
||||
);
|
||||
}
|
||||
@@ -4693,12 +4693,12 @@ mod tests {
|
||||
fn smooth_constraint_accepts_a_stale_normal_on_an_arbitrary_plane() {
|
||||
let mut scene = Scene::new();
|
||||
let target = scene.add_entity(EntityType::Line(
|
||||
acadrust::entities::Line::from_points(
|
||||
codec::entities::Line::from_points(
|
||||
Vector3::new(0.0, 0.0, 1.0),
|
||||
Vector3::new(5.0, 0.0, 1.0),
|
||||
),
|
||||
));
|
||||
let mut source = acadrust::entities::Spline::new();
|
||||
let mut source = codec::entities::Spline::new();
|
||||
source.degree = 3;
|
||||
source.normal = Vector3::UNIT_Z;
|
||||
source.control_points = vec![
|
||||
@@ -4707,7 +4707,7 @@ mod tests {
|
||||
Vector3::new(4.0, 0.0, 2.0),
|
||||
Vector3::new(5.0, 0.0, 3.0),
|
||||
];
|
||||
source.knots = cadkernel::space::clamped_uniform_knots(3, 4);
|
||||
source.knots = kernel::space::clamped_uniform_knots(3, 4);
|
||||
let source = scene.add_entity(EntityType::Spline(source));
|
||||
let refs = vec![
|
||||
ParametricRef::point(source, 0),
|
||||
@@ -4727,10 +4727,10 @@ mod tests {
|
||||
};
|
||||
let curve = crate::entities::spline::nurbs3(source).unwrap();
|
||||
let jet =
|
||||
cadkernel::space::CurveJet::from_nurbs(&curve, cadkernel::space::SplineEnd::Start)
|
||||
kernel::space::CurveJet::from_nurbs(&curve, kernel::space::SplineEnd::Start)
|
||||
.unwrap();
|
||||
assert!(cadkernel::space::Vec3::from(jet.point)
|
||||
.distance(cadkernel::space::Vec3::new(0.0, 0.0, 1.0))
|
||||
assert!(kernel::space::Vec3::from(jet.point)
|
||||
.distance(kernel::space::Vec3::new(0.0, 0.0, 1.0))
|
||||
< 1.0e-9);
|
||||
assert!(jet.tangent[1].abs() < 1.0e-9 && jet.tangent[2].abs() < 1.0e-9);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user