forked from 1b-agent/opencadstudio-upstream
Point clouds: drawn from their scans, placed, cropped and attached as the reference does
Scans (.rcs) and projects (.rcp) are read and their points drawn as screen-sized dots, coloured by the cloud's stylization. The cloud's placement carries its scale and rotation; its extents and crops stay in the scan's coordinates. A missing scan shows the extents with the saved path. -POINTCLOUDATTACH / POINTCLOUDATTACH, POINTCLOUDCROP and the POINTCLOUD* settings follow the reference's prompts and messages, the Properties list is the reference's, and a locked cloud is left alone by edits. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
07f25f4bca
commit
e9c4e501db
58 files changed
+2711
-237
No files matched your search
+40
-2
@@ -1011,6 +1011,18 @@ impl OpenCADStudio {
|
||||
);
|
||||
}
|
||||
}
|
||||
// Point cloud: the saved path from its definition; the scan's
|
||||
// metres against the drawing's units.
|
||||
codec::EntityType::Extended(extended) => {
|
||||
if let codec::entities::ExtendedEntityData::PointCloudEx(data) = &extended.data {
|
||||
if let Some(definition) = crate::scene::model::point_cloud::definition(doc, data) {
|
||||
set_row(&mut sections, "ext_pcx_path", definition.source_filename.clone());
|
||||
}
|
||||
set_row(&mut sections, "ext_pcx_unit", t!("Meters").into_owned());
|
||||
let factor = insert_unit_scale(doc.header.insertion_units, 6).unwrap_or(1.0);
|
||||
set_row(&mut sections, "ext_pcx_unit_factor", format_unit_factor(factor));
|
||||
}
|
||||
}
|
||||
// Leader: text style / vertical text placement / overall
|
||||
// scale come from its dimension style.
|
||||
codec::EntityType::Leader(ld) => {
|
||||
@@ -2632,7 +2644,15 @@ filter={:.1} local={:.1} aggregate={:.1} entities={}",
|
||||
.iter()
|
||||
.all(|handle| self.tabs[i].scene.is_layer_locked(*handle));
|
||||
if locked_only {
|
||||
make_sections_read_only(&mut panel.sections);
|
||||
// A point cloud locked on its own (not by its layer) still
|
||||
// takes its Locked row, the way it is unlocked.
|
||||
let cloud_lock_only = property_handles
|
||||
.iter()
|
||||
.all(|handle| self.tabs[i].scene.locked_layer_name(*handle).is_none());
|
||||
make_sections_read_only(
|
||||
&mut panel.sections,
|
||||
if cloud_lock_only { &["ext_pcx_locked"] } else { &[] },
|
||||
);
|
||||
// Rows demoted to read-only no longer back an editable field;
|
||||
// drop them from the id→key map so focus can't map onto them.
|
||||
panel.field_key_by_id = crate::ui::properties::build_field_key_map(&panel.sections);
|
||||
@@ -2981,6 +3001,20 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
||||
handles
|
||||
}
|
||||
|
||||
/// The point clouds the Locked row applies to: locked ones too, unless
|
||||
/// their layer is locked.
|
||||
pub(super) fn point_cloud_lock_targets(&self, i: usize) -> Vec<Handle> {
|
||||
let mut handles = self.tabs[i].properties.selected_handles();
|
||||
if handles.is_empty() {
|
||||
handles = self.tabs[i].properties.source_handles.clone();
|
||||
}
|
||||
if handles.is_empty() {
|
||||
handles.extend(self.tabs[i].selected_handle);
|
||||
}
|
||||
handles.retain(|handle| self.tabs[i].scene.locked_layer_name(*handle).is_none());
|
||||
handles
|
||||
}
|
||||
|
||||
pub(super) fn has_property_selection(&self, i: usize) -> bool {
|
||||
!self.tabs[i].properties.selected_handles().is_empty()
|
||||
|| !self.tabs[i].properties.source_handles.is_empty()
|
||||
@@ -3438,12 +3472,16 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_sections_read_only(sections: &mut [crate::scene::model::object::PropSection]) {
|
||||
fn make_sections_read_only(
|
||||
sections: &mut [crate::scene::model::object::PropSection],
|
||||
keep: &[&str],
|
||||
) {
|
||||
use crate::scene::model::object::PropValue;
|
||||
|
||||
for property in sections
|
||||
.iter_mut()
|
||||
.flat_map(|section| section.props.iter_mut())
|
||||
.filter(|property| !keep.contains(&property.field))
|
||||
{
|
||||
let text = match &property.value {
|
||||
PropValue::ReadOnly(value)
|
||||
|
||||
Reference in new issue
Block a user