forked from 1b-agent/opencadstudio-upstream
Complete SUBTRACT behavior
This commit is contained in:
1 parent
5857ffa2bd
commit
04a9a1b0a0
10 files changed
+562
-69
No files matched your search
@@ -25,16 +25,20 @@ impl BoolOp {
|
||||
enum SubtractStep {
|
||||
Bases,
|
||||
Cutters,
|
||||
ConvertMeshes,
|
||||
}
|
||||
|
||||
pub struct SubtractCommand {
|
||||
step: SubtractStep,
|
||||
bases: Vec<Handle>,
|
||||
cutters: Vec<Handle>,
|
||||
selected: Vec<Handle>,
|
||||
bases_have_mesh: bool,
|
||||
selected_has_mesh: bool,
|
||||
}
|
||||
|
||||
impl SubtractCommand {
|
||||
pub fn new(bases: Vec<Handle>) -> Self {
|
||||
pub fn new(bases: Vec<Handle>, bases_have_mesh: bool) -> Self {
|
||||
let step = if bases.is_empty() {
|
||||
SubtractStep::Bases
|
||||
} else {
|
||||
@@ -43,7 +47,18 @@ impl SubtractCommand {
|
||||
Self {
|
||||
step,
|
||||
bases,
|
||||
cutters: Vec::new(),
|
||||
selected: Vec::new(),
|
||||
bases_have_mesh,
|
||||
selected_has_mesh: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(&mut self, convert_meshes: bool) -> CmdResult {
|
||||
CmdResult::SolidSubtract {
|
||||
bases: std::mem::take(&mut self.bases),
|
||||
cutters: std::mem::take(&mut self.cutters),
|
||||
convert_meshes,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,11 +70,26 @@ impl CadCommand for SubtractCommand {
|
||||
|
||||
fn prompt(&self) -> String {
|
||||
match self.step {
|
||||
SubtractStep::Bases => crate::t!("SUBTRACT Select base solids, then press Enter:")
|
||||
SubtractStep::Bases => crate::t!("SUBTRACT Select base Solids, Regions, Surfaces, or Meshes, then press Enter:")
|
||||
.into_owned(),
|
||||
SubtractStep::Cutters => {
|
||||
crate::t!("SUBTRACT Select solids to subtract, then press Enter:").into_owned()
|
||||
crate::t!("SUBTRACT Select Solids, Regions, Surfaces, or Meshes to subtract, then press Enter:").into_owned()
|
||||
}
|
||||
SubtractStep::ConvertMeshes => crate::t!(
|
||||
"SUBTRACT Convert selected closed Mesh objects to solids? [Yes/No] <Yes>:"
|
||||
)
|
||||
.into_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn options(&self) -> Vec<crate::command::CmdOption> {
|
||||
if matches!(self.step, SubtractStep::ConvertMeshes) {
|
||||
vec![
|
||||
crate::command::CmdOption::new(crate::t!("Yes").as_ref(), "Y"),
|
||||
crate::command::CmdOption::new(crate::t!("No").as_ref(), "N"),
|
||||
]
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,31 +98,72 @@ impl CadCommand for SubtractCommand {
|
||||
}
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
if matches!(self.step, SubtractStep::ConvertMeshes) {
|
||||
return self.finish(true);
|
||||
}
|
||||
if self.selected.is_empty() {
|
||||
return CmdResult::NeedPoint;
|
||||
}
|
||||
match self.step {
|
||||
SubtractStep::Bases => {
|
||||
self.bases = std::mem::take(&mut self.selected);
|
||||
self.bases_have_mesh = self.selected_has_mesh;
|
||||
self.selected_has_mesh = false;
|
||||
self.step = SubtractStep::Cutters;
|
||||
CmdResult::DeselectAndContinue
|
||||
}
|
||||
SubtractStep::Cutters => CmdResult::SolidSubtract {
|
||||
bases: std::mem::take(&mut self.bases),
|
||||
cutters: std::mem::take(&mut self.selected),
|
||||
},
|
||||
SubtractStep::Cutters => {
|
||||
self.cutters = std::mem::take(&mut self.selected);
|
||||
if self.bases_have_mesh || self.selected_has_mesh {
|
||||
self.step = SubtractStep::ConvertMeshes;
|
||||
CmdResult::NeedPoint
|
||||
} else {
|
||||
self.finish(false)
|
||||
}
|
||||
}
|
||||
SubtractStep::ConvertMeshes => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn wants_text_input(&self) -> bool {
|
||||
matches!(self.step, SubtractStep::ConvertMeshes)
|
||||
}
|
||||
|
||||
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||
if !matches!(self.step, SubtractStep::ConvertMeshes) {
|
||||
return None;
|
||||
}
|
||||
Some(match text.trim().to_ascii_lowercase().as_str() {
|
||||
"" | "y" | "yes" => self.finish(true),
|
||||
"n" | "no" => self.finish(false),
|
||||
_ => CmdResult::NeedPoint,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_selection_gathering(&self) -> bool {
|
||||
true
|
||||
!matches!(self.step, SubtractStep::ConvertMeshes)
|
||||
}
|
||||
|
||||
fn inject_selection_entities(&mut self, entities: Vec<SelectionEntity>) {
|
||||
self.selected_has_mesh = entities.iter().any(|entity| {
|
||||
matches!(
|
||||
entity.entity,
|
||||
EntityType::Mesh(_) | EntityType::PolygonMesh(_) | EntityType::PolyfaceMesh(_)
|
||||
)
|
||||
});
|
||||
self.selected = entities
|
||||
.into_iter()
|
||||
.filter_map(|entity| {
|
||||
matches!(entity.entity, EntityType::Solid3D(_)).then_some(entity.handle)
|
||||
matches!(
|
||||
entity.entity,
|
||||
EntityType::Solid3D(_)
|
||||
| EntityType::Region(_)
|
||||
| EntityType::Surface(_)
|
||||
| EntityType::Mesh(_)
|
||||
| EntityType::PolygonMesh(_)
|
||||
| EntityType::PolyfaceMesh(_)
|
||||
)
|
||||
.then_some(entity.handle)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user