1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// SPDX-License-Identifier: Apache-2.0
//! Material and visual-appearance assets plus topology bindings.
use std::collections::BTreeMap;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::ids::{AppearanceId, BodyId, EdgeId, FaceId, VertexId};
use crate::topology::Color;
/// A decoded appearance/material asset.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Appearance {
/// Stable arena id.
pub id: AppearanceId,
/// Display/preset name stored in the source, when present.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
/// Asset GUID stored in the Protein record.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub asset_guid: Option<String>,
/// Visual asset GUID stored in the source, when present.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub visual_guid: Option<String>,
/// Physical-material token stored in the source, when present.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub physical_token: Option<String>,
/// Source schema family, such as `GenericSchema` or `PrismOpaqueSchema`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub schema: Option<String>,
/// Source material classification, when stored in the asset catalog.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub category: Option<String>,
/// Resolved diffuse/albedo color.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_color: Option<Color>,
/// Additional byte-decoded shader scalars keyed by schema property name.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub properties: BTreeMap<String, f64>,
/// Texture assets connected to shader input slots.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub textures: Vec<TextureRef>,
}
/// One texture asset connected to an appearance shader slot.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct TextureRef {
/// Stable source asset GUID.
pub asset_guid: String,
/// Shader property receiving this texture, such as `generic_diffuse`.
pub slot: String,
/// Texture schema family, such as `UnifiedBitmapSchema`.
pub schema: String,
/// Ordered library resource paths stored by the texture asset.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub paths: Vec<String>,
/// External asset-library URN, when present.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub urn: Option<String>,
/// Two-dimensional texture-coordinate mapping.
pub mapping: TextureMap2d,
/// Bump/normal interpretation for a bump texture.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub bump: Option<BumpMap>,
}
/// Neutral two-dimensional texture-coordinate mapping.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct TextureMap2d {
/// Source mapping channel.
pub map_channel: u32,
/// Source UVW mapping mode.
pub uvw_source: u32,
/// U-coordinate offset.
pub u_offset: f64,
/// V-coordinate offset.
pub v_offset: f64,
/// U-coordinate scale.
pub u_scale: f64,
/// V-coordinate scale.
pub v_scale: f64,
/// Counterclockwise texture rotation in radians.
pub rotation: f64,
/// Whether the texture repeats along U.
pub repeat_u: bool,
/// Whether the texture repeats along V.
pub repeat_v: bool,
/// Real-world X offset in millimetres.
pub real_world_offset_x: f64,
/// Real-world Y offset in millimetres.
pub real_world_offset_y: f64,
/// Real-world X scale in millimetres.
pub real_world_scale_x: f64,
/// Real-world Y scale in millimetres.
pub real_world_scale_y: f64,
}
/// Bump-map interpretation and amplitudes.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct BumpMap {
/// Whether the bitmap stores tangent-space normals instead of heights.
pub normal_map: bool,
/// Height-map depth in millimetres.
pub depth: f64,
/// Unitless normal-map amplitude.
pub normal_scale: f64,
}
/// A topology entity which receives an appearance.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind", content = "id", rename_all = "snake_case")]
pub enum AppearanceTarget {
/// Whole-body appearance.
Body(BodyId),
/// Per-face appearance override.
Face(FaceId),
/// Per-edge line appearance.
Edge(EdgeId),
/// Per-vertex point appearance.
Vertex(VertexId),
/// Standalone surface geometry appearance.
Surface(crate::ids::SurfaceId),
/// Standalone curve geometry appearance.
Curve(crate::ids::CurveId),
/// Standalone point geometry appearance.
Point(crate::ids::PointId),
/// Tessellated geometry appearance.
Tessellation(String),
/// Native presentation carrier without a neutral geometry arena.
Source {
/// Native source entity identity.
source_id: String,
},
}
/// An explicit appearance assignment.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct AppearanceBinding {
/// Globally unique deterministic assignment identity.
pub id: String,
/// Assigned topology entity.
pub target: AppearanceTarget,
/// Referenced appearance asset.
pub appearance: AppearanceId,
/// Fusion design-entity id, such as `0_985`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_entity_id: Option<String>,
/// Design `MetaStream` object type, such as `Body`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub object_type: Option<String>,
/// ACT change-version channel GUIDs for this assigned entity.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub channels: BTreeMap<String, String>,
}