forked from 1b-agent/opencadstudio-upstream
Harden revolve validation and properties
This commit is contained in:
1 parent
2e112f9aeb
commit
5bbb0bbe1f
8 files changed
+223
-26
No files matched your search
Generated
+1
-1
@@ -878,7 +878,7 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||
[[package]]
|
||||
name = "cadkernel"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=284df21acdbc778e2f0fde7cbf47a35dae328920#284df21acdbc778e2f0fde7cbf47a35dae328920"
|
||||
source = "git+https://github.com/HakanSeven12/cadkernel.git?rev=7e6a651c9493bd52f6abcdaccf508d346766cda5#7e6a651c9493bd52f6abcdaccf508d346766cda5"
|
||||
dependencies = [
|
||||
"acadrust",
|
||||
"cavalier_contours",
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ rfd = "0.17"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
env_logger = "0.11"
|
||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "393d6c0857447f9ca678bed97a612707f0a842c6", features = ["serde"] }
|
||||
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "284df21acdbc778e2f0fde7cbf47a35dae328920", features = ["acis", "offset"] }
|
||||
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "7e6a651c9493bd52f6abcdaccf508d346766cda5", features = ["acis", "offset"] }
|
||||
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
||||
flate2 = "1"
|
||||
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff"] }
|
||||
|
||||
@@ -715,7 +715,9 @@ common =
|
||||
.quadrant = Quadrant
|
||||
.quality = Quality
|
||||
.revolve-could-not-revolve-profile = REVOLVE: could not revolve profile.
|
||||
.revolve-created-objects-failed-sources = REVOLVE: __ocs_arg_created__ object(s) created; __ocs_arg_failed__ source(s) could not be revolved.
|
||||
.revolve-entity-not-found = REVOLVE: entity not found.
|
||||
.revolve-no-selected-object-could-be-revolved = REVOLVE: no selected object could be revolved with the requested options.
|
||||
.revolve-solid-created-0 = REVOLVE: solid created (__ocs_fmt_0__°).
|
||||
.radians = Radians
|
||||
.radius = Radius
|
||||
@@ -2064,7 +2066,14 @@ insert =
|
||||
.revolve-angle-of-revolution-360 = REVOLVE Angle of revolution <360>:
|
||||
.revolve-axis-end-point = REVOLVE Axis end point:
|
||||
.revolve-axis-start-point = REVOLVE Axis start point:
|
||||
.revolve-creation-mode-solid-surface = REVOLVE Creation mode [Solid/Surface]
|
||||
.revolve-enter-angle-expression = REVOLVE Enter angle expression:
|
||||
.revolve-select-line-ray-or-construction-line-for-axis = REVOLVE Select line, ray, or construction line for axis:
|
||||
.revolve-select-objects-or-mode = REVOLVE Select objects to revolve or [Mode] (Enter to finish):
|
||||
.revolve-select-profile = REVOLVE Select profile:
|
||||
.revolve-specify-angle-or-options = REVOLVE Specify angle of revolution or [Start angle/Reverse/Expression]
|
||||
.revolve-specify-axis-start-or-options = REVOLVE Specify axis start point or [Object/X/Y/Z/Mode]:
|
||||
.revolve-specify-start-angle = REVOLVE Specify start angle
|
||||
.sweep-select-path-line-arc-lwpolyline = SWEEP Select path (Line, Arc, LwPolyline):
|
||||
.sweep-select-profile-to-sweep = SWEEP Select profile to sweep:
|
||||
.set-base-point =
|
||||
@@ -2434,6 +2443,7 @@ properties =
|
||||
.alt-suppress-trailing-zeros = Alt suppress trailing zeros
|
||||
.ambient = Ambient
|
||||
.angle-format = Angle format
|
||||
.angle-of-revolution = Angle of revolution
|
||||
.angle-precision = Angle precision
|
||||
.annotation-scale = Annotation scale
|
||||
.annotative-scale = Annotative scale
|
||||
@@ -2449,6 +2459,12 @@ properties =
|
||||
.at-least = At least
|
||||
.attachment-type = Attachment type
|
||||
.attachment = Attachment
|
||||
.axis-direction-x = Axis direction X
|
||||
.axis-direction-y = Axis direction Y
|
||||
.axis-direction-z = Axis direction Z
|
||||
.axis-position-x = Axis position X
|
||||
.axis-position-y = Axis position Y
|
||||
.axis-position-z = Axis position Z
|
||||
.arrowhead-size = Arrowhead Size
|
||||
.attenuation = Attenuation
|
||||
.attribute-definition = Attribute Definition
|
||||
@@ -2879,6 +2895,7 @@ properties =
|
||||
.show = Show
|
||||
.show-clipping = Show Clipping
|
||||
.show-cropping = Show Cropping
|
||||
.show-history = Show History
|
||||
.show-intensity = Show Intensity
|
||||
.show-clipped = Show clipped
|
||||
.show-image = Show image
|
||||
@@ -2886,6 +2903,8 @@ properties =
|
||||
.singleline = SingleLine
|
||||
.softness = Softness
|
||||
.solid = Solid
|
||||
.solid-history = Solid History
|
||||
.solid-type = Solid type
|
||||
.solid3d = Solid3D
|
||||
.source-files = Source Files
|
||||
.source-block = Source block
|
||||
|
||||
@@ -702,7 +702,9 @@ common =
|
||||
.quadrant = Çeyrek Nokta
|
||||
.quality = Kalite
|
||||
.revolve-could-not-revolve-profile = REVOLVE: Profil döndürülemedi.
|
||||
.revolve-created-objects-failed-sources = REVOLVE: __ocs_arg_created__ nesne oluşturuldu; __ocs_arg_failed__ kaynak döndürülemedi.
|
||||
.revolve-entity-not-found = REVOLVE: Nesne bulunamadı.
|
||||
.revolve-no-selected-object-could-be-revolved = REVOLVE: Seçilen nesnelerin hiçbiri istenen seçeneklerle döndürülemedi.
|
||||
.revolve-solid-created-0 = REVOLVE: Katı oluşturuldu (__ocs_fmt_0__°).
|
||||
.radians = Radyan
|
||||
.radius = Yarıçap
|
||||
@@ -2030,7 +2032,14 @@ insert =
|
||||
.revolve-angle-of-revolution-360 = REVOLVE Döndürme açısı <360>:
|
||||
.revolve-axis-end-point = REVOLVE Eksen bitiş noktası:
|
||||
.revolve-axis-start-point = REVOLVE Eksen başlangıç noktası:
|
||||
.revolve-creation-mode-solid-surface = REVOLVE Oluşturma modu [Solid/Surface]
|
||||
.revolve-enter-angle-expression = REVOLVE Açı ifadesini girin:
|
||||
.revolve-select-line-ray-or-construction-line-for-axis = REVOLVE Eksen için çizgi, ışın veya sonsuz çizgi seçin:
|
||||
.revolve-select-objects-or-mode = REVOLVE Döndürülecek nesneleri seçin veya [Mode] (bitirmek için Enter):
|
||||
.revolve-select-profile = REVOLVE Profili seçin:
|
||||
.revolve-specify-angle-or-options = REVOLVE Döndürme açısını belirtin veya [Start angle/Reverse/Expression]
|
||||
.revolve-specify-axis-start-or-options = REVOLVE Eksen başlangıç noktasını belirtin veya [Object/X/Y/Z/Mode]:
|
||||
.revolve-specify-start-angle = REVOLVE Başlangıç açısını belirtin
|
||||
.sweep-select-path-line-arc-lwpolyline = SWEEP Yolu seçin (Çizgi, Yay, Hafif Çoklu Çizgi):
|
||||
.sweep-select-profile-to-sweep = SWEEP Süpürülecek profili seçin:
|
||||
.set-base-point = Taban Noktasını Ayarla
|
||||
@@ -2375,6 +2384,7 @@ properties =
|
||||
.alt-suppress-trailing-zeros = Alternatif birimlerde sondaki sıfırları gizle
|
||||
.ambient = Ortam
|
||||
.angle-format = Açı biçimi
|
||||
.angle-of-revolution = Döndürme açısı
|
||||
.angle-precision = Açı hassasiyeti
|
||||
.annotation-scale = Açıklama ölçeği
|
||||
.annotative-scale = Açıklamalı ölçek
|
||||
@@ -2390,6 +2400,12 @@ properties =
|
||||
.at-least = En az
|
||||
.attachment-type = Bağlantı türü
|
||||
.attachment = Bağlantı
|
||||
.axis-direction-x = Eksen yönü X
|
||||
.axis-direction-y = Eksen yönü Y
|
||||
.axis-direction-z = Eksen yönü Z
|
||||
.axis-position-x = Eksen konumu X
|
||||
.axis-position-y = Eksen konumu Y
|
||||
.axis-position-z = Eksen konumu Z
|
||||
.arrowhead-size = Ok Ucu Boyutu
|
||||
.attenuation = Zayıflama
|
||||
.attribute-definition = Öznitelik Tanımı
|
||||
@@ -2819,6 +2835,7 @@ properties =
|
||||
.show = Göster
|
||||
.show-clipping = Kırpmayı Göster
|
||||
.show-cropping = Kırpmayı Göster
|
||||
.show-history = Geçmişi Göster
|
||||
.show-intensity = Yoğunluğu Göster
|
||||
.show-clipped = Kırpılanı göster
|
||||
.show-image = Görüntüyü göster
|
||||
@@ -2826,6 +2843,8 @@ properties =
|
||||
.singleline = Tek Satır
|
||||
.softness = Yumuşaklık
|
||||
.solid = Katı
|
||||
.solid-history = Katı Geçmişi
|
||||
.solid-type = Katı türü
|
||||
.solid3d = 3B Katı
|
||||
.source-files = Kaynak Dosyalar
|
||||
.source-block = Kaynak blok
|
||||
|
||||
@@ -3831,12 +3831,11 @@ impl OpenCADStudio {
|
||||
mode,
|
||||
color: _,
|
||||
} => {
|
||||
if handles.is_empty()
|
||||
|| handles
|
||||
.iter()
|
||||
.any(|handle| self.reject_locked_edit(i, *handle))
|
||||
{
|
||||
if handles.is_empty() {
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
return Task::none();
|
||||
}
|
||||
let delete_sources = self.tabs[i].scene.document.header.delete_objects;
|
||||
@@ -3847,11 +3846,23 @@ impl OpenCADStudio {
|
||||
use crate::scene::model::sweep_model;
|
||||
let from = axis_start.to_array();
|
||||
let to = axis_end.to_array();
|
||||
let pending = self.begin_undo(i, "REVOLVE", handles.len(), true);
|
||||
let mut editable_handles = Vec::with_capacity(handles.len());
|
||||
let mut failed = 0usize;
|
||||
for handle in handles {
|
||||
if self.reject_locked_edit(i, handle) {
|
||||
failed += 1;
|
||||
} else {
|
||||
editable_handles.push(handle);
|
||||
}
|
||||
}
|
||||
let pending = if editable_handles.is_empty() {
|
||||
None
|
||||
} else {
|
||||
self.begin_undo(i, "REVOLVE", editable_handles.len(), true)
|
||||
};
|
||||
let mut created_handles = Vec::new();
|
||||
let mut consumed = Vec::new();
|
||||
let mut failed = 0usize;
|
||||
for handle in &handles {
|
||||
for handle in &editable_handles {
|
||||
let Some(entity) = self.tabs[i].scene.document.get_entity(*handle).cloned()
|
||||
else {
|
||||
failed += 1;
|
||||
|
||||
@@ -283,6 +283,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Angle = 0.0000° (degenerate rays)" => Some(("inquiry", "angle-0-0000-degenerate-rays")),
|
||||
"Angle format" => Some(("properties", "angle-format")),
|
||||
"Angle precision" => Some(("properties", "angle-precision")),
|
||||
"Angle of revolution" => Some(("properties", "angle-of-revolution")),
|
||||
"Angles" => Some(("model", "angles")),
|
||||
"Angular" => Some(("annotate", "angular")),
|
||||
"Angular decimals (DIMADEC)" => Some(("common", "angular-decimals-dimadec")),
|
||||
@@ -357,6 +358,12 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Axis Point" => Some(("model", "axis-point")),
|
||||
"Axis Vector" => Some(("model", "axis-vector")),
|
||||
"Axis, End" => Some(("draw", "axis-end")),
|
||||
"Axis direction X" => Some(("properties", "axis-direction-x")),
|
||||
"Axis direction Y" => Some(("properties", "axis-direction-y")),
|
||||
"Axis direction Z" => Some(("properties", "axis-direction-z")),
|
||||
"Axis position X" => Some(("properties", "axis-position-x")),
|
||||
"Axis position Y" => Some(("properties", "axis-position-y")),
|
||||
"Axis position Z" => Some(("properties", "axis-position-z")),
|
||||
"BACKGROUND colour [Default/Black/DarkGray/Gray/LightGray/White] or R G B (0–255):" => Some(("file", "background-colour-default-black-darkgray-gray")),
|
||||
"BASE Specify base point:" => Some(("insert", "base-specify-base-point")),
|
||||
"BEDIT Select block reference to edit:" => Some(("modify", "bedit-select-block-reference-to-edit")),
|
||||
@@ -2177,9 +2184,18 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"REVOLVE Angle of revolution <360>:" => Some(("insert", "revolve-angle-of-revolution-360")),
|
||||
"REVOLVE Axis end point:" => Some(("insert", "revolve-axis-end-point")),
|
||||
"REVOLVE Axis start point:" => Some(("insert", "revolve-axis-start-point")),
|
||||
"REVOLVE Creation mode [Solid/Surface]" => Some(("insert", "revolve-creation-mode-solid-surface")),
|
||||
"REVOLVE Enter angle expression:" => Some(("insert", "revolve-enter-angle-expression")),
|
||||
"REVOLVE Select line, ray, or construction line for axis:" => Some(("insert", "revolve-select-line-ray-or-construction-line-for-axis")),
|
||||
"REVOLVE Select objects to revolve or [Mode] (Enter to finish):" => Some(("insert", "revolve-select-objects-or-mode")),
|
||||
"REVOLVE Select profile:" => Some(("insert", "revolve-select-profile")),
|
||||
"REVOLVE Specify angle of revolution or [Start angle/Reverse/Expression]" => Some(("insert", "revolve-specify-angle-or-options")),
|
||||
"REVOLVE Specify axis start point or [Object/X/Y/Z/Mode]:" => Some(("insert", "revolve-specify-axis-start-or-options")),
|
||||
"REVOLVE Specify start angle" => Some(("insert", "revolve-specify-start-angle")),
|
||||
"REVOLVE: created %{created} object(s); %{failed} source(s) could not be revolved." => Some(("common", "revolve-created-objects-failed-sources")),
|
||||
"REVOLVE: could not revolve profile." => Some(("common", "revolve-could-not-revolve-profile")),
|
||||
"REVOLVE: entity not found." => Some(("common", "revolve-entity-not-found")),
|
||||
"REVOLVE: no selected object could be revolved with the requested options." => Some(("common", "revolve-no-selected-object-could-be-revolved")),
|
||||
"REVOLVE: solid created ({:.0}°)." => Some(("common", "revolve-solid-created-0")),
|
||||
"ROTATE Specify first reference point or type reference angle:" => Some(("modify", "rotate-specify-first-reference-point-or-type-r")),
|
||||
"ROTATE Specify new absolute angle [ref=%{a}]:" => Some(("modify", "rotate-specify-new-absolute-angle-ref-a")),
|
||||
@@ -2477,6 +2493,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Show Annotation Objects" => Some(("ui", "show-annotation-objects")),
|
||||
"Show Clipping" => Some(("properties", "show-clipping")),
|
||||
"Show Cropping" => Some(("properties", "show-cropping")),
|
||||
"Show History" => Some(("properties", "show-history")),
|
||||
"Show Intensity" => Some(("properties", "show-intensity")),
|
||||
"Show Lineweight" => Some(("ui", "show-lineweight")),
|
||||
"Show Lineweight\nLWDISPLAY" => Some(("ui", "show-lineweight-lwdisplay")),
|
||||
@@ -2494,6 +2511,8 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Snap to\nUnderlays" => Some(("insert", "snap-to-underlays")),
|
||||
"Softness" => Some(("properties", "softness")),
|
||||
"Solid" => Some(("properties", "solid")),
|
||||
"Solid History" => Some(("properties", "solid-history")),
|
||||
"Solid type" => Some(("properties", "solid-type")),
|
||||
"Solid created." => Some(("common", "solid-created")),
|
||||
"Solid3D" => Some(("properties", "solid3d")),
|
||||
"Source Files" => Some(("properties", "source-files")),
|
||||
|
||||
@@ -622,6 +622,7 @@ pub struct RevolveCommand {
|
||||
axis_end: DVec3,
|
||||
working_plane: WorkingPlane,
|
||||
mode: ExtrudeMode,
|
||||
mode_return: RevolveStep,
|
||||
angle: f64,
|
||||
start_angle: f64,
|
||||
reverse: bool,
|
||||
@@ -670,6 +671,7 @@ impl RevolveCommand {
|
||||
axis_end: DVec3::new(0.0, 0.0, 1.0),
|
||||
working_plane: WorkingPlane::default(),
|
||||
mode: defaults.mode,
|
||||
mode_return: RevolveStep::Pick,
|
||||
angle: defaults.angle,
|
||||
start_angle: defaults.start_angle,
|
||||
reverse: false,
|
||||
@@ -678,8 +680,18 @@ impl RevolveCommand {
|
||||
}
|
||||
|
||||
pub fn set_preselection(&mut self, profiles: Vec<(Handle, EntityType)>) {
|
||||
self.handles = profiles.iter().map(|(handle, _)| *handle).collect();
|
||||
self.preview_profiles = profiles;
|
||||
let selected_handles = profiles.iter().map(|(handle, _)| *handle).collect::<Vec<_>>();
|
||||
self.preview_profiles = profiles
|
||||
.into_iter()
|
||||
.filter(|(_, entity)| {
|
||||
crate::scene::model::sweep_model::extrusion_profile_of(entity).is_some()
|
||||
})
|
||||
.collect();
|
||||
self.handles = if self.preview_profiles.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
selected_handles
|
||||
};
|
||||
if !self.handles.is_empty() {
|
||||
self.step = RevolveStep::AxisStart;
|
||||
}
|
||||
@@ -844,7 +856,7 @@ impl CadCommand for RevolveCommand {
|
||||
t!("REVOLVE Creation mode [Solid/Surface]"),
|
||||
if self.mode == ExtrudeMode::Solid { "Solid" } else { "Surface" }
|
||||
),
|
||||
RevolveStep::AxisStart => t!("REVOLVE Specify axis start point or [Object/X/Y/Z]:").into_owned(),
|
||||
RevolveStep::AxisStart => t!("REVOLVE Specify axis start point or [Object/X/Y/Z/Mode]:").into_owned(),
|
||||
RevolveStep::AxisEnd => t!("REVOLVE Axis end point:").into_owned(),
|
||||
RevolveStep::AxisObject => t!("REVOLVE Select line, ray, or construction line for axis:").into_owned(),
|
||||
RevolveStep::Angle => format!(
|
||||
@@ -872,6 +884,7 @@ impl CadCommand for RevolveCommand {
|
||||
CmdOption::new("X", "X"),
|
||||
CmdOption::new("Y", "Y"),
|
||||
CmdOption::new("Z", "Z"),
|
||||
CmdOption::new("Mode", "MODE"),
|
||||
],
|
||||
RevolveStep::Angle => vec![
|
||||
CmdOption::new("Start angle", "START"),
|
||||
@@ -955,6 +968,7 @@ impl CadCommand for RevolveCommand {
|
||||
let upper = value.to_ascii_uppercase();
|
||||
match self.step {
|
||||
RevolveStep::Pick if "MODE".starts_with(&upper) => {
|
||||
self.mode_return = RevolveStep::Pick;
|
||||
self.step = RevolveStep::Mode;
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
@@ -970,13 +984,17 @@ impl CadCommand for RevolveCommand {
|
||||
.lock()
|
||||
.unwrap_or_else(|error| error.into_inner())
|
||||
.mode = self.mode;
|
||||
self.step = RevolveStep::Pick;
|
||||
self.step = self.mode_return;
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
RevolveStep::AxisStart => {
|
||||
if "OBJECT".starts_with(&upper) {
|
||||
self.step = RevolveStep::AxisObject;
|
||||
Some(CmdResult::NeedPoint)
|
||||
} else if "MODE".starts_with(&upper) {
|
||||
self.mode_return = RevolveStep::AxisStart;
|
||||
self.step = RevolveStep::Mode;
|
||||
Some(CmdResult::NeedPoint)
|
||||
} else if upper == "X" {
|
||||
Some(self.set_axis(self.working_plane.x))
|
||||
} else if upper == "Y" {
|
||||
@@ -1038,7 +1056,7 @@ impl CadCommand for RevolveCommand {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
RevolveStep::Mode => {
|
||||
self.step = RevolveStep::Pick;
|
||||
self.step = self.mode_return;
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
RevolveStep::Angle => self.finish(self.angle),
|
||||
@@ -1062,11 +1080,19 @@ impl CadCommand for RevolveCommand {
|
||||
if self.step != RevolveStep::Pick {
|
||||
return;
|
||||
}
|
||||
self.handles = entities.iter().map(|entry| entry.handle).collect();
|
||||
let selected_handles = entities.iter().map(|entry| entry.handle).collect::<Vec<_>>();
|
||||
self.preview_profiles = entities
|
||||
.into_iter()
|
||||
.filter(|entry| {
|
||||
crate::scene::model::sweep_model::extrusion_profile_of(&entry.entity).is_some()
|
||||
})
|
||||
.map(|entry| (entry.handle, entry.entity))
|
||||
.collect();
|
||||
self.handles = if self.preview_profiles.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
selected_handles
|
||||
};
|
||||
}
|
||||
fn on_selection_complete(&mut self, _handles: Vec<Handle>) -> CmdResult {
|
||||
CmdResult::NeedPoint
|
||||
|
||||
@@ -113,6 +113,73 @@ fn displayed_history_state(object_show_history: bool, show_history_mode: i16) ->
|
||||
}
|
||||
}
|
||||
|
||||
fn revolve_profile_world_normal(value: &SolidHistoryRevolve) -> Option<glam::DVec3> {
|
||||
let profile = value.sweep_entity.as_ref().and_then(embedded_entity)?;
|
||||
let normal = crate::entities::curve::entity_curve(&profile)?.plane.normal()?;
|
||||
let inverse_transpose = matrix(value.base.transform)?.inverse().transpose();
|
||||
inverse_transpose
|
||||
.transform_vector3(glam::DVec3::from_array(normal))
|
||||
.try_normalize()
|
||||
}
|
||||
|
||||
fn revolve_position_component_editable(value: &SolidHistoryRevolve, axis: usize) -> bool {
|
||||
revolve_profile_world_normal(value).is_some_and(|normal| normal[axis].abs() <= 1e-9)
|
||||
}
|
||||
|
||||
fn revolve_direction_component_capacity(
|
||||
value: &SolidHistoryRevolve,
|
||||
axis: usize,
|
||||
) -> Option<(glam::DVec3, f64)> {
|
||||
let normal = revolve_profile_world_normal(value)?;
|
||||
let capacity = (1.0 - normal[axis] * normal[axis]).max(0.0).sqrt();
|
||||
Some((normal, capacity))
|
||||
}
|
||||
|
||||
fn revolve_direction_component_editable(value: &SolidHistoryRevolve, axis: usize) -> bool {
|
||||
revolve_direction_component_capacity(value, axis)
|
||||
.is_some_and(|(_, capacity)| capacity > 1e-9)
|
||||
}
|
||||
|
||||
fn revolve_position_property(
|
||||
value: &SolidHistoryRevolve,
|
||||
axis: usize,
|
||||
label: &str,
|
||||
field: &'static str,
|
||||
position: f64,
|
||||
) -> Property {
|
||||
if revolve_position_component_editable(value, axis) {
|
||||
crate::entities::common::edit_prop(label, field, position)
|
||||
} else {
|
||||
Property {
|
||||
label: label.to_string(),
|
||||
field,
|
||||
value: PropValue::ReadOnly(crate::entities::common::format_length(position)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn revolve_direction_property(
|
||||
value: &SolidHistoryRevolve,
|
||||
axis: usize,
|
||||
label: &str,
|
||||
field: &'static str,
|
||||
direction: f64,
|
||||
) -> Property {
|
||||
if revolve_direction_component_editable(value, axis) {
|
||||
crate::entities::common::edit_scalar_prop(label, field, direction)
|
||||
} else {
|
||||
Property {
|
||||
label: label.to_string(),
|
||||
field,
|
||||
value: PropValue::ReadOnly(if direction == 0.0 {
|
||||
"0".to_string()
|
||||
} else {
|
||||
direction.to_string()
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_specialized_primitive_properties(
|
||||
document: &acadrust::CadDocument,
|
||||
handle: acadrust::Handle,
|
||||
@@ -201,32 +268,44 @@ fn revolve_properties(
|
||||
value.revolve_angle,
|
||||
)),
|
||||
},
|
||||
crate::entities::common::edit_prop(
|
||||
revolve_position_property(
|
||||
value,
|
||||
0,
|
||||
t!("Axis position X").as_ref(),
|
||||
PROP_AXIS_POSITION_X,
|
||||
axis_position.x,
|
||||
),
|
||||
crate::entities::common::edit_prop(
|
||||
revolve_position_property(
|
||||
value,
|
||||
1,
|
||||
t!("Axis position Y").as_ref(),
|
||||
PROP_AXIS_POSITION_Y,
|
||||
axis_position.y,
|
||||
),
|
||||
crate::entities::common::edit_prop(
|
||||
revolve_position_property(
|
||||
value,
|
||||
2,
|
||||
t!("Axis position Z").as_ref(),
|
||||
PROP_AXIS_POSITION_Z,
|
||||
axis_position.z,
|
||||
),
|
||||
crate::entities::common::edit_scalar_prop(
|
||||
revolve_direction_property(
|
||||
value,
|
||||
0,
|
||||
t!("Axis direction X").as_ref(),
|
||||
PROP_AXIS_DIRECTION_X,
|
||||
axis_direction.x,
|
||||
),
|
||||
crate::entities::common::edit_scalar_prop(
|
||||
revolve_direction_property(
|
||||
value,
|
||||
1,
|
||||
t!("Axis direction Y").as_ref(),
|
||||
PROP_AXIS_DIRECTION_Y,
|
||||
axis_direction.y,
|
||||
),
|
||||
crate::entities::common::edit_scalar_prop(
|
||||
revolve_direction_property(
|
||||
value,
|
||||
2,
|
||||
t!("Axis direction Z").as_ref(),
|
||||
PROP_AXIS_DIRECTION_Z,
|
||||
axis_direction.z,
|
||||
@@ -1287,6 +1366,9 @@ fn apply_revolve_geometry_property(
|
||||
PROP_AXIS_POSITION_Y => 1,
|
||||
_ => 2,
|
||||
};
|
||||
if !revolve_position_component_editable(value, axis) {
|
||||
return Some(false);
|
||||
}
|
||||
let target = crate::entities::common::parse_length(text)?;
|
||||
if !target.is_finite() {
|
||||
return Some(false);
|
||||
@@ -1317,17 +1399,38 @@ fn apply_revolve_geometry_property(
|
||||
_ => 2,
|
||||
};
|
||||
let target = text.trim().replace(',', ".").parse::<f64>().ok()?;
|
||||
if !target.is_finite() {
|
||||
let Some((normal, capacity)) = revolve_direction_component_capacity(value, axis) else {
|
||||
return Some(false);
|
||||
};
|
||||
if !target.is_finite() || capacity <= 1e-9 || target.abs() > capacity + 1e-12 {
|
||||
return Some(false);
|
||||
}
|
||||
let mut world = world_vector(
|
||||
let current_world = world_vector(
|
||||
value.base.transform,
|
||||
[value.direction.x, value.direction.y, value.direction.z],
|
||||
)?;
|
||||
world[axis] = target;
|
||||
let Some(world) = world.try_normalize() else {
|
||||
let target = target.clamp(-capacity, capacity);
|
||||
if (current_world[axis] - target).abs() <= 1e-12 {
|
||||
return Some(false);
|
||||
}
|
||||
let component_axis = match axis {
|
||||
0 => glam::DVec3::X,
|
||||
1 => glam::DVec3::Y,
|
||||
_ => glam::DVec3::Z,
|
||||
};
|
||||
let Some(projected_axis) = (component_axis - normal * normal[axis]).try_normalize() else {
|
||||
return Some(false);
|
||||
};
|
||||
let other_axis = normal.cross(projected_axis);
|
||||
let along_projected = target / capacity;
|
||||
let remaining = (1.0 - along_projected * along_projected).max(0.0).sqrt();
|
||||
let other_sign = if current_world.dot(other_axis) < 0.0 {
|
||||
-1.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let world =
|
||||
projected_axis * along_projected + other_axis * (other_sign * remaining);
|
||||
let Some(local) = matrix(value.base.transform)?
|
||||
.inverse()
|
||||
.transform_vector3(world)
|
||||
|
||||
Reference in new issue
Block a user