forked from 1b-agent/opencadstudio-upstream
Complete WEDGE creation and properties parity
This commit is contained in:
1 parent
3e45cff72f
commit
fea64a1e91
4 files changed
+181
-101
No files matched your search
@@ -441,14 +441,14 @@ impl OpenCADStudio {
|
||||
let display_entity = dispatch::entity_in_working_plane(contextual.as_ref(), plane);
|
||||
let entity = &display_entity;
|
||||
let group_names = self.tabs[i].scene.group_names_for_entity(handle);
|
||||
let box_primitive =
|
||||
crate::scene::model::solid_history::is_box_primitive(
|
||||
let rectangular_primitive =
|
||||
crate::scene::model::solid_history::is_rectangular_primitive(
|
||||
&self.tabs[i].scene.document,
|
||||
handle,
|
||||
);
|
||||
let mut sections =
|
||||
dispatch::properties_sectioned(handle, entity, &text_style_names);
|
||||
if box_primitive {
|
||||
if rectangular_primitive {
|
||||
sections.retain(|section| {
|
||||
!section.props.iter().any(|property| {
|
||||
property.field.starts_with("acis_")
|
||||
@@ -620,7 +620,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
if !box_primitive && matches!(
|
||||
if !rectangular_primitive && matches!(
|
||||
entity,
|
||||
acadrust::EntityType::Solid3D(_)
|
||||
| acadrust::EntityType::Region(_)
|
||||
@@ -694,7 +694,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
if !box_primitive {
|
||||
if !rectangular_primitive {
|
||||
sections.extend(crate::entities::object_data::sections(
|
||||
&self.tabs[i].scene.document,
|
||||
&self.tabs[i].scene.object_data_cache,
|
||||
@@ -2386,7 +2386,7 @@ impl OpenCADStudio {
|
||||
annotation_scale_handle,
|
||||
);
|
||||
let mut entity_grips = dispatch::grips(contextual.as_ref());
|
||||
if crate::scene::model::solid_history::is_box_primitive(
|
||||
if crate::scene::model::solid_history::is_rectangular_primitive(
|
||||
&self.tabs[i].scene.document,
|
||||
handle,
|
||||
) {
|
||||
|
||||
@@ -5,12 +5,15 @@ use acadrust::objects::SolidHistoryOperation;
|
||||
use acadrust::EntityType;
|
||||
use cadkernel::brep::Body;
|
||||
use glam::DVec3;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use crate::command::{CadCommand, CmdOption, CmdResult, WorkingPlane};
|
||||
use crate::scene::model::solid_model;
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use crate::t;
|
||||
|
||||
static LAST_WEDGE_HEIGHT: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
/// Which primitive a `PrimitiveCommand` builds.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Shape {
|
||||
@@ -63,7 +66,10 @@ impl Shape {
|
||||
/// True for footprints picked as a centre + radius (round shapes); false
|
||||
/// for corner-to-corner footprints (box/wedge).
|
||||
fn radial(self) -> bool {
|
||||
!matches!(self, Shape::Box | Shape::Wedge)
|
||||
!self.rectangular()
|
||||
}
|
||||
fn rectangular(self) -> bool {
|
||||
matches!(self, Shape::Box | Shape::Wedge)
|
||||
}
|
||||
/// Whether a height value is collected after the footprint.
|
||||
fn needs_height(self) -> bool {
|
||||
@@ -116,19 +122,33 @@ impl PrimitiveCommand {
|
||||
|
||||
/// A reasonable default height when the user just presses Enter.
|
||||
fn default_height(&self) -> f64 {
|
||||
match self.shape {
|
||||
Shape::Box | Shape::Wedge => {
|
||||
let d = self.pts[1] - self.pts[0];
|
||||
d.x.abs().max(d.y.abs())
|
||||
if self.shape == Shape::Wedge {
|
||||
let bits = LAST_WEDGE_HEIGHT.load(Ordering::Relaxed);
|
||||
if bits != 0 {
|
||||
let height = f64::from_bits(bits);
|
||||
if height.is_finite() && height >= 1e-6 {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
_ => (self.pts[1] - self.pts[0]).length(),
|
||||
}
|
||||
.max(1.0)
|
||||
let height = match self.shape {
|
||||
Shape::Box | Shape::Wedge => match (self.box_length, self.box_width) {
|
||||
(Some(length), Some(width)) => length.max(width),
|
||||
_ if self.pts.len() >= 2 => {
|
||||
let d = self.pts[1] - self.pts[0];
|
||||
d.x.abs().max(d.y.abs())
|
||||
}
|
||||
_ => 1.0,
|
||||
},
|
||||
_ if self.pts.len() >= 2 => (self.pts[1] - self.pts[0]).length(),
|
||||
_ => 1.0,
|
||||
};
|
||||
height.max(1.0)
|
||||
}
|
||||
|
||||
fn cursor_height(&self, point: DVec3) -> f64 {
|
||||
let height = self.plane.to_local(point).z - self.pts[0].z;
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
height
|
||||
} else {
|
||||
height.max(1e-6)
|
||||
@@ -268,19 +288,24 @@ impl PrimitiveCommand {
|
||||
true
|
||||
}
|
||||
|
||||
fn set_box_cube(&mut self, size: f64) -> Option<CmdResult> {
|
||||
fn set_box_cube(&mut self, size: f64, angle: f64) -> Option<CmdResult> {
|
||||
let size = size.abs();
|
||||
if !size.is_finite() || size < 1e-6 {
|
||||
if !size.is_finite() || !angle.is_finite() || size < 1e-6 {
|
||||
return None;
|
||||
}
|
||||
let (sin, cos) = angle.sin_cos();
|
||||
let x_axis = DVec3::new(cos, sin, 0.0);
|
||||
let y_axis = DVec3::new(-sin, cos, 0.0);
|
||||
let origin = if self.box_centered {
|
||||
self.pts[0] - DVec3::new(size * 0.5, size * 0.5, 0.0)
|
||||
self.pts[0] - x_axis * size * 0.5 - y_axis * size * 0.5
|
||||
} else {
|
||||
self.pts[0]
|
||||
};
|
||||
self.box_origin = Some(origin);
|
||||
self.box_length = Some(size);
|
||||
self.box_width = Some(size);
|
||||
self.box_angle = angle;
|
||||
self.box_width_sign = 1.0;
|
||||
Some(self.commit(size))
|
||||
}
|
||||
|
||||
@@ -319,48 +344,68 @@ impl PrimitiveCommand {
|
||||
true
|
||||
}
|
||||
|
||||
fn box_preview(&self, height: f64) -> Option<WireModel> {
|
||||
fn rectangular_preview(&self, height: f64) -> Option<WireModel> {
|
||||
let (origin, x_axis, y_axis, length, width, height) = self.box_spec(height)?;
|
||||
let base = [
|
||||
origin,
|
||||
origin + x_axis * length,
|
||||
origin + x_axis * length + y_axis * width,
|
||||
origin + y_axis * width,
|
||||
];
|
||||
let top = base.map(|point| point + DVec3::Z * height);
|
||||
let mut points = Vec::new();
|
||||
push_loop(&mut points, &base);
|
||||
push_loop(&mut points, &top);
|
||||
for index in 0..4 {
|
||||
push_segment(&mut points, base[index], top[index]);
|
||||
if self.shape == Shape::Wedge {
|
||||
let near = [
|
||||
origin,
|
||||
origin + x_axis * length,
|
||||
origin + DVec3::Z * height,
|
||||
];
|
||||
let far = near.map(|point| point + y_axis * width);
|
||||
push_loop(&mut points, &near);
|
||||
push_loop(&mut points, &far);
|
||||
for index in 0..3 {
|
||||
push_segment(&mut points, near[index], far[index]);
|
||||
}
|
||||
} else {
|
||||
let base = [
|
||||
origin,
|
||||
origin + x_axis * length,
|
||||
origin + x_axis * length + y_axis * width,
|
||||
origin + y_axis * width,
|
||||
];
|
||||
let top = base.map(|point| point + DVec3::Z * height);
|
||||
push_loop(&mut points, &base);
|
||||
push_loop(&mut points, &top);
|
||||
for index in 0..4 {
|
||||
push_segment(&mut points, base[index], top[index]);
|
||||
}
|
||||
}
|
||||
Some(self.place_preview(wire("primitive_height_preview", points)))
|
||||
}
|
||||
|
||||
fn build_wedge(&self, height: f64) -> Option<(Body, SolidHistoryOperation)> {
|
||||
use crate::scene::model::solid_history;
|
||||
|
||||
let (origin, x_axis, y_axis, length, width, height) = self.box_spec(height)?;
|
||||
let base = solid_model::wedge_solid([0.0; 3], length, width, height)?;
|
||||
let placed = solid_model::placed(
|
||||
&base,
|
||||
x_axis.to_array(),
|
||||
y_axis.to_array(),
|
||||
DVec3::Z.to_array(),
|
||||
origin.to_array(),
|
||||
)?;
|
||||
Some((
|
||||
placed,
|
||||
solid_history::wedge_op(
|
||||
self.history_transform_axes(origin, x_axis, y_axis),
|
||||
length,
|
||||
width,
|
||||
height,
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
/// Build the persistent kernel body and its history node.
|
||||
fn build(&self, height: f64) -> Option<(Body, SolidHistoryOperation)> {
|
||||
use crate::scene::model::solid_history;
|
||||
|
||||
let (solid, history) = match self.shape {
|
||||
Shape::Box => return self.build_box(height),
|
||||
Shape::Wedge => {
|
||||
let (a, b) = (self.pts[0], self.pts[1]);
|
||||
let length = (b.x - a.x).abs();
|
||||
let width = (b.y - a.y).abs();
|
||||
if length < 1e-6 || width < 1e-6 || height < 1e-6 {
|
||||
return None;
|
||||
}
|
||||
let origin = [a.x.min(b.x), a.y.min(b.y), a.z];
|
||||
(
|
||||
solid_model::wedge_solid(origin, length, width, height),
|
||||
solid_history::wedge_op(
|
||||
self.history_transform(DVec3::from_array(origin)),
|
||||
length,
|
||||
width,
|
||||
height,
|
||||
),
|
||||
)
|
||||
}
|
||||
Shape::Wedge => return self.build_wedge(height),
|
||||
Shape::Cylinder | Shape::Cone => {
|
||||
let c = self.pts[0];
|
||||
let r = (self.pts[1] - c).length();
|
||||
@@ -440,6 +485,9 @@ impl PrimitiveCommand {
|
||||
fn commit(&self, height: f64) -> CmdResult {
|
||||
match self.build(height) {
|
||||
Some((solid, history)) => {
|
||||
if self.shape == Shape::Wedge {
|
||||
LAST_WEDGE_HEIGHT.store(height.abs().to_bits(), Ordering::Relaxed);
|
||||
}
|
||||
// Place the local body on the working plane.
|
||||
let placed = solid_model::placed(
|
||||
&solid,
|
||||
@@ -482,7 +530,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn cursor_axis(&self) -> Option<(DVec3, DVec3)> {
|
||||
let constrained = if self.shape == Shape::Box {
|
||||
let constrained = if self.shape.rectangular() {
|
||||
self.box_step == BoxStep::Height
|
||||
} else {
|
||||
self.height_step
|
||||
@@ -501,7 +549,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
let n = self.shape.name();
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
return match self.box_step {
|
||||
BoxStep::FirstCorner => t!("%{n} Specify first corner or [Center]:", n = n),
|
||||
BoxStep::CenterPoint => t!("%{n} Specify center point:", n = n),
|
||||
@@ -511,7 +559,11 @@ impl CadCommand for PrimitiveCommand {
|
||||
BoxStep::CubeSize => t!("%{n} Specify cube length:", n = n),
|
||||
BoxStep::Length => t!("%{n} Specify length:", n = n),
|
||||
BoxStep::Width => t!("%{n} Specify width:", n = n),
|
||||
BoxStep::Height => t!("%{n} Specify height or [2Point]:", n = n),
|
||||
BoxStep::Height => t!(
|
||||
"%{n} Specify height or [2Point] <%{height}>:",
|
||||
n = n,
|
||||
height = format!("{:.4}", self.default_height())
|
||||
),
|
||||
BoxStep::HeightFirstPoint => {
|
||||
t!("%{n} Specify first point for height:", n = n)
|
||||
}
|
||||
@@ -540,7 +592,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn options(&self) -> Vec<CmdOption> {
|
||||
if self.shape != Shape::Box {
|
||||
if !self.shape.rectangular() {
|
||||
return Vec::new();
|
||||
}
|
||||
match self.box_step {
|
||||
@@ -555,7 +607,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
let local = self.plane.to_local(pt);
|
||||
if !local.is_finite() {
|
||||
return CmdResult::NeedPoint;
|
||||
@@ -567,12 +619,23 @@ impl CadCommand for PrimitiveCommand {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
BoxStep::OppositeCorner => {
|
||||
self.set_box_corner_footprint(local);
|
||||
CmdResult::NeedPoint
|
||||
let height = local.z - self.pts[0].z;
|
||||
if !self.set_box_corner_footprint(local) {
|
||||
CmdResult::NeedPoint
|
||||
} else if height.abs() >= 1e-6 {
|
||||
self.commit(height)
|
||||
} else {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
}
|
||||
BoxStep::CubeSize => {
|
||||
let delta = local - self.pts[0];
|
||||
self.set_box_cube(
|
||||
delta.x.hypot(delta.y),
|
||||
delta.y.atan2(delta.x),
|
||||
)
|
||||
.unwrap_or(CmdResult::NeedPoint)
|
||||
}
|
||||
BoxStep::CubeSize => self
|
||||
.set_box_cube((local - self.pts[0]).length())
|
||||
.unwrap_or(CmdResult::NeedPoint),
|
||||
BoxStep::Length => {
|
||||
let delta = local - self.pts[0];
|
||||
if !self.set_box_length(delta.x.hypot(delta.y), delta.y.atan2(delta.x)) {
|
||||
@@ -632,8 +695,12 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
if self.shape == Shape::Box {
|
||||
return CmdResult::Cancel;
|
||||
if self.shape.rectangular() {
|
||||
return if self.box_step == BoxStep::Height {
|
||||
self.commit(self.default_height())
|
||||
} else {
|
||||
CmdResult::Cancel
|
||||
};
|
||||
}
|
||||
if self.height_step {
|
||||
let h = self.default_height();
|
||||
@@ -647,7 +714,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn wants_text_input(&self) -> bool {
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
matches!(
|
||||
self.box_step,
|
||||
BoxStep::FirstCorner
|
||||
@@ -663,7 +730,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn point_step_accepts_keywords(&self) -> bool {
|
||||
self.shape == Shape::Box
|
||||
self.shape.rectangular()
|
||||
&& matches!(
|
||||
self.box_step,
|
||||
BoxStep::FirstCorner | BoxStep::OppositeCorner | BoxStep::Height
|
||||
@@ -671,7 +738,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, raw: &str) -> Option<CmdResult> {
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
let token = raw.trim();
|
||||
let upper = token.to_uppercase();
|
||||
return match self.box_step {
|
||||
@@ -693,7 +760,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
BoxStep::CubeSize => crate::entities::common::parse_typed_length(token)
|
||||
.and_then(|value| self.set_box_cube(value)),
|
||||
.and_then(|value| self.set_box_cube(value, 0.0)),
|
||||
BoxStep::Length => {
|
||||
let value = crate::entities::common::parse_typed_length(token)?;
|
||||
self.set_box_length(value, 0.0)
|
||||
@@ -722,7 +789,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
if self.pts.is_empty() {
|
||||
return None;
|
||||
}
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
let local = self.plane.to_local(pt);
|
||||
if !local.is_finite() {
|
||||
return None;
|
||||
@@ -750,18 +817,25 @@ impl CadCommand for PrimitiveCommand {
|
||||
Some(self.place_preview(footprint_wire(Shape::Box, &points)))
|
||||
}
|
||||
BoxStep::CubeSize => {
|
||||
let size = (local - self.pts[0]).length().max(1e-6);
|
||||
let mut preview = PrimitiveCommand::new("BOX");
|
||||
let delta = local - self.pts[0];
|
||||
let size = delta.x.hypot(delta.y).max(1e-6);
|
||||
let mut preview = PrimitiveCommand::new(self.shape.name());
|
||||
preview.plane = self.plane;
|
||||
preview.pts = self.pts.clone();
|
||||
preview.box_origin = Some(if self.box_centered {
|
||||
self.pts[0] - DVec3::new(size * 0.5, size * 0.5, 0.0)
|
||||
} else {
|
||||
self.pts[0]
|
||||
});
|
||||
preview.box_origin = Some(self.pts[0]);
|
||||
preview.box_length = Some(size);
|
||||
preview.box_width = Some(size);
|
||||
preview.box_preview(size)
|
||||
preview.box_angle = delta.y.atan2(delta.x);
|
||||
preview.box_width_sign = 1.0;
|
||||
if self.box_centered {
|
||||
let (sin, cos) = preview.box_angle.sin_cos();
|
||||
let x_axis = DVec3::new(cos, sin, 0.0);
|
||||
let y_axis = DVec3::new(-sin, cos, 0.0);
|
||||
preview.box_origin = Some(
|
||||
self.pts[0] - x_axis * size * 0.5 - y_axis * size * 0.5,
|
||||
);
|
||||
}
|
||||
preview.rectangular_preview(size)
|
||||
}
|
||||
BoxStep::Length => Some(self.place_preview(wire(
|
||||
"primitive_preview",
|
||||
@@ -771,7 +845,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
let delta = local - self.pts[0];
|
||||
let normal = DVec3::new(-self.box_angle.sin(), self.box_angle.cos(), 0.0);
|
||||
let signed = delta.dot(normal);
|
||||
let mut preview = PrimitiveCommand::new("BOX");
|
||||
let mut preview = PrimitiveCommand::new(self.shape.name());
|
||||
preview.plane = self.plane;
|
||||
preview.pts = self.pts.clone();
|
||||
preview.box_origin = self.box_origin;
|
||||
@@ -779,9 +853,9 @@ impl CadCommand for PrimitiveCommand {
|
||||
preview.box_width = Some(signed.abs().max(1e-6));
|
||||
preview.box_angle = self.box_angle;
|
||||
preview.box_width_sign = if signed < 0.0 { -1.0 } else { 1.0 };
|
||||
preview.box_preview(1e-6)
|
||||
preview.rectangular_preview(1e-6)
|
||||
}
|
||||
BoxStep::Height => self.box_preview(self.cursor_height(pt)),
|
||||
BoxStep::Height => self.rectangular_preview(self.cursor_height(pt)),
|
||||
BoxStep::HeightSecondPoint => self.box_height_anchor.map(|first| {
|
||||
self.place_preview(wire(
|
||||
"primitive_preview",
|
||||
@@ -806,7 +880,7 @@ impl CadCommand for PrimitiveCommand {
|
||||
fn dyn_spec(&self) -> Option<crate::command::DynSpec> {
|
||||
use crate::command::{DynAnchor, DynFieldSpec, DynGuide, DynRole, DynSpec};
|
||||
|
||||
let role = if self.shape == Shape::Box {
|
||||
let role = if self.shape.rectangular() {
|
||||
match self.box_step {
|
||||
BoxStep::CubeSize | BoxStep::Length => DynRole::Distance,
|
||||
BoxStep::Width => DynRole::Width,
|
||||
@@ -827,13 +901,16 @@ impl CadCommand for PrimitiveCommand {
|
||||
}
|
||||
|
||||
fn dyn_live_value(&self, cursor: DVec3) -> Option<f64> {
|
||||
if self.shape == Shape::Box {
|
||||
if self.shape.rectangular() {
|
||||
let local = self.plane.to_local(cursor);
|
||||
if !local.is_finite() {
|
||||
return None;
|
||||
}
|
||||
return match self.box_step {
|
||||
BoxStep::CubeSize | BoxStep::Length => Some((local - self.pts[0]).length()),
|
||||
BoxStep::CubeSize | BoxStep::Length => {
|
||||
let delta = local - self.pts[0];
|
||||
Some(delta.x.hypot(delta.y))
|
||||
}
|
||||
BoxStep::Width => {
|
||||
let normal = DVec3::new(-self.box_angle.sin(), self.box_angle.cos(), 0.0);
|
||||
Some((local - self.pts[0]).dot(normal).abs())
|
||||
|
||||
@@ -63,19 +63,19 @@ fn history_flags(
|
||||
Some((history.record_history, history.show_history))
|
||||
}
|
||||
|
||||
pub fn is_box_primitive(
|
||||
pub fn is_rectangular_primitive(
|
||||
document: &acadrust::CadDocument,
|
||||
handle: acadrust::Handle,
|
||||
) -> bool {
|
||||
matches!(
|
||||
document.solid_history_operation(handle),
|
||||
Some(SolidHistoryOperation::Box(_))
|
||||
Some(SolidHistoryOperation::Box(_) | SolidHistoryOperation::Wedge(_))
|
||||
)
|
||||
}
|
||||
|
||||
pub fn reference_point(operation: &SolidHistoryOperation) -> Option<glam::DVec3> {
|
||||
match operation {
|
||||
SolidHistoryOperation::Box(value) => world_point(
|
||||
SolidHistoryOperation::Box(value) | SolidHistoryOperation::Wedge(value) => world_point(
|
||||
value.base.transform,
|
||||
[value.length * 0.5, value.width * 0.5, 0.0],
|
||||
),
|
||||
@@ -83,10 +83,11 @@ pub fn reference_point(operation: &SolidHistoryOperation) -> Option<glam::DVec3>
|
||||
}
|
||||
}
|
||||
|
||||
fn box_properties(
|
||||
fn rectangular_properties(
|
||||
document: &acadrust::CadDocument,
|
||||
handle: acadrust::Handle,
|
||||
value: &SolidHistoryBox,
|
||||
solid_type: &str,
|
||||
) -> Vec<PropSection> {
|
||||
let Some(position) = world_point(
|
||||
value.base.transform,
|
||||
@@ -106,7 +107,7 @@ fn box_properties(
|
||||
Property {
|
||||
label: t!("Solid type").into_owned(),
|
||||
field: "solid_history_type",
|
||||
value: PropValue::ReadOnly(t!("Box").into_owned()),
|
||||
value: PropValue::ReadOnly(t!(solid_type).into_owned()),
|
||||
},
|
||||
crate::entities::common::edit_prop(
|
||||
t!("Position X").as_ref(),
|
||||
@@ -183,12 +184,12 @@ pub fn primitive_properties(
|
||||
return Vec::new();
|
||||
};
|
||||
let props = match operation {
|
||||
SolidHistoryOperation::Box(value) => return box_properties(document, handle, value),
|
||||
SolidHistoryOperation::Wedge(value) => vec![
|
||||
history_prop(t!("Length").as_ref(), PROP_LENGTH, value.length),
|
||||
history_prop(t!("Width").as_ref(), PROP_WIDTH, value.width),
|
||||
history_prop(t!("Height").as_ref(), PROP_HEIGHT, value.height),
|
||||
],
|
||||
SolidHistoryOperation::Box(value) => {
|
||||
return rectangular_properties(document, handle, value, "Box")
|
||||
}
|
||||
SolidHistoryOperation::Wedge(value) => {
|
||||
return rectangular_properties(document, handle, value, "Wedge")
|
||||
}
|
||||
SolidHistoryOperation::Cylinder(value) | SolidHistoryOperation::Cone(value) => vec![
|
||||
history_prop(t!("Radius").as_ref(), PROP_RADIUS, value.major_radius),
|
||||
history_prop(t!("Height").as_ref(), PROP_HEIGHT, value.height),
|
||||
@@ -287,7 +288,7 @@ pub fn apply_history_choice(
|
||||
before != (history.record_history, history.show_history)
|
||||
}
|
||||
|
||||
fn apply_box_geometry_property(
|
||||
fn apply_rectangular_geometry_property(
|
||||
value: &mut SolidHistoryBox,
|
||||
field: &str,
|
||||
text: &str,
|
||||
@@ -360,8 +361,12 @@ pub fn apply_primitive_property(
|
||||
field: &str,
|
||||
value: &str,
|
||||
) -> bool {
|
||||
if let SolidHistoryOperation::Box(box_value) = operation {
|
||||
if let Some(applied) = apply_box_geometry_property(box_value, field, value) {
|
||||
if let SolidHistoryOperation::Box(rectangular_value)
|
||||
| SolidHistoryOperation::Wedge(rectangular_value) = operation
|
||||
{
|
||||
if let Some(applied) =
|
||||
apply_rectangular_geometry_property(rectangular_value, field, value)
|
||||
{
|
||||
return applied;
|
||||
}
|
||||
}
|
||||
@@ -376,7 +381,7 @@ pub fn apply_primitive_property(
|
||||
return false;
|
||||
}
|
||||
let positive = || (number > 0.0).then_some(number);
|
||||
if let SolidHistoryOperation::Box(value) = operation {
|
||||
if let SolidHistoryOperation::Box(value) | SolidHistoryOperation::Wedge(value) = operation {
|
||||
let Some(next) = positive() else {
|
||||
return false;
|
||||
};
|
||||
@@ -411,12 +416,6 @@ pub fn apply_primitive_property(
|
||||
return true;
|
||||
}
|
||||
match operation {
|
||||
SolidHistoryOperation::Wedge(value) => match field {
|
||||
PROP_LENGTH => value.length = positive().unwrap_or(value.length),
|
||||
PROP_WIDTH => value.width = positive().unwrap_or(value.width),
|
||||
PROP_HEIGHT => value.height = positive().unwrap_or(value.height),
|
||||
_ => return false,
|
||||
},
|
||||
SolidHistoryOperation::Cylinder(value) | SolidHistoryOperation::Cone(value) => match field {
|
||||
PROP_RADIUS => {
|
||||
let Some(radius) = positive() else {
|
||||
|
||||
+6
-2
@@ -791,7 +791,11 @@ impl Scene {
|
||||
handle: Handle,
|
||||
operation: acadrust::objects::SolidHistoryOperation,
|
||||
) -> bool {
|
||||
let box_primitive = matches!(operation, acadrust::objects::SolidHistoryOperation::Box(_));
|
||||
let rectangular_primitive = matches!(
|
||||
operation,
|
||||
acadrust::objects::SolidHistoryOperation::Box(_)
|
||||
| acadrust::objects::SolidHistoryOperation::Wedge(_)
|
||||
);
|
||||
let Some(graph) = self.document.create_solid_history(handle, operation) else {
|
||||
return false;
|
||||
};
|
||||
@@ -799,7 +803,7 @@ impl Scene {
|
||||
for node in graph.nodes {
|
||||
self.record_undo_object_before(node, None);
|
||||
}
|
||||
if box_primitive {
|
||||
if rectangular_primitive {
|
||||
let _ = crate::scene::model::solid_history::apply_history_choice(
|
||||
&mut self.document,
|
||||
handle,
|
||||
|
||||
Reference in new issue
Block a user