diff --git a/crates/smlib/src/core.rs b/crates/smlib/src/core.rs index f1c3676525..596f3f2eac 100644 --- a/crates/smlib/src/core.rs +++ b/crates/smlib/src/core.rs @@ -59,6 +59,7 @@ pub(crate) fn fixes() -> UpstreamFixes { f.fillet_refuse_face_consuming_blends = true; f.fillet_refuse_non_manifold_result = true; f.fillet_refuse_crossing_rails = true; + f.fillet_vertex_error_diagnostics = true; f.fillet_corner_ball_patch = true; f.fillet_chamfer_cone_on_arc = true; f.fillet_torus_center_on_axis = true; @@ -138,6 +139,7 @@ pub(crate) fn fixes() -> UpstreamFixes { f.corner_blend_stays_inside_neighbours = true; f.fillet_cleanup_keeps_target_faces = true; f.fillet_nx1_tangent_side_edge = true; + f.fillet_3x2_mixed_concave_side_edge = true; f.offset_closed_curve_trim_arc = true; f.offset_stitch_at_body_tolerance = true; f.curve_contacts_at_curve_ends = true; @@ -147,6 +149,7 @@ pub(crate) fn fixes() -> UpstreamFixes { f.sphere_small_circle_not_touching = true; f.ssi_tangent_contact_points = true; f.ssi_trace_tangent_curves_once = true; + f.ssi_singular_start_inside_direction = true; f.found_torus_sphere_keep_tested_nurb = true; f } diff --git a/crates/smlib/src/core/convert.rs b/crates/smlib/src/core/convert.rs index 96fdb2eca2..3cd08a5915 100644 --- a/crates/smlib/src/core/convert.rs +++ b/crates/smlib/src/core/convert.rs @@ -11,9 +11,8 @@ //! from the edges' and vertices' own ([`own_tolerances`]). Each entity keeps its tolerance across //! the kernels instead of every one taking the largest at each crossing. //! -//! Where solidcore has no port of an SMLib call the C++ makes, the conversion fails with -//! "not supported yet" naming the call: `SmSurface::ApproximateSurface` (a face whose surface is -//! not a B-spline kind). +//! A face whose surface is not a B-spline kind (an offset) exports its approximation, as +//! `FlatFromBrep` does (`SmSurface::ApproximateSurface`). //! //! [`from_arrays`] also runs the capi's `PutEnclosingShellsFirst` ([`put_enclosing_shells_first`], //! an addition to SmuConvert): a bounded region of several shells starts its list at the shell @@ -34,6 +33,7 @@ use solidcore::geom::axis2_placement::Axis2Placement; use solidcore::geom::extent1d::Extent1d; use solidcore::geom::extent2d::Extent2d; use solidcore::geom::object::ObjectRef; +use solidcore::geom::tol::approx_tol3d; use solidcore::nurbs::b_spline_curve::{BSplineCurve, BSplineCurveForm, CanonicalData, KnotType}; use solidcore::nurbs::b_spline_surface::{BSplineSurface, BSplineSurfaceForm, CanonicalSurfaceData}; use solidcore::nurbs::crv_basic::Curve as NurbCurve; @@ -75,11 +75,6 @@ fn bad(what: &str) -> Error { Error::Solidcore(format!("flat arrays: {what}")) } -/// A call solidcore has no port of. -fn unported(call: &str) -> Error { - Error::Solidcore(format!("not supported yet: solidcore has no {call}")) -} - fn get(v: &[T], i: usize) -> Result { v.get(i).copied().ok_or_else(|| bad("index past its array")) } @@ -975,8 +970,21 @@ fn flat_from_brep(k: &mut Kernel, b: &mut Brep) -> Result { } if nurbs_form || ty == SURFACE_NURBS_I { // Every analytic class is an SmBSplineSurface: its own NURBS, in face order with the - // NURBS faces' surfaces. Another surface would be approximated (ApproximateSurface). - let part = bspline_surface_part(k, surface)?.ok_or_else(|| unported("SmSurface::ApproximateSurface"))?; + // NURBS faces' surfaces. Another surface (an offset) is approximated within the + // curves' tolerance, splitting its spans up to 5 times; its status fails the export, + // as does no surface, which would leave the arrays without this face's NURBS. + let approximated; + let part = match bspline_surface_part(k, surface)? { + Some(part) => part, + None => { + approximated = surface + .approximate_surface(k, approx_tol3d(k, approx_tol), 5, true) + .map_err(sc("SmSurface::ApproximateSurface"))? + .surface + .ok_or_else(|| bad("a face surface SMLib could not convert to a B-spline"))?; + bspline_surface_part(k, &approximated)?.ok_or_else(|| bad("an approximated face surface that is not a B-spline"))? + } + }; add_bspline_surface(&mut o, part.gw_nurb().ok_or_else(|| bad("a B-spline surface without its NURB"))?)?; } } diff --git a/crates/smlib/src/core/offset_tests.rs b/crates/smlib/src/core/offset_tests.rs index e1b26ddc72..6662e7f6fb 100644 --- a/crates/smlib/src/core/offset_tests.rs +++ b/crates/smlib/src/core/offset_tests.rs @@ -409,7 +409,7 @@ cases!( thicken_plate_symmetric, thicken_a_solid, offset_sheet_plate, - offset_sheet_quarter_cylinder: ignore = "solidcore#1441: an offset surface does not export, no SmSurface::ApproximateSurface (solidcore#1441)", + offset_sheet_quarter_cylinder: ignore = "solidcore#1477: the quarter arc sweeps to an SmSurfOfExtrusion, whose offset exports as a spline, where the fork's 12918e9 sweeps an SmCylinder (solidcore#1477)", offset_sheet_a_solid, offset_faces_top_out: ignore = "no SmOffsetFacesExecutive, fork a96ce9f (solidcore#1060)", offset_faces_through,