cadmpeg-ir 0.6.2

CAD data model, validation, diffing, and codec API for cadmpeg.
// SPDX-License-Identifier: Apache-2.0
#![allow(clippy::unwrap_used)]

use crate::examples::unit_cube;
use crate::CadIr;

#[test]
fn appearance_asset_and_binding_round_trip() {
    use crate::appearance::{
        Appearance, AppearanceBinding, AppearanceTarget, BumpMap, TextureMap2d, TextureRef,
    };
    use crate::ids::AppearanceId;
    use crate::scalar::{Angle, FiniteReal, Length};

    let real = |value| FiniteReal::new(value).unwrap();
    let length = |value| Length::new(value).unwrap();
    let mut ir = unit_cube().expect("valid unit cube fixture");
    let body = ir.model.bodies[0].id.clone();
    ir.model.appearances.push(Appearance {
        id: AppearanceId::mint("synthetic:test:appearance#prism-001").expect("valid identity"),
        name: Some("Prism-001".into()),
        asset_guid: Some("visual-guid".into()),
        library_id: None,
        visual_guid: Some("visual-guid".into()),
        physical_token: Some("physical-token".into()),
        schema: Some("GenericSchema".into()),
        category: None,
        base_color: Some(crate::topology::Color::new(0.1, 0.2, 0.3, 1.0).expect("valid color")),
        properties: std::collections::BTreeMap::new(),
        textures: vec![TextureRef {
            asset_guid: "texture-guid".into(),
            slot: "generic_bump_map".into(),
            schema: "BumpMapSchema".into(),
            paths: vec!["cloud/resource/texture.png".into()],
            urn: Some("adsk.raas:asset.name:texture".into()),
            mapping: TextureMap2d {
                map_channel: 1,
                uvw_source: 0,
                u_offset: real(0.25),
                v_offset: real(-0.5),
                u_scale: real(2.0),
                v_scale: real(3.0),
                rotation: Angle::new(std::f64::consts::FRAC_PI_2).unwrap(),
                repeat_u: true,
                repeat_v: false,
                real_world_offset_x: length(12.7),
                real_world_offset_y: length(25.4),
                real_world_scale_x: length(304.8),
                real_world_scale_y: length(609.6),
            },
            bump: Some(BumpMap {
                normal_map: true,
                depth: length(2.54),
                normal_scale: real(0.75),
            }),
        }],
    });
    ir.model.appearance_bindings.push(AppearanceBinding {
        id: "synthetic:test:appearance-binding#0"
            .try_into()
            .expect("valid identity"),
        target: AppearanceTarget::Body(body),
        appearance: AppearanceId::mint("synthetic:test:appearance#prism-001")
            .expect("valid identity"),
        source_entity_id: Some("0_1".into()),
        object_type: Some("Body".into()),
        visible: Some(false),
        channels: std::collections::BTreeMap::new(),
    });
    ir.model.appearance_bindings.push(AppearanceBinding {
        id: "synthetic:test:appearance-binding#edge"
            .try_into()
            .expect("valid identity"),
        target: AppearanceTarget::Edge(ir.model.edges[0].id.clone()),
        appearance: AppearanceId::mint("synthetic:test:appearance#prism-001")
            .expect("valid identity"),
        source_entity_id: Some("0_1".into()),
        object_type: Some("Edge".into()),
        visible: None,
        channels: std::collections::BTreeMap::new(),
    });
    ir.model.appearance_bindings.push(AppearanceBinding {
        id: "synthetic:test:appearance-binding#vertex"
            .try_into()
            .expect("valid identity"),
        target: AppearanceTarget::Vertex(ir.model.vertices[0].id.clone()),
        appearance: AppearanceId::mint("synthetic:test:appearance#prism-001")
            .expect("valid identity"),
        source_entity_id: Some("0_1".into()),
        object_type: Some("Vertex".into()),
        visible: None,
        channels: std::collections::BTreeMap::new(),
    });

    let json = ir.to_canonical_json().unwrap();
    let decoded = CadIr::from_json(&json).unwrap();
    assert_eq!(decoded.model.appearances, ir.model.appearances);
    assert_eq!(
        decoded.model.appearance_bindings,
        ir.model.appearance_bindings
    );
}