Merge commit 'ac9a6b07' into codex/pointcloud-attach

# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
#	src/app/control/actions.rs
#	src/locale_catalog.rs
This commit is contained in:
ramox81 committed 2026-09-30 13:26:52 +03:00
commit ee0d4aedb5
35 files changed
+673 -13

No files matched your search

+2
View File
@@ -740,6 +740,8 @@ inventory::submit!(crate::command::CommandRegistration {
"EXPORTSTEP",
"EXPORTSTL",
"EXTERNALREFERENCES",
"POINTCLOUDMANAGER",
"POINTCLOUDMANAGERCLOSE",
"EXTRIM",
"FILETAB",
"FIND",
+7 -1
View File
@@ -34,7 +34,13 @@ impl OpenCADStudio {
common.color.clone()
};
let color = color.rgb().map_or([255; 3], |(r, g, b)| [r, g, b]);
if let Some(placed) = crate::scene::model::point_cloud::placed(document, data, color, None) {
if let Some(placed) = crate::scene::model::point_cloud::placed(
document,
data,
color,
None,
&crate::scene::model::point_cloud::hidden(common),
) {
clouds.push((common.handle, placed));
}
}
+70 -1
View File
@@ -162,6 +162,59 @@ impl OpenCADStudio {
self.refresh_properties();
}
/// A Point Cloud Manager click: a switch writes the cloud's visibility
/// extended data as one undo step; the rest is palette state.
pub(in crate::app) fn update_pc_manager(&mut self, message: crate::ui::window::pc_manager::PcManagerMsg) -> Task<Message> {
use crate::scene::model::point_cloud::VISIBILITY_APP;
use crate::ui::window::pc_manager::{self, PcManagerMsg};
let i = self.active_tab;
match message {
PcManagerMsg::Toggle(handle, row) => {
let Some(cloud) =
pc_manager::clouds(&self.tabs[i].scene.document, &[]).into_iter().find(|c| c.handle == handle)
else {
return Task::none();
};
if self.tabs[i].scene.is_layer_locked(handle) {
return Task::none();
}
let hidden = pc_manager::toggled(&cloud.hidden, &cloud.scans, &row);
self.push_undo_snapshot(i, "POINTCLOUDMANAGER");
self.tabs[i].scene.ensure_app_id(VISIBILITY_APP);
let app_handle = self.tabs[i].scene.document.app_ids.get(VISIBILITY_APP).map(|a| a.handle.value());
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
let data = &mut entity.common_mut().extended_data;
if let Some(app) = app_handle {
data.raw_dwg_eed.retain(|(a, _)| *a != app);
}
data.remove_record(VISIBILITY_APP);
if !hidden.is_empty() {
let mut record = codec::xdata::ExtendedDataRecord::new(VISIBILITY_APP);
for name in hidden {
record.add_value(codec::xdata::XDataValue::String(name));
}
data.add_record(record);
}
}
self.tabs[i].scene.bump_entities(&[(handle, crate::scene::ChangeKind::Modified)]);
self.tabs[i].dirty = true;
}
PcManagerMsg::Expand(key) => {
if !self.pc_manager.collapsed.remove(&key) {
self.pc_manager.collapsed.insert(key);
}
}
PcManagerMsg::Select(key) => self.pc_manager.selected = Some(key),
PcManagerMsg::Search(text) => self.pc_manager.search = text,
PcManagerMsg::CollapseAll => {
let clouds = pc_manager::clouds(&self.tabs[i].scene.document, &[]);
self.pc_manager.collapsed.extend(pc_manager::folding_keys(&clouds));
}
PcManagerMsg::ExpandAll => self.pc_manager.collapsed.clear(),
}
Task::none()
}
/// One undo step that edits every selected PDF underlay.
fn edit_selected_underlays(&mut self, i: usize, label: &str, edit: impl Fn(&mut Underlay)) {
let handles: Vec<_> = self
@@ -319,7 +372,23 @@ impl OpenCADStudio {
crop.inverted = !crop.inverted;
}
}),
"_PCUNCROP" => self.edit_selected_point_clouds(i, "POINTCLOUDUNCROP", |data| data.croppings.clear()),
// The Point Cloud Manager docks on the right like External
// References and opens expanded.
"POINTCLOUDMANAGER" => {
let id = crate::ui::dock::PanelId::PointCloudManager;
self.pc_manager.show = true;
if self.dock.location(id).is_none() {
self.dock.dock(id, crate::app::config::DockSide::Right, usize::MAX);
}
self.dock_expanded = Some(id);
}
"POINTCLOUDMANAGERCLOSE" => {
self.pc_manager.show = false;
if self.dock_expanded == Some(crate::ui::dock::PanelId::PointCloudManager) {
self.dock_expanded = None;
}
}
"_PCUNCROP" =>self.edit_selected_point_clouds(i, "POINTCLOUDUNCROP", |data| data.croppings.clear()),
"_PDFULUNCLIP" => {
self.edit_selected_underlays(i, "PDFCLIP", |u| {
u.clip_boundary_vertices.clear();
+14
View File
@@ -71,6 +71,7 @@ pub(super) const NAMES: &[&str] = &[
"close_modal",
"pdf_dialog_ok",
"pdf_layer_toggle",
"pc_manager_toggle",
"pdf_page_select",
"pc_colormap",
"ribbon_tab",
@@ -719,6 +720,19 @@ impl OpenCADStudio {
_ => return Err(failure("invalid_value", "Unknown color map edit")),
})
}
// Point Cloud Manager: flip a row's switch, "<handle>:<row>" with
// row cloud, unassigned, scans or scan:<name>.
"pc_manager_toggle" => {
use crate::ui::window::pc_manager::{PcManagerMsg, Row};
let value = string(req, "value")?;
let parsed = value.split_once(':').and_then(|(handle, row)| {
Some((codec::Handle::new(u64::from_str_radix(handle, 16).ok()?), Row::parse(row)?))
});
let Some((handle, row)) = parsed else {
return Err(failure("bad_value", "Expected <handle>:<row>"));
};
Message::PcManager(PcManagerMsg::Toggle(handle, row))
}
// Attach dialog: choose pages by index ("0,2").
"pdf_page_select" => {
let pages: Vec<usize> = string(req, "value")?
+5
View File
@@ -793,6 +793,8 @@ pub(super) struct OpenCADStudio {
/// Whether the Browser panel is shown. Off until BROWSER opens it, so
/// the default layout is unchanged for existing users.
pub(crate) show_browser: bool,
/// Point Cloud Manager palette (POINTCLOUDMANAGER).
pub(crate) pc_manager: crate::ui::window::pc_manager::PcManager,
/// Which viewport background the colour wheel is editing, or `None` when
/// it is closed. One slot, because only one wheel can be open at a time.
pub(crate) bg_picker: Option<BgTarget>,
@@ -3845,6 +3847,8 @@ pub enum Message {
PdfImportPick,
/// An edit in one of the PDF dialogs.
PdfDialog(crate::ui::window::pdf_dialogs::PdfDialogMsg),
/// A click or search in the Point Cloud Manager.
PcManager(crate::ui::window::pc_manager::PcManagerMsg),
PdfImportPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
/// Result of the PDFATTACH file picker.
PdfAttachPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
@@ -4160,6 +4164,7 @@ impl OpenCADStudio {
graph_undo_open: false,
show_external_references: false,
show_browser: false,
pc_manager: Default::default(),
bg_picker: None,
block_palette: Default::default(),
xref_manager: Default::default(),
+4
View File
@@ -608,6 +608,9 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
PanelId::NodeGraph => {
self.show_node_graph = false;
}
PanelId::PointCloudManager => {
self.pc_manager.show = false;
}
PanelId::Properties => {
self.show_properties = false;
self.ribbon.set_properties(false);
@@ -712,6 +715,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
PanelId::ExternalReferences => self.show_external_references,
PanelId::Browser => self.show_browser,
PanelId::NodeGraph => self.show_node_graph,
PanelId::PointCloudManager => self.pc_manager.show,
}
}
+1
View File
@@ -1806,6 +1806,7 @@ impl OpenCADStudio {
}
Message::PdfDialog(message) => self.update_pdf_dialog(message),
Message::PcManager(message) => self.update_pc_manager(message),
Message::RibbonSelectTab(idx) => {
self.ribbon.select(idx);
Task::none()
+8
View File
@@ -1870,6 +1870,7 @@ bg={bg_ms:.1}ms n={view_count}"
crate::ui::dock::PanelId::ExternalReferences => self.show_external_references,
crate::ui::dock::PanelId::Browser => self.show_browser,
crate::ui::dock::PanelId::NodeGraph => self.show_node_graph,
crate::ui::dock::PanelId::PointCloudManager => self.pc_manager.show,
}
};
let edge_stack = |side: crate::app::config::DockSide| -> Option<Element<'_, Message>> {
@@ -2994,6 +2995,13 @@ impl OpenCADStudio {
auto_collapse,
),
crate::ui::dock::PanelId::NodeGraph => tab.graph.panel(width, auto_collapse),
crate::ui::dock::PanelId::PointCloudManager => crate::ui::window::pc_manager::view(
&self.pc_manager,
&tab.scene.document,
&tab.scene.selected_handles_in_order(),
width,
auto_collapse,
),
};
let divider = dock_divider(id);
match side {