Another project
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 3.4 kB View raw
1use bone_kernel::{ 2 BrepSolid, Curve2Kind, ExtrudeDirection, ExtrudeEndCondition, ExtrudeFeature, ExtrudeProfile, 3 ExtrudeSense, Line2, MergeResult, ProfileEdge, ProfileLoop, evaluate_extrude, 4}; 5use bone_render::{SolidRenderer, SolidScene, Style, frame_isometric}; 6use bone_types::{ 7 AngleTolerance, ChordHeightTolerance, FeatureId, Length, Plane3, Point2, Point3, 8 PositiveLength, SketchEntityId, SketchId, Tolerance, UnitVec3, millimeter, 9}; 10use slotmap::{Key, SlotMap}; 11 12mod common; 13 14use common::{check_golden, extent_square as extent, make_context}; 15 16const GOLDEN: &str = "tests/goldens/cube_iso_256.png"; 17const UPDATE_ENV: &str = "BONE_UPDATE_CUBE_ISO_GOLDEN"; 18const TOLERANCE: Tolerance = Tolerance::new(1.0e-9); 19 20fn unit_cube() -> BrepSolid { 21 let mut entities: SlotMap<SketchEntityId, ()> = SlotMap::with_key(); 22 let mut features: SlotMap<FeatureId, ()> = SlotMap::with_key(); 23 let Ok(plane) = Plane3::new( 24 Point3::origin(), 25 UnitVec3::x_axis(), 26 UnitVec3::y_axis(), 27 TOLERANCE, 28 ) else { 29 panic!("x and y axes are orthonormal"); 30 }; 31 let corners = [ 32 Point2::from_mm(0.0, 0.0), 33 Point2::from_mm(1.0, 0.0), 34 Point2::from_mm(1.0, 1.0), 35 Point2::from_mm(0.0, 1.0), 36 ]; 37 let edges = (0..4) 38 .map(|index| { 39 let start = corners[index]; 40 let end = corners[(index + 1) % 4]; 41 let Ok(segment) = Line2::new(start, end, TOLERANCE) else { 42 panic!("rectangle endpoints are distinct"); 43 }; 44 ProfileEdge::new( 45 Curve2Kind::Line(segment), 46 entities.insert(()), 47 entities.insert(()), 48 ) 49 }) 50 .collect(); 51 let profile = ExtrudeProfile::new(plane, vec![ProfileLoop::Open(edges)]); 52 let Ok(depth) = PositiveLength::new(Length::new::<millimeter>(1.0)) else { 53 panic!("1 mm is a positive length"); 54 }; 55 let feature = ExtrudeFeature { 56 sketch: SketchId::null(), 57 direction: ExtrudeDirection::Normal { 58 sense: ExtrudeSense::Forward, 59 }, 60 end_condition: ExtrudeEndCondition::Blind { depth }, 61 draft: None, 62 thin_wall: None, 63 merge_result: MergeResult::Merge, 64 }; 65 let Ok(solid) = evaluate_extrude(features.insert(()), &profile, &feature) else { 66 panic!("the unit square extrudes into a cube"); 67 }; 68 solid 69} 70 71#[test] 72fn cube_iso_matches_golden() { 73 let size = extent(256); 74 let ctx = make_context(size); 75 let mut renderer = SolidRenderer::new(ctx.gpu(), ctx.color_format()); 76 let solid = unit_cube(); 77 let Ok(mesh) = solid.tessellate( 78 ChordHeightTolerance::from_mm(0.05), 79 AngleTolerance::from_radians(0.2), 80 ) else { 81 panic!("the cube tessellates"); 82 }; 83 let Ok(scene) = SolidScene::from_mesh(&mesh) else { 84 panic!("the cube mesh packs face pick ids"); 85 }; 86 let Some(aabb) = solid.bounding_box() else { 87 panic!("the cube has a bounding box"); 88 }; 89 let Ok(camera) = frame_isometric(aabb, size) else { 90 panic!("the cube frames isometrically"); 91 }; 92 let style = Style::default(); 93 94 let Ok(frame) = renderer.render(&ctx, &scene, camera, &style) else { 95 panic!("SolidRenderer::render failed"); 96 }; 97 98 check_golden(&frame, GOLDEN, UPDATE_ENV); 99}