forked from 1b-agent/opencadstudio-upstream
style: rustfmt the tree so the CI lint check passes
This commit is contained in:
1 parent
1317a7b4fd
commit
6025d8be44
128 files changed
+4097
-1676
No files matched your search
+218
-60
@@ -1513,32 +1513,51 @@ impl Scene {
|
||||
/// their sources: made again from them with the values they were made
|
||||
/// with. A surface edited along with its sources keeps its own edit.
|
||||
/// Returns the surfaces rebuilt.
|
||||
pub(crate) fn refresh_associative_surfaces(&mut self, changes: &[(Handle, crate::scene::ChangeKind)]) -> Vec<(Handle, crate::scene::ChangeKind)> {
|
||||
use crate::scene::model::surface_sources::{axis_points, surface_sources, SurfaceSources, SURFACE_SOURCES_APP};
|
||||
pub(crate) fn refresh_associative_surfaces(
|
||||
&mut self,
|
||||
changes: &[(Handle, crate::scene::ChangeKind)],
|
||||
) -> Vec<(Handle, crate::scene::ChangeKind)> {
|
||||
use crate::scene::model::surface_sources::{
|
||||
axis_points, surface_sources, SurfaceSources, SURFACE_SOURCES_APP,
|
||||
};
|
||||
use crate::scene::model::sweep_model;
|
||||
use codec::objects::SolidHistoryOperation;
|
||||
let changed = changes.iter()
|
||||
let changed = changes
|
||||
.iter()
|
||||
.filter(|(_, kind)| !matches!(kind, crate::scene::ChangeKind::Removed))
|
||||
.map(|(handle, _)| *handle)
|
||||
.collect::<rustc_hash::FxHashSet<_>>();
|
||||
if changed.is_empty() || !self.document.app_ids.contains(SURFACE_SOURCES_APP) {
|
||||
return Vec::new();
|
||||
}
|
||||
let linked = self.document.entities()
|
||||
let linked = self
|
||||
.document
|
||||
.entities()
|
||||
.filter(|entity| matches!(entity, EntityType::Surface(_)))
|
||||
.filter_map(|entity| {
|
||||
let handle = entity.common().handle;
|
||||
let sources = surface_sources(entity)?;
|
||||
(!changed.contains(&handle) && sources.handles().iter().any(|source| changed.contains(source)))
|
||||
.then_some((handle, sources))
|
||||
(!changed.contains(&handle)
|
||||
&& sources
|
||||
.handles()
|
||||
.iter()
|
||||
.any(|source| changed.contains(source)))
|
||||
.then_some((handle, sources))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut rebuilt = Vec::new();
|
||||
for (handle, sources) in linked {
|
||||
let source = |handle: Handle| self.document.get_entity(handle).cloned();
|
||||
// The surface made again: a history step, or a body with its data.
|
||||
let made: Option<Result<SolidHistoryOperation, (kernel::brep::Body, codec::entities::SurfaceData)>> = match &sources {
|
||||
SurfaceSources::Extrude { profile, height, direction, taper } => (|| {
|
||||
let made: Option<
|
||||
Result<SolidHistoryOperation, (kernel::brep::Body, codec::entities::SurfaceData)>,
|
||||
> = match &sources {
|
||||
SurfaceSources::Extrude {
|
||||
profile,
|
||||
height,
|
||||
direction,
|
||||
taper,
|
||||
} => (|| {
|
||||
let entity = source(*profile)?;
|
||||
let (shape, _) = sweep_model::extrusion_profile_of(&entity)?;
|
||||
let direction = match direction {
|
||||
@@ -1546,37 +1565,86 @@ impl Scene {
|
||||
None => glam::DVec3::from_array(shape.plane.normal()?) * *height,
|
||||
};
|
||||
if self.document.solid_history_operations(handle).is_some() {
|
||||
return sweep_model::extrusion_history(&entity, None, direction.to_array(), *taper, shape.plane.origin).map(Ok);
|
||||
return sweep_model::extrusion_history(
|
||||
&entity,
|
||||
None,
|
||||
direction.to_array(),
|
||||
*taper,
|
||||
shape.plane.origin,
|
||||
)
|
||||
.map(Ok);
|
||||
}
|
||||
let body = sweep_model::extruded_surface(&entity, direction.to_array(), *taper)?;
|
||||
let EntityType::Surface(fresh) = crate::modules::insert::solid3d_cmds::empty_extruded_surface(direction, *taper) else { return None };
|
||||
let body =
|
||||
sweep_model::extruded_surface(&entity, direction.to_array(), *taper)?;
|
||||
let EntityType::Surface(fresh) =
|
||||
crate::modules::insert::solid3d_cmds::empty_extruded_surface(
|
||||
direction, *taper,
|
||||
)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
Some(Err((body, fresh.surface_data)))
|
||||
})(),
|
||||
SurfaceSources::Revolve { profile, axis, start, end, angle, start_angle } => (|| {
|
||||
SurfaceSources::Revolve {
|
||||
profile,
|
||||
axis,
|
||||
start,
|
||||
end,
|
||||
angle,
|
||||
start_angle,
|
||||
} => (|| {
|
||||
let entity = source(*profile)?;
|
||||
let (start, end) = axis
|
||||
.and_then(|axis| self.document.get_entity(axis).and_then(axis_points))
|
||||
.unwrap_or((*start, *end));
|
||||
let body = sweep_model::revolved_surface(&entity, start.to_array(), end.to_array(), *angle, *start_angle)?;
|
||||
let EntityType::Surface(fresh) = crate::modules::insert::solid3d_cmds::empty_revolved_surface(&entity, start, end, *angle, *start_angle) else { return None };
|
||||
let body = sweep_model::revolved_surface(
|
||||
&entity,
|
||||
start.to_array(),
|
||||
end.to_array(),
|
||||
*angle,
|
||||
*start_angle,
|
||||
)?;
|
||||
let EntityType::Surface(fresh) =
|
||||
crate::modules::insert::solid3d_cmds::empty_revolved_surface(
|
||||
&entity,
|
||||
start,
|
||||
end,
|
||||
*angle,
|
||||
*start_angle,
|
||||
)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
Some(Err((body, fresh.surface_data)))
|
||||
})(),
|
||||
SurfaceSources::Loft { sections } => (|| {
|
||||
let operations = self.document.solid_history_operations(handle)?;
|
||||
let mut record = operations.into_iter().find_map(|operation| match operation {
|
||||
SolidHistoryOperation::Loft(record) => Some(record),
|
||||
_ => None,
|
||||
})?;
|
||||
let mut record =
|
||||
operations
|
||||
.into_iter()
|
||||
.find_map(|operation| match operation {
|
||||
SolidHistoryOperation::Loft(record) => Some(record),
|
||||
_ => None,
|
||||
})?;
|
||||
if record.cross_sections.len() != sections.len() {
|
||||
return None;
|
||||
}
|
||||
record.cross_sections = sections.iter()
|
||||
.map(|section| source(*section).as_ref().and_then(crate::scene::model::loft_command_model::embedded_section))
|
||||
record.cross_sections = sections
|
||||
.iter()
|
||||
.map(|section| {
|
||||
source(*section)
|
||||
.as_ref()
|
||||
.and_then(crate::scene::model::loft_command_model::embedded_section)
|
||||
})
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
Some(Ok(SolidHistoryOperation::Loft(record)))
|
||||
})(),
|
||||
};
|
||||
let before = self.document.get_entity(handle).cloned().map(std::sync::Arc::new);
|
||||
let before = self
|
||||
.document
|
||||
.get_entity(handle)
|
||||
.cloned()
|
||||
.map(std::sync::Arc::new);
|
||||
match made {
|
||||
Some(Ok(operation)) => {
|
||||
self.record_undo_before(handle, before);
|
||||
@@ -1585,11 +1653,18 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
Some(Err((body, data))) => {
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&body) else { continue };
|
||||
let Some(display) = self.prepare_solid_model_display(handle, &body) else { continue };
|
||||
let Some(document) = crate::scene::convert::acis_export::solid_to_sat(&body)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let Some(display) = self.prepare_solid_model_display(handle, &body) else {
|
||||
continue;
|
||||
};
|
||||
self.record_undo_before(handle, before);
|
||||
if let Some(EntityType::Surface(surface)) = self.document.get_entity_mut(handle) {
|
||||
surface.acis_data = codec::entities::AcisData::from_sat(&document.to_sat_string());
|
||||
if let Some(EntityType::Surface(surface)) = self.document.get_entity_mut(handle)
|
||||
{
|
||||
surface.acis_data =
|
||||
codec::entities::AcisData::from_sat(&document.to_sat_string());
|
||||
surface.surface_data = data;
|
||||
}
|
||||
self.register_prepared_solid_model(handle, body, display);
|
||||
@@ -1614,42 +1689,90 @@ impl Scene {
|
||||
let mut sources = Vec::new();
|
||||
let mut others = Vec::new();
|
||||
for item in self.document.objects.values() {
|
||||
let ObjectType::Associative(action) = item else { continue };
|
||||
let AssociativeData::Action(action) = &action.data else { continue };
|
||||
let Some(AssociativeData::SurfaceActionBody(body)) = object(action.action_body) else { continue };
|
||||
let Some(AssociativeData::Dependency(written)) = object(body.surface_body.dependency) else { continue };
|
||||
let ObjectType::Associative(action) = item else {
|
||||
continue;
|
||||
};
|
||||
let AssociativeData::Action(action) = &action.data else {
|
||||
continue;
|
||||
};
|
||||
let Some(AssociativeData::SurfaceActionBody(body)) = object(action.action_body) else {
|
||||
continue;
|
||||
};
|
||||
let Some(AssociativeData::Dependency(written)) = object(body.surface_body.dependency)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
// The entities a named path parameter reads (an edge of a region
|
||||
// reads through a geometry dependency).
|
||||
let read = |name: &str| -> Vec<Handle> {
|
||||
action.owned_parameters.iter().filter_map(|parameter| {
|
||||
let Some(AssociativeData::PathActionParam(path)) = object(*parameter) else { return None };
|
||||
if path.compound.action_param.name != name { return None; }
|
||||
let Some(AssociativeData::EdgeActionParam(edge)) = object(*path.compound.parameters.first()?) else { return None };
|
||||
match object(edge.single_dependency.dependency) {
|
||||
Some(AssociativeData::Dependency(dependency)) => Some(dependency.dependent_on),
|
||||
Some(AssociativeData::GeomDependency(dependency)) => Some(dependency.dependency.dependent_on),
|
||||
action
|
||||
.owned_parameters
|
||||
.iter()
|
||||
.filter_map(|parameter| {
|
||||
let Some(AssociativeData::PathActionParam(path)) = object(*parameter)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
if path.compound.action_param.name != name {
|
||||
return None;
|
||||
}
|
||||
let Some(AssociativeData::EdgeActionParam(edge)) =
|
||||
object(*path.compound.parameters.first()?)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
match object(edge.single_dependency.dependency) {
|
||||
Some(AssociativeData::Dependency(dependency)) => {
|
||||
Some(dependency.dependent_on)
|
||||
}
|
||||
Some(AssociativeData::GeomDependency(dependency)) => {
|
||||
Some(dependency.dependency.dependent_on)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let real = |name: &str| {
|
||||
action
|
||||
.values
|
||||
.iter()
|
||||
.find(|value| value.name == name)
|
||||
.and_then(|value| value.variables.first())
|
||||
.and_then(|variable| match variable.value.value {
|
||||
codec::objects::AssocEvalValue::Real(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}).collect()
|
||||
})
|
||||
};
|
||||
let real = |name: &str| action.values.iter().find(|value| value.name == name)
|
||||
.and_then(|value| value.variables.first())
|
||||
.and_then(|variable| match variable.value.value {
|
||||
codec::objects::AssocEvalValue::Real(value) => Some(value),
|
||||
_ => None,
|
||||
});
|
||||
match body.kind {
|
||||
AssocSurfaceActionKind::Extruded => {
|
||||
if let (Some(profile), Some(height), Some(taper)) =
|
||||
(read("ExtrudeProfile").first().copied(), real("ExtrusionHeight"), real("ExtrusionTaperAngle"))
|
||||
{
|
||||
others.push((written.dependent_on, (body.kind, vec![profile], None, height, taper)));
|
||||
if let (Some(profile), Some(height), Some(taper)) = (
|
||||
read("ExtrudeProfile").first().copied(),
|
||||
real("ExtrusionHeight"),
|
||||
real("ExtrusionTaperAngle"),
|
||||
) {
|
||||
others.push((
|
||||
written.dependent_on,
|
||||
(body.kind, vec![profile], None, height, taper),
|
||||
));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
AssocSurfaceActionKind::Revolved => {
|
||||
if let (Some(profile), Some(angle)) = (read("RevolveProfile").first().copied(), real("RevolveAngle")) {
|
||||
others.push((written.dependent_on, (body.kind, vec![profile], read("RevolvePath").first().copied(), angle, 0.0)));
|
||||
if let (Some(profile), Some(angle)) = (
|
||||
read("RevolveProfile").first().copied(),
|
||||
real("RevolveAngle"),
|
||||
) {
|
||||
others.push((
|
||||
written.dependent_on,
|
||||
(
|
||||
body.kind,
|
||||
vec![profile],
|
||||
read("RevolvePath").first().copied(),
|
||||
angle,
|
||||
0.0,
|
||||
),
|
||||
));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1692,7 +1815,10 @@ impl Scene {
|
||||
links.push((written.dependent_on, expressions));
|
||||
}
|
||||
// The profile and path the action reads.
|
||||
if let (Some(profile), Some(path)) = (read("SweepProfile").first().copied(), read("SweepPath").first().copied()) {
|
||||
if let (Some(profile), Some(path)) = (
|
||||
read("SweepProfile").first().copied(),
|
||||
read("SweepPath").first().copied(),
|
||||
) {
|
||||
sources.push((written.dependent_on, profile, path));
|
||||
}
|
||||
}
|
||||
@@ -1735,27 +1861,59 @@ impl Scene {
|
||||
}
|
||||
// Associative extruded, revolved and lofted surfaces follow their
|
||||
// sources here too.
|
||||
use crate::scene::model::surface_sources::{link_surface_sources, surface_sources, SurfaceSources};
|
||||
use crate::scene::model::surface_sources::{
|
||||
link_surface_sources, surface_sources, SurfaceSources,
|
||||
};
|
||||
for (surface, (kind, handles, axis, amount, taper)) in others {
|
||||
let Some(entity @ EntityType::Surface(value)) = self.document.get_entity(surface) else { continue };
|
||||
if surface_sources(entity).is_some() { continue; }
|
||||
let Some(entity @ EntityType::Surface(value)) = self.document.get_entity(surface)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if surface_sources(entity).is_some() {
|
||||
continue;
|
||||
}
|
||||
let linked = match (kind, &value.surface_data) {
|
||||
(AssocSurfaceActionKind::Extruded, codec::entities::SurfaceData::Extruded { sweep_vector, .. }) => {
|
||||
(
|
||||
AssocSurfaceActionKind::Extruded,
|
||||
codec::entities::SurfaceData::Extruded { sweep_vector, .. },
|
||||
) => {
|
||||
let profile = handles[0];
|
||||
let along = glam::DVec3::new(sweep_vector.x, sweep_vector.y, sweep_vector.z);
|
||||
// A direction other than the profile's normal is kept.
|
||||
let normal = self.document.get_entity(profile)
|
||||
.and_then(|entity| crate::scene::model::sweep_model::extrusion_profile_of(entity))
|
||||
let normal = self
|
||||
.document
|
||||
.get_entity(profile)
|
||||
.and_then(|entity| {
|
||||
crate::scene::model::sweep_model::extrusion_profile_of(entity)
|
||||
})
|
||||
.and_then(|(shape, _)| shape.plane.normal())
|
||||
.map(glam::DVec3::from_array);
|
||||
let direction = match normal {
|
||||
Some(normal) if (normal * amount - along).length() <= 1e-9 * amount.abs().max(1.0) => None,
|
||||
Some(normal)
|
||||
if (normal * amount - along).length()
|
||||
<= 1e-9 * amount.abs().max(1.0) =>
|
||||
{
|
||||
None
|
||||
}
|
||||
_ if along.length() > 1e-12 => Some(along),
|
||||
_ => None,
|
||||
};
|
||||
SurfaceSources::Extrude { profile, height: amount, direction, taper }
|
||||
SurfaceSources::Extrude {
|
||||
profile,
|
||||
height: amount,
|
||||
direction,
|
||||
taper,
|
||||
}
|
||||
}
|
||||
(AssocSurfaceActionKind::Revolved, codec::entities::SurfaceData::Revolved { axis_point, axis_vector, start_angle, .. }) => {
|
||||
(
|
||||
AssocSurfaceActionKind::Revolved,
|
||||
codec::entities::SurfaceData::Revolved {
|
||||
axis_point,
|
||||
axis_vector,
|
||||
start_angle,
|
||||
..
|
||||
},
|
||||
) => {
|
||||
let start = glam::DVec3::new(axis_point.x, axis_point.y, axis_point.z);
|
||||
SurfaceSources::Revolve {
|
||||
profile: handles[0],
|
||||
|
||||
Reference in new issue
Block a user