forked from 1b-agent/opencadstudio-upstream
style: apply cargo fmt across workspace
This commit is contained in:
1 parent
85710e5454
commit
9cf9ff2c5c
531 files changed
+57740
-33906
No files matched your search
+183
-137
@@ -1,14 +1,12 @@
|
||||
// Kernel B-rep solid modelling and exact ACIS persistence.
|
||||
|
||||
use codec::{
|
||||
entities::{
|
||||
AcisData, EntityCommon, Region, Solid3D, Surface, SurfaceData, SurfaceKind, Wire,
|
||||
},
|
||||
entities::{AcisData, EntityCommon, Region, Solid3D, Surface, SurfaceData, SurfaceKind, Wire},
|
||||
objects::{SolidHistoryBoolean, SolidHistoryOperation},
|
||||
EntityType, Handle,
|
||||
};
|
||||
use kernel::brep::{Body, EdgeKey, FaceKey};
|
||||
use iced::Task;
|
||||
use kernel::brep::{Body, EdgeKey, FaceKey};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use super::Message;
|
||||
@@ -149,15 +147,10 @@ fn inherited_common(source: &EntityCommon) -> EntityCommon {
|
||||
result
|
||||
}
|
||||
|
||||
fn union_bodies(
|
||||
kind: UnionEntityKind,
|
||||
bodies: Vec<Body>,
|
||||
) -> Result<Body, kernel::brep::Snag> {
|
||||
fn union_bodies(kind: UnionEntityKind, bodies: Vec<Body>) -> Result<Body, kernel::brep::Snag> {
|
||||
if kind == UnionEntityKind::Solid {
|
||||
let mut operands = bodies.into_iter();
|
||||
let mut result = operands
|
||||
.next()
|
||||
.ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
let mut result = operands.next().ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
for operand in operands {
|
||||
result = solid_model::boolean_result(Bool::Union, &result, &operand)?;
|
||||
}
|
||||
@@ -222,9 +215,7 @@ fn subtract_bodies(
|
||||
}
|
||||
|
||||
let mut bases = bases.into_iter();
|
||||
let mut result = bases
|
||||
.next()
|
||||
.ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
let mut result = bases.next().ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
for base in bases {
|
||||
result = solid_model::boolean_result(Bool::Union, &result, &base)?;
|
||||
}
|
||||
@@ -308,9 +299,7 @@ fn intersect_bodies(
|
||||
) -> Result<IntersectBodyOutcome, kernel::brep::Snag> {
|
||||
if kind == UnionEntityKind::Solid {
|
||||
let mut operands = bodies.into_iter();
|
||||
let mut result = operands
|
||||
.next()
|
||||
.ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
let mut result = operands.next().ok_or(kernel::brep::Snag::CutRefused)?;
|
||||
for operand in operands {
|
||||
result = solid_model::boolean_result(Bool::Intersect, &result, &operand)?;
|
||||
if result.faces.is_empty() {
|
||||
@@ -322,11 +311,13 @@ fn intersect_bodies(
|
||||
|
||||
let references = bodies.iter().collect::<Vec<_>>();
|
||||
let tolerance = kernel::brep::operation_tolerance(&references);
|
||||
Ok(match kernel::brep::intersect_planar_regions(&bodies, tolerance)? {
|
||||
kernel::brep::PlanarIntersection::Area(body) => IntersectBodyOutcome::Area(body),
|
||||
kernel::brep::PlanarIntersection::Touching => IntersectBodyOutcome::Touching,
|
||||
kernel::brep::PlanarIntersection::Disjoint => IntersectBodyOutcome::Disjoint,
|
||||
})
|
||||
Ok(
|
||||
match kernel::brep::intersect_planar_regions(&bodies, tolerance)? {
|
||||
kernel::brep::PlanarIntersection::Area(body) => IntersectBodyOutcome::Area(body),
|
||||
kernel::brep::PlanarIntersection::Touching => IntersectBodyOutcome::Touching,
|
||||
kernel::brep::PlanarIntersection::Disjoint => IntersectBodyOutcome::Disjoint,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
impl super::OpenCADStudio {
|
||||
@@ -364,8 +355,7 @@ impl super::OpenCADStudio {
|
||||
inner.common.plotstyle_flags = 2;
|
||||
}
|
||||
inner.wires = solid_model::edge_wires(&solid);
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&solid)
|
||||
else {
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&solid) else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("The solid could not be encoded as ACIS.").as_ref());
|
||||
return Handle::NULL;
|
||||
@@ -382,7 +372,13 @@ impl super::OpenCADStudio {
|
||||
let require_complete = matches!(history, SolidHistoryOperation::Loft(_));
|
||||
self.tabs[i].scene.create_solid_history(handle, history);
|
||||
if !self.tabs[i].scene.register_solid_model(handle, solid)
|
||||
|| (require_complete && self.tabs[i].scene.meshes.get(&handle).is_none_or(|mesh| !mesh.complete)) {
|
||||
|| (require_complete
|
||||
&& self.tabs[i]
|
||||
.scene
|
||||
.meshes
|
||||
.get(&handle)
|
||||
.is_none_or(|mesh| !mesh.complete))
|
||||
{
|
||||
// A command result is not successful until it has renderable
|
||||
// geometry. Roll the new entity back so DELOBJ cannot consume a
|
||||
// visible source in exchange for an invisible result.
|
||||
@@ -394,11 +390,7 @@ impl super::OpenCADStudio {
|
||||
|
||||
/// Add an open sheet body as a persistent Surface entity and register its
|
||||
/// exact B-rep for shaded and wireframe display.
|
||||
pub(super) fn add_surface_model(
|
||||
&mut self,
|
||||
entity: EntityType,
|
||||
surface: Body,
|
||||
) -> Handle {
|
||||
pub(super) fn add_surface_model(&mut self, entity: EntityType, surface: Body) -> Handle {
|
||||
self.add_surface_model_inner(entity, surface, true)
|
||||
}
|
||||
|
||||
@@ -420,11 +412,7 @@ impl super::OpenCADStudio {
|
||||
handle
|
||||
}
|
||||
|
||||
fn add_surface_model_preserving_style(
|
||||
&mut self,
|
||||
entity: EntityType,
|
||||
surface: Body,
|
||||
) -> Handle {
|
||||
fn add_surface_model_preserving_style(&mut self, entity: EntityType, surface: Body) -> Handle {
|
||||
self.add_surface_model_inner(entity, surface, false)
|
||||
}
|
||||
|
||||
@@ -442,8 +430,7 @@ impl super::OpenCADStudio {
|
||||
inner.common.plotstyle_flags = 2;
|
||||
}
|
||||
inner.wires = solid_model::edge_wires(&surface);
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&surface)
|
||||
else {
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&surface) else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("The surface could not be encoded as ACIS.").as_ref());
|
||||
return Handle::NULL;
|
||||
@@ -460,7 +447,13 @@ impl super::OpenCADStudio {
|
||||
let require_complete = self.tabs[i].scene.document.get_entity(handle).is_some_and(|entity|
|
||||
matches!(entity, EntityType::Surface(value) if value.kind == codec::entities::SurfaceKind::Lofted));
|
||||
if !self.tabs[i].scene.register_solid_model(handle, surface)
|
||||
|| (require_complete && self.tabs[i].scene.meshes.get(&handle).is_none_or(|mesh| !mesh.complete)) {
|
||||
|| (require_complete
|
||||
&& self.tabs[i]
|
||||
.scene
|
||||
.meshes
|
||||
.get(&handle)
|
||||
.is_none_or(|mesh| !mesh.complete))
|
||||
{
|
||||
self.tabs[i].scene.rollback_new_entities(&[handle]);
|
||||
return Handle::NULL;
|
||||
}
|
||||
@@ -656,11 +649,16 @@ impl super::OpenCADStudio {
|
||||
|
||||
self.push_undo_snapshot(i, "FILLETEDGE");
|
||||
// A solid without history stays without one, as in the reference.
|
||||
let has_history = self.tabs[i].scene.document.solid_history_graph(handle).is_some();
|
||||
if has_history && !self.tabs[i].scene.append_solid_history(
|
||||
handle,
|
||||
solid_history::fillet_op(history_edges, radius),
|
||||
) {
|
||||
let has_history = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.solid_history_graph(handle)
|
||||
.is_some();
|
||||
if has_history
|
||||
&& !self.tabs[i]
|
||||
.scene
|
||||
.append_solid_history(handle, solid_history::fillet_op(history_edges, radius))
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("The fillet history could not be recorded.").as_ref());
|
||||
return false;
|
||||
@@ -732,22 +730,29 @@ impl super::OpenCADStudio {
|
||||
.position(|candidate| candidate == base_face)
|
||||
.and_then(|ordinal| i32::try_from(ordinal).ok())
|
||||
else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("The selected base face no longer belongs to the body.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("The selected base face no longer belongs to the body.").as_ref(),
|
||||
);
|
||||
return false;
|
||||
};
|
||||
|
||||
self.push_undo_snapshot(i, "CHAMFEREDGE");
|
||||
let has_history = self.tabs[i].scene.document.solid_history_graph(handle).is_some();
|
||||
if has_history && !self.tabs[i].scene.append_solid_history(
|
||||
handle,
|
||||
solid_history::chamfer_op(
|
||||
history_edges,
|
||||
history_face,
|
||||
base_distance,
|
||||
other_distance,
|
||||
),
|
||||
) {
|
||||
let has_history = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.solid_history_graph(handle)
|
||||
.is_some();
|
||||
if has_history
|
||||
&& !self.tabs[i].scene.append_solid_history(
|
||||
handle,
|
||||
solid_history::chamfer_op(
|
||||
history_edges,
|
||||
history_face,
|
||||
base_distance,
|
||||
other_distance,
|
||||
),
|
||||
)
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("The chamfer history could not be recorded.").as_ref());
|
||||
return false;
|
||||
@@ -793,9 +798,10 @@ impl super::OpenCADStudio {
|
||||
if self.reject_locked_edit(i, handle) {
|
||||
return Task::none();
|
||||
}
|
||||
if !matches!(self.tabs[i].scene.document.get_entity(handle), Some(
|
||||
EntityType::Solid3D(_) | EntityType::Surface(_)
|
||||
)) {
|
||||
if !matches!(
|
||||
self.tabs[i].scene.document.get_entity(handle),
|
||||
Some(EntityType::Solid3D(_) | EntityType::Surface(_))
|
||||
) {
|
||||
self.command_line
|
||||
.push_error(crate::t!("Select a 3D solid or surface edge.").as_ref());
|
||||
return Task::none();
|
||||
@@ -821,13 +827,7 @@ impl super::OpenCADStudio {
|
||||
.push_error(crate::t!("CHAMFEREDGE: select a base face edge.").as_ref());
|
||||
return Task::none();
|
||||
};
|
||||
match kernel::brep::chamfer_edges(
|
||||
&body,
|
||||
edges,
|
||||
base_face,
|
||||
value,
|
||||
other_value,
|
||||
) {
|
||||
match kernel::brep::chamfer_edges(&body, edges, base_face, value, other_value) {
|
||||
Ok(result) => Some(result),
|
||||
Err(error) => {
|
||||
self.command_line
|
||||
@@ -946,8 +946,9 @@ impl super::OpenCADStudio {
|
||||
return Task::none();
|
||||
}
|
||||
Err(kernel::brep::ShellError::UnknownFace) => {
|
||||
self.command_line
|
||||
.push_error(crate::t!("A selected face does not belong to the solid.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("A selected face does not belong to the solid.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
Err(kernel::brep::ShellError::NoMaterial) => {
|
||||
@@ -959,8 +960,10 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
Err(kernel::brep::ShellError::Kernel(_)) => {
|
||||
self.command_line.push_error(
|
||||
crate::t!("The shell could not be constructed from the selected solid and distance.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"The shell could not be constructed from the selected solid and distance."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1083,8 +1086,10 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
Err(kernel::brep::Snag::CutRefused) => {
|
||||
self.command_line.push_error(
|
||||
crate::t!("INTERSECT: the selected topology could not be intersected safely.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"INTERSECT: the selected topology could not be intersected safely."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1323,7 +1328,8 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
Err(kernel::brep::Snag::CutRefused) => {
|
||||
self.command_line.push_error(
|
||||
crate::t!("UNION: the selected topology could not be closed safely.").as_ref(),
|
||||
crate::t!("UNION: the selected topology could not be closed safely.")
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1385,7 +1391,8 @@ impl super::OpenCADStudio {
|
||||
.map(|operand| (*operand, SolidHistoryBoolean::UNION))
|
||||
.collect::<Vec<_>>();
|
||||
let scene = &mut self.tabs[i].scene;
|
||||
if !scene.join_boolean_histories(handle, group.handles[0], &steps, &bodies) {
|
||||
if !scene.join_boolean_histories(handle, group.handles[0], &steps, &bodies)
|
||||
{
|
||||
if let Some(body) = scene.solid_models.get(&handle).cloned() {
|
||||
scene.create_solid_history(handle, solid_history::brep_op(&body));
|
||||
}
|
||||
@@ -1423,7 +1430,11 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(
|
||||
crate::t!("UNION: created %{count} result object(s).", count = created.len()).as_ref(),
|
||||
crate::t!(
|
||||
"UNION: created %{count} result object(s).",
|
||||
count = created.len()
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
@@ -1480,8 +1491,10 @@ impl super::OpenCADStudio {
|
||||
cutter_handles.retain(|handle| operand_bodies.contains_key(handle));
|
||||
if base_handles.is_empty() || cutter_handles.is_empty() {
|
||||
self.command_line.push_error(
|
||||
crate::t!("SUBTRACT: select at least one base and one cutter Solid, Region, or Surface.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"SUBTRACT: select at least one base and one cutter Solid, Region, or Surface."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1585,7 +1598,8 @@ impl super::OpenCADStudio {
|
||||
.iter()
|
||||
.map(|handle| operand_bodies[handle].clone())
|
||||
.collect::<Vec<_>>();
|
||||
let result = match subtract_bodies(group.kind, group.plane, base_bodies, cutter_bodies) {
|
||||
let result = match subtract_bodies(group.kind, group.plane, base_bodies, cutter_bodies)
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(kernel::brep::Snag::NoClosedForm) => {
|
||||
self.command_line.push_error(
|
||||
@@ -1660,10 +1674,12 @@ impl super::OpenCADStudio {
|
||||
.map(|cutter| (*cutter, SolidHistoryBoolean::SUBTRACT)),
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
let joined = self.join_boolean_history(handle, &mut entity, &steps, &operand_bodies);
|
||||
let joined =
|
||||
self.join_boolean_history(handle, &mut entity, &steps, &operand_bodies);
|
||||
if !self.tabs[i].scene.update_entity(entity) {
|
||||
self.command_line.push_error(
|
||||
crate::t!("SUBTRACT: the retained base object could not be updated.").as_ref(),
|
||||
crate::t!("SUBTRACT: the retained base object could not be updated.")
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1748,9 +1764,8 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.restore_solid_models(&handles);
|
||||
handles.retain(|handle| self.tabs[i].scene.solid_models.contains_key(handle));
|
||||
if handles.is_empty() {
|
||||
self.command_line.push_error(
|
||||
crate::t!("SLICE: select at least one solid or surface.").as_ref(),
|
||||
);
|
||||
self.command_line
|
||||
.push_error(crate::t!("SLICE: select at least one solid or surface.").as_ref());
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
@@ -1832,8 +1847,10 @@ impl super::OpenCADStudio {
|
||||
.filter(|display| display.0.complete)
|
||||
else {
|
||||
self.command_line.push_error(
|
||||
crate::t!("SLICE: a result could not be displayed completely; no object was changed.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"SLICE: a result could not be displayed completely; no object was changed."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
};
|
||||
@@ -1843,8 +1860,10 @@ impl super::OpenCADStudio {
|
||||
Some(entity) => entity,
|
||||
None => {
|
||||
self.command_line.push_error(
|
||||
crate::t!("SLICE: a result could not be encoded; no object was changed.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"SLICE: a result could not be encoded; no object was changed."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1884,8 +1903,10 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.rollback_new_entities(&created);
|
||||
self.discard_last_undo_entry(i);
|
||||
self.command_line.push_error(
|
||||
crate::t!("SLICE: a result could not be committed; all source objects were retained.")
|
||||
.as_ref(),
|
||||
crate::t!(
|
||||
"SLICE: a result could not be committed; all source objects were retained."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
@@ -1952,8 +1973,9 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.len() != 2 {
|
||||
self.command_line
|
||||
.push_error(crate::t!("INTERFERE: select exactly two solids created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("INTERFERE: select exactly two solids created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
let a = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
@@ -1968,8 +1990,10 @@ impl super::OpenCADStudio {
|
||||
self.add_solid_model(EntityType::Solid3D(s3d), result, history);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(crate::t!("INTERFERE: created an interference solid from the overlap.").as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::t!("INTERFERE: created an interference solid from the overlap.")
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
None => self
|
||||
.command_line
|
||||
@@ -1985,18 +2009,19 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DROTATE: select exactly one solid created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DROTATE: select exactly one solid created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
let Some(middle) = solid_model::centre(&solid) else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DROTATE: could not determine the solid's extent.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DROTATE: could not determine the solid's extent.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
};
|
||||
let Some(rotated) =
|
||||
solid_model::turned(&solid, axis, angle_deg.to_radians(), middle)
|
||||
let Some(rotated) = solid_model::turned(&solid, axis, angle_deg.to_radians(), middle)
|
||||
else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DROTATE: could not turn the solid.").as_ref());
|
||||
@@ -2014,10 +2039,13 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"3DROTATE: rotated {angle_deg}° about the {} axis.",
|
||||
["X", "Y", "Z"][axis]
|
||||
).as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::tf!(
|
||||
"3DROTATE: rotated {angle_deg}° about the {} axis.",
|
||||
["X", "Y", "Z"][axis]
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -2029,14 +2057,16 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DMIRROR: select exactly one solid created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DMIRROR: select exactly one solid created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
let Some(middle) = solid_model::centre(&solid) else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DMIRROR: could not determine the solid's extent.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DMIRROR: could not determine the solid's extent.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
};
|
||||
let Some(reflected) = solid_model::mirrored(&solid, axis, middle) else {
|
||||
@@ -2055,10 +2085,13 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"3DMIRROR: added a mirror across the {} plane.",
|
||||
["X", "Y", "Z"][axis]
|
||||
).as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::tf!(
|
||||
"3DMIRROR: added a mirror across the {} plane.",
|
||||
["X", "Y", "Z"][axis]
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -2074,8 +2107,9 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DALIGN: select exactly one solid created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DALIGN: select exactly one solid created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
// Build a right-handed frame (origin + orthonormal axes) from 3 points.
|
||||
@@ -2097,8 +2131,10 @@ impl super::OpenCADStudio {
|
||||
))
|
||||
};
|
||||
let (Some(s), Some(d)) = (frame(src), frame(dst)) else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("3DALIGN: each point triple must be non-coincident and non-collinear.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("3DALIGN: each point triple must be non-coincident and non-collinear.")
|
||||
.as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
};
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
@@ -2120,8 +2156,9 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(crate::t!("3DALIGN: aligned the solid to the destination points.").as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::t!("3DALIGN: aligned the solid to the destination points.").as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -2135,8 +2172,9 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.len() != 1 {
|
||||
self.command_line
|
||||
.push_error(crate::t!("SECTION: select exactly one solid created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("SECTION: select exactly one solid created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
let solid = self.tabs[i].scene.solid_models[&handles[0]].clone();
|
||||
@@ -2167,11 +2205,14 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"SECTION: created {} section line(s) at {}={value}.",
|
||||
segs.len(),
|
||||
["X", "Y", "Z"][axis]
|
||||
).as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::tf!(
|
||||
"SECTION: created {} section line(s) at {}={value}.",
|
||||
segs.len(),
|
||||
["X", "Y", "Z"][axis]
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -2214,9 +2255,12 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.select_entity(handle, false);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"PYRAMID: created a {n}-sided pyramid (radius {radius}, height {height})."
|
||||
).as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::tf!(
|
||||
"PYRAMID: created a {n}-sided pyramid (radius {radius}, height {height})."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
@@ -2253,8 +2297,9 @@ impl super::OpenCADStudio {
|
||||
))
|
||||
});
|
||||
let Some((handle, fit)) = found else {
|
||||
self.command_line
|
||||
.push_error(crate::t!("SPLINEFIT: select a polyline to fit a spline through.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("SPLINEFIT: select a polyline to fit a spline through.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
};
|
||||
if fit.len() < 3 {
|
||||
@@ -2289,10 +2334,7 @@ impl super::OpenCADStudio {
|
||||
spl.degree = 3;
|
||||
spl.control_points = ctrl;
|
||||
spl.knots = knots;
|
||||
spl.fit_points = fit
|
||||
.iter()
|
||||
.map(|q| Vector3::new(q[0], q[1], q[2]))
|
||||
.collect();
|
||||
spl.fit_points = fit.iter().map(|q| Vector3::new(q[0], q[1], q[2])).collect();
|
||||
// flags.rational defaults to false (non-rational) — exactly what we want.
|
||||
self.push_undo_snapshot(i, "SPLINEFIT");
|
||||
self.tabs[i].scene.erase_entities(&[handle]);
|
||||
@@ -2347,8 +2389,9 @@ impl super::OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
let handles = self.selected_solid_handles();
|
||||
if handles.is_empty() {
|
||||
self.command_line
|
||||
.push_error(crate::t!("CONVTOSURFACE: select a solid created this session.").as_ref());
|
||||
self.command_line.push_error(
|
||||
crate::t!("CONVTOSURFACE: select a solid created this session.").as_ref(),
|
||||
);
|
||||
return Task::none();
|
||||
}
|
||||
let mut surfaces: Vec<Surface> = Vec::new();
|
||||
@@ -2377,12 +2420,15 @@ impl super::OpenCADStudio {
|
||||
}
|
||||
let n = surfaces.len();
|
||||
for surf in surfaces {
|
||||
self.tabs[i].scene.add_entity(EntityType::Surface(Box::new(surf)));
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.add_entity(EntityType::Surface(Box::new(surf)));
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_output(crate::tf!("CONVTOSURFACE: converted {n} solid(s) to surface(s).").as_ref());
|
||||
self.command_line.push_output(
|
||||
crate::tf!("CONVTOSURFACE: converted {n} solid(s) to surface(s).").as_ref(),
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user