forked from 1b-agent/opencadstudio-upstream
Merge updated pull request #1289 native segment persistence
This commit is contained in:
commit
c41d763984
1 file changed
+110
-32
@@ -536,18 +536,12 @@ impl<'a> GroupBuilder<'a> {
|
|||||||
}
|
}
|
||||||
let entity = self.document.get_entity(handle)?;
|
let entity = self.document.get_entity(handle)?;
|
||||||
let points = super::dimension_assoc::source_points(entity);
|
let points = super::dimension_assoc::source_points(entity);
|
||||||
let closed = match entity {
|
let (closed, bulge) = match entity {
|
||||||
EntityType::LwPolyline(polyline) => {
|
EntityType::LwPolyline(polyline) => {
|
||||||
if polyline.vertices.get(index)?.bulge.abs() > 1e-9 {
|
(polyline.is_closed, polyline.vertices.get(index)?.bulge)
|
||||||
return None;
|
|
||||||
}
|
|
||||||
polyline.is_closed
|
|
||||||
}
|
}
|
||||||
EntityType::Polyline2D(polyline) => {
|
EntityType::Polyline2D(polyline) => {
|
||||||
if polyline.vertices.get(index)?.bulge.abs() > 1e-9 {
|
(polyline.is_closed(), polyline.vertices.get(index)?.bulge)
|
||||||
return None;
|
|
||||||
}
|
|
||||||
polyline.is_closed()
|
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
@@ -560,19 +554,44 @@ impl<'a> GroupBuilder<'a> {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let node_id = self.alloc_node_id();
|
let node_id = self.alloc_node_id();
|
||||||
self.push_node(
|
if bulge.abs() <= 1e-9 {
|
||||||
node_id,
|
self.push_node(
|
||||||
"AcConstrainedBoundedLine",
|
node_id,
|
||||||
AssocConstraintNodeData::BoundedLine {
|
"AcConstrainedBoundedLine",
|
||||||
geometry_dependency: Handle::NULL,
|
AssocConstraintNodeData::BoundedLine {
|
||||||
geometry_node_id: node_id,
|
geometry_dependency: Handle::NULL,
|
||||||
point: start,
|
geometry_node_id: node_id,
|
||||||
direction: (end - start).normalize(),
|
point: start,
|
||||||
is_ray: false,
|
direction: (end - start).normalize(),
|
||||||
start_point: start,
|
is_ray: false,
|
||||||
end_point: end,
|
start_point: start,
|
||||||
},
|
end_point: end,
|
||||||
);
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let arc = cadkernel::geom2d::BulgeArc::from_bulge(
|
||||||
|
[start.x, start.y],
|
||||||
|
[end.x, end.y],
|
||||||
|
bulge,
|
||||||
|
)?;
|
||||||
|
self.push_node(
|
||||||
|
node_id,
|
||||||
|
"AcConstrainedArc",
|
||||||
|
AssocConstraintNodeData::Arc {
|
||||||
|
geometry_dependency: Handle::NULL,
|
||||||
|
geometry_node_id: node_id,
|
||||||
|
center: Vector3::new(arc.center[0], arc.center[1], start.z),
|
||||||
|
normal: Vector3::UNIT_Z,
|
||||||
|
direction: Vector3::UNIT_X,
|
||||||
|
radius: arc.radius,
|
||||||
|
start_parameter: arc.start_angle,
|
||||||
|
end_parameter: arc.start_angle + arc.sweep,
|
||||||
|
reserved: 0.0,
|
||||||
|
start_point: start,
|
||||||
|
end_point: end,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
self.entities
|
self.entities
|
||||||
.entry(handle)
|
.entry(handle)
|
||||||
.or_default()
|
.or_default()
|
||||||
@@ -1537,7 +1556,7 @@ fn dependency_entity(
|
|||||||
(Some(EntityType::Line(_)), AssocConstraintNodeData::BoundedLine { is_ray, .. }) => !is_ray,
|
(Some(EntityType::Line(_)), AssocConstraintNodeData::BoundedLine { is_ray, .. }) => !is_ray,
|
||||||
(
|
(
|
||||||
Some(EntityType::LwPolyline(_) | EntityType::Polyline2D(_)),
|
Some(EntityType::LwPolyline(_) | EntityType::Polyline2D(_)),
|
||||||
AssocConstraintNodeData::BoundedLine { .. },
|
AssocConstraintNodeData::BoundedLine { .. } | AssocConstraintNodeData::Arc { .. },
|
||||||
) => true,
|
) => true,
|
||||||
(Some(EntityType::Ray(_)), AssocConstraintNodeData::BoundedLine { is_ray, .. }) => *is_ray,
|
(Some(EntityType::Ray(_)), AssocConstraintNodeData::BoundedLine { is_ray, .. }) => *is_ray,
|
||||||
(Some(EntityType::XLine(_)), AssocConstraintNodeData::Line { .. }) => true,
|
(Some(EntityType::XLine(_)), AssocConstraintNodeData::Line { .. }) => true,
|
||||||
@@ -1580,13 +1599,18 @@ fn polyline_segment_reference(
|
|||||||
data: &AssocConstraintNodeData,
|
data: &AssocConstraintNodeData,
|
||||||
work_plane: &[Vector3; 3],
|
work_plane: &[Vector3; 3],
|
||||||
) -> Option<ParametricRef> {
|
) -> Option<ParametricRef> {
|
||||||
let AssocConstraintNodeData::BoundedLine {
|
let (start_point, end_point) = match data {
|
||||||
start_point,
|
AssocConstraintNodeData::BoundedLine {
|
||||||
end_point,
|
start_point,
|
||||||
..
|
end_point,
|
||||||
} = data
|
..
|
||||||
else {
|
}
|
||||||
return None;
|
| AssocConstraintNodeData::Arc {
|
||||||
|
start_point,
|
||||||
|
end_point,
|
||||||
|
..
|
||||||
|
} => (*start_point, *end_point),
|
||||||
|
_ => return None,
|
||||||
};
|
};
|
||||||
let [origin, axis_x, axis_y] = *work_plane;
|
let [origin, axis_x, axis_y] = *work_plane;
|
||||||
let normal = Vector3::new(
|
let normal = Vector3::new(
|
||||||
@@ -1595,8 +1619,8 @@ fn polyline_segment_reference(
|
|||||||
axis_x.x * axis_y.y - axis_x.y * axis_y.x,
|
axis_x.x * axis_y.y - axis_x.y * axis_y.x,
|
||||||
);
|
);
|
||||||
let to_world = |point: Vector3| origin + axis_x * point.x + axis_y * point.y + normal * point.z;
|
let to_world = |point: Vector3| origin + axis_x * point.x + axis_y * point.y + normal * point.z;
|
||||||
let start_point = to_world(*start_point);
|
let start_point = to_world(start_point);
|
||||||
let end_point = to_world(*end_point);
|
let end_point = to_world(end_point);
|
||||||
let entity_value = document.get_entity(entity)?;
|
let entity_value = document.get_entity(entity)?;
|
||||||
let closed = match entity_value {
|
let closed = match entity_value {
|
||||||
EntityType::LwPolyline(polyline) => polyline.is_closed,
|
EntityType::LwPolyline(polyline) => polyline.is_closed,
|
||||||
@@ -3292,6 +3316,60 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bulged_polyline_point_on_curve_round_trips_with_its_segment() {
|
||||||
|
for ext in ["dwg", "dxf"] {
|
||||||
|
let mut source = LwPolyline::new();
|
||||||
|
source.add_point(Vector2::new(0.0, 0.0));
|
||||||
|
source.add_point_with_bulge(Vector2::new(5.0, 0.0), 0.5);
|
||||||
|
source.add_point(Vector2::new(10.0, 5.0));
|
||||||
|
let mut scene = Scene::new();
|
||||||
|
let polyline = scene.add_entity(EntityType::LwPolyline(source));
|
||||||
|
let point = line_entity(&mut scene, (8.0, 2.0), (9.0, 2.0));
|
||||||
|
scene
|
||||||
|
.parametric_constraint_set_mut(ParametricScope::ModelSpace)
|
||||||
|
.add(
|
||||||
|
ConstraintKind::PointOnCurve,
|
||||||
|
vec![
|
||||||
|
ParametricRef::point(point, 0),
|
||||||
|
ParametricRef::segment(polyline, 1),
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
scene.sync_native_parametric_graph();
|
||||||
|
let group = native_group(
|
||||||
|
&scene.document,
|
||||||
|
scene.document.header.model_space_block_handle,
|
||||||
|
);
|
||||||
|
assert!(group
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.any(|node| node.class_name == "AcConstrainedArc"));
|
||||||
|
|
||||||
|
let bytes = crate::io::save_to_bytes(&scene.document, ext, scene.document.version)
|
||||||
|
.unwrap_or_else(|error| panic!("save {ext}: {error}"));
|
||||||
|
let mut restored = Scene::new();
|
||||||
|
restored.document = crate::io::load_bytes(&format!("bulged_segment.{ext}"), bytes)
|
||||||
|
.unwrap_or_else(|error| panic!("reload {ext}: {error}"));
|
||||||
|
restored.load_parametric_constraints_from_document();
|
||||||
|
|
||||||
|
let set = restored
|
||||||
|
.parametric_constraint_set(ParametricScope::ModelSpace)
|
||||||
|
.expect("native point-on-curve constraint should be imported");
|
||||||
|
assert_eq!(set.constraints.len(), 1, "{ext}");
|
||||||
|
assert_eq!(set.constraints[0].kind, ConstraintKind::PointOnCurve);
|
||||||
|
assert_eq!(
|
||||||
|
set.constraints[0].refs,
|
||||||
|
vec![
|
||||||
|
ParametricRef::point(point, 0),
|
||||||
|
ParametricRef::segment(polyline, 1),
|
||||||
|
],
|
||||||
|
"{ext}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn distance_with_named_parameter_scene() -> (Scene, Handle) {
|
fn distance_with_named_parameter_scene() -> (Scene, Handle) {
|
||||||
let mut scene = Scene::new();
|
let mut scene = Scene::new();
|
||||||
let a = line_entity(&mut scene, (0.0, 0.0), (10.0, 0.0));
|
let a = line_entity(&mut scene, (0.0, 0.0), (10.0, 0.0));
|
||||||
|
|||||||
Reference in new issue
Block a user