forked from 1b-agent/opencadstudio-upstream
Merge remote-tracking branch 'origin/main' into codex/shell-parity
# Conflicts: # Cargo.lock # Cargo.toml # crates/ocs_doc_api/Cargo.toml # src/modules/model/mod.rs
This commit is contained in:
commit
7913f8e2da
68 files changed
+5496
-548
No files matched your search
@@ -21,3 +21,54 @@ pub fn solid_to_sat(body: &Body) -> Option<SatDocument> {
|
||||
let binary = SabWriter::write(&document);
|
||||
valid(&SabReader::read(&binary).ok()?).then_some(document)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use cadkernel::geom2d::{Arc, Curve};
|
||||
use cadkernel::space::Plane;
|
||||
|
||||
fn circle_section(z: f64, radius: f64) -> (Plane, Vec<Curve>) {
|
||||
let curves = (0..4)
|
||||
.map(|part| {
|
||||
let start = std::f64::consts::FRAC_PI_2 * part as f64;
|
||||
Curve::Arc(Arc {
|
||||
centre: [0.0, 0.0],
|
||||
radius,
|
||||
start_angle: start,
|
||||
end_angle: start + std::f64::consts::FRAC_PI_2,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
(
|
||||
Plane::from_axes([0.0, 0.0, z], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]),
|
||||
curves,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_curved_loft_round_trips_through_text_and_binary_acis() {
|
||||
let body = cadkernel::brep::loft(&[
|
||||
circle_section(0.0, 5.0),
|
||||
circle_section(10.0, 2.0),
|
||||
])
|
||||
.unwrap();
|
||||
assert!(body.validate().is_empty());
|
||||
|
||||
let mut document = SatDocument::new();
|
||||
cadkernel::acis::append(&body, &mut document).unwrap();
|
||||
let text = document.to_sat_string();
|
||||
let parsed = SatDocument::parse(&text).unwrap();
|
||||
let (restored, text_loss) = cadkernel::acis::lift(&parsed);
|
||||
assert!(text_loss.is_empty(), "{text_loss:?}");
|
||||
assert_eq!(restored.len(), 1);
|
||||
assert!(restored[0].validate().is_empty());
|
||||
|
||||
let binary = SabWriter::write(&parsed);
|
||||
let parsed_binary = SabReader::read(&binary).unwrap();
|
||||
let (restored, binary_loss) = cadkernel::acis::lift(&parsed_binary);
|
||||
assert!(binary_loss.is_empty(), "{binary_loss:?}");
|
||||
assert_eq!(restored.len(), 1);
|
||||
assert!(restored[0].validate().is_empty());
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,33 @@ fn split_mixed_polyline(
|
||||
|
||||
// Emit each arc segment as an analytical wire (CircleGpu target)
|
||||
for tg in tangent_geoms {
|
||||
if matches!(tg, TangentGeom::Arc { .. }) {
|
||||
if let TangentGeom::Arc {
|
||||
center,
|
||||
axis_x,
|
||||
axis_y,
|
||||
radius,
|
||||
start_angle,
|
||||
end_angle,
|
||||
} = *tg
|
||||
{
|
||||
let mut arc_pts = Vec::with_capacity(17);
|
||||
let n = 16;
|
||||
let sweep = if end_angle >= start_angle {
|
||||
end_angle - start_angle
|
||||
} else {
|
||||
end_angle - start_angle + std::f64::consts::TAU
|
||||
};
|
||||
for s in 0..=n {
|
||||
let frac = s as f64 / n as f64;
|
||||
let ang = start_angle + frac * sweep;
|
||||
let p = [
|
||||
center[0] + radius * (ang.cos() * axis_x[0] + ang.sin() * axis_y[0]),
|
||||
center[1] + radius * (ang.cos() * axis_x[1] + ang.sin() * axis_y[1]),
|
||||
center[2] + radius * (ang.cos() * axis_x[2] + ang.sin() * axis_y[2]),
|
||||
];
|
||||
arc_pts.push(p);
|
||||
}
|
||||
let (points, points_low) = points_to_ds(arc_pts);
|
||||
out.push(WireModel {
|
||||
bg_adapt: None,
|
||||
point_marker: None,
|
||||
@@ -238,8 +264,8 @@ fn split_mixed_polyline(
|
||||
dash_align_end: None,
|
||||
text_verts: Vec::new(),
|
||||
name: name.to_string(),
|
||||
points: Vec::new(),
|
||||
points_low: Vec::new(),
|
||||
points,
|
||||
points_low,
|
||||
color,
|
||||
selected,
|
||||
pattern_length,
|
||||
|
||||
Reference in new issue
Block a user