forked from 1b-agent/opencadstudio-upstream
Merge pull request #1184 from Ramox81/codex/hatchedit-command-parity
This commit is contained in:
commit
753fa17b68
24 files changed
+926
-132
No files matched your search
@@ -628,6 +628,14 @@ pub(crate) fn boundary_entities_from_sources(
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub(crate) fn replace_hatch_association(&mut self,handle:Handle,paths:Vec<acadrust::entities::BoundaryPath>) {
|
||||
let Some(EntityType::Hatch(hatch))=self.document.get_entity_mut(handle) else{return;};
|
||||
hatch.paths=paths;
|
||||
hatch.is_associative=true;
|
||||
self.associative_hatch_source_cache.borrow_mut().take();
|
||||
self.refresh_fill_model(handle);
|
||||
}
|
||||
|
||||
pub(crate) fn edit_hatch_boundary_handles(
|
||||
&mut self,
|
||||
hatch_handle: Handle,
|
||||
|
||||
@@ -252,7 +252,52 @@ fn apply_object_defaults(doc: &CadDocument, entity: &mut EntityType) {
|
||||
}
|
||||
|
||||
pub fn apply_current_creation_styles(doc: &CadDocument, entity: &mut EntityType) {
|
||||
entity.common_mut().transparency = doc.current_entity_transparency();
|
||||
apply_text_defaults(doc, entity);
|
||||
apply_dimension_defaults(doc, entity);
|
||||
apply_object_defaults(doc, entity);
|
||||
}
|
||||
|
||||
pub(crate) fn parse_current_transparency(value: &str) -> Option<acadrust::types::Transparency> {
|
||||
use acadrust::types::Transparency;
|
||||
match value.trim().to_ascii_uppercase().as_str() {
|
||||
"BYLAYER" | "-1" => Some(Transparency::ByLayer),
|
||||
"BYBLOCK" | "-2" => Some(Transparency::ByBlock),
|
||||
value => value.parse::<u8>().ok().filter(|value| *value <= 90)
|
||||
.map(|value| Transparency::from_percent(value as f64 / 100.0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn current_transparency_label(value: acadrust::types::Transparency) -> String {
|
||||
use acadrust::types::Transparency;
|
||||
match value {
|
||||
Transparency::ByLayer => "ByLayer".into(),
|
||||
Transparency::ByBlock => "ByBlock".into(),
|
||||
Transparency::Explicit(_) => format!("{:.0}", value.as_percent() * 100.0),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod transparency_tests {
|
||||
use super::*;
|
||||
use acadrust::types::Transparency;
|
||||
|
||||
#[test]
|
||||
fn parses_supported_current_transparency_values() {
|
||||
assert_eq!(parse_current_transparency("ByLayer"), Some(Transparency::ByLayer));
|
||||
assert_eq!(parse_current_transparency("-1"), Some(Transparency::ByLayer));
|
||||
assert_eq!(parse_current_transparency("ByBlock"), Some(Transparency::ByBlock));
|
||||
assert_eq!(parse_current_transparency("-2"), Some(Transparency::ByBlock));
|
||||
assert_eq!(parse_current_transparency("25"), Some(Transparency::Explicit(64)));
|
||||
assert!(parse_current_transparency("91").is_none());
|
||||
assert!(parse_current_transparency("25.5").is_none());
|
||||
assert!(parse_current_transparency("invalid").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn labels_transparency_for_command_and_properties_inputs() {
|
||||
assert_eq!(current_transparency_label(Transparency::ByLayer), "ByLayer");
|
||||
assert_eq!(current_transparency_label(Transparency::ByBlock), "ByBlock");
|
||||
assert_eq!(current_transparency_label(Transparency::Explicit(64)), "25");
|
||||
}
|
||||
}
|
||||
@@ -1674,6 +1674,7 @@ impl Scene {
|
||||
let fill_plane_boundary = Some(Arc::new(fill_plane.1));
|
||||
let fill_plane = Some(fill_plane.0);
|
||||
models.push(HatchModel {
|
||||
pattern_origin: None,
|
||||
render_instance,
|
||||
boundary: Arc::new(boundary),
|
||||
boundary_wcs: None,
|
||||
@@ -2107,6 +2108,7 @@ impl Scene {
|
||||
|
||||
let storage = crate::entities::curve::ocs_plane(dxf.normal, dxf.elevation);
|
||||
Some(HatchModel {
|
||||
pattern_origin: Some([dxf.pattern_origin().x, dxf.pattern_origin().y]),
|
||||
render_instance: None,
|
||||
boundary: std::sync::Arc::new(boundary_f32),
|
||||
boundary_wcs: None,
|
||||
@@ -2429,6 +2431,7 @@ impl Scene {
|
||||
})
|
||||
.collect();
|
||||
HatchModel {
|
||||
pattern_origin: None,
|
||||
render_instance: None,
|
||||
boundary: std::sync::Arc::new(boundary),
|
||||
boundary_wcs: None,
|
||||
@@ -2663,6 +2666,9 @@ impl Scene {
|
||||
// carries `world_origin: [0, 0]`, which after the world_offset removal
|
||||
// leaves the fill mis-placed and effectively invisible until a later
|
||||
// edit rebuilds it from the DXF — so keep the seed, don't overwrite it.
|
||||
if let Some(origin) = model.pattern_origin {
|
||||
dxf.record_pattern_origin(Vector2::new(origin[0], origin[1]));
|
||||
}
|
||||
let mut entity = EntityType::Hatch(dxf);
|
||||
|
||||
if let Some(layer) = layer {
|
||||
@@ -2671,6 +2677,8 @@ impl Scene {
|
||||
if let Some((color, transparency)) = entity_style {
|
||||
entity.common_mut().color = color;
|
||||
entity.common_mut().transparency = transparency;
|
||||
} else {
|
||||
entity.common_mut().transparency = self.document.current_entity_transparency();
|
||||
}
|
||||
|
||||
self.add_entity(entity)
|
||||
|
||||
@@ -3856,6 +3856,7 @@ impl Scene {
|
||||
let ((x0, y0), (x1, y1)) = self.paper_limits()?;
|
||||
let (x0, y0, x1, y1) = (x0 as f32, y0 as f32, x1 as f32, y1 as f32);
|
||||
Some(HatchModel {
|
||||
pattern_origin: None,
|
||||
render_instance: None,
|
||||
world_origin: [0.0, 0.0],
|
||||
boundary: Arc::new(vec![[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]]),
|
||||
|
||||
@@ -208,6 +208,8 @@ pub struct FillPlane {
|
||||
/// A hatched region defined by a closed polygon boundary.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HatchModel {
|
||||
/// Recorded hatch origin in its fill plane, independent of intrinsic PAT line bases.
|
||||
pub pattern_origin: Option<[f64; 2]>,
|
||||
pub render_instance: Option<super::instance_model::RenderInstance>,
|
||||
/// World XY anchor (in the same offset-relative coordinate space as
|
||||
/// the rest of the scene — `world_offset` already subtracted, but
|
||||
|
||||
@@ -141,7 +141,7 @@ fn boundary_sources(scene: &Scene, plane: WorkingPlane) -> FxHashMap<Handle, Bou
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn selected_rings(sources: &FxHashMap<Handle, BoundarySource>, point: [f64; 2]) -> Option<Vec<Vec<[f64; 2]>>> {
|
||||
pub(crate) fn selected_rings(sources: &FxHashMap<Handle, BoundarySource>, point: [f64; 2]) -> Option<Vec<Vec<[f64; 2]>>> {
|
||||
let rings = boundary_faces(sources, BOUNDARY_TOLERANCE);
|
||||
let loops = boundary_loops(sources, &rings)?;
|
||||
let tolerance = Tolerance::new(BOUNDARY_TOLERANCE);
|
||||
@@ -179,8 +179,12 @@ fn boundary_region(
|
||||
sources: &FxHashMap<Handle, BoundarySource>, rings: &[Vec<[f64; 2]>], plane: WorkingPlane,
|
||||
) -> Option<EntityType> {
|
||||
let loops = boundary_loops(sources, rings)?;
|
||||
region_from_loops(&loops, plane)
|
||||
}
|
||||
|
||||
pub(crate) fn region_from_loops(loops: &[Vec<Curve>], plane: WorkingPlane) -> Option<EntityType> {
|
||||
let kernel_plane = Plane::from_axes(plane.origin.to_array(), plane.x.to_array(), plane.y.to_array());
|
||||
let sheet = brep::planar_region(kernel_plane, &loops)?;
|
||||
let sheet = brep::planar_region(kernel_plane, loops)?;
|
||||
let document = crate::scene::convert::acis_export::solid_to_sat(&sheet)?;
|
||||
let mut region = Region::new();
|
||||
region.acis_data = AcisData::from_sat(&document.to_sat_string());
|
||||
|
||||
@@ -154,6 +154,7 @@ impl Scene {
|
||||
return None;
|
||||
}
|
||||
let mut model = HatchModel {
|
||||
pattern_origin: None,
|
||||
render_instance: None,
|
||||
world_origin: origin,
|
||||
boundary: std::sync::Arc::new(boundary),
|
||||
|
||||
@@ -2886,6 +2886,7 @@ impl Scene {
|
||||
}
|
||||
boundary.push(boundary[0]);
|
||||
hatches.push(HatchModel {
|
||||
pattern_origin: None,
|
||||
render_instance: wire.render_instance.clone(),
|
||||
world_origin: [0.0, 0.0],
|
||||
boundary: Arc::new(boundary),
|
||||
|
||||
Reference in new issue
Block a user