Skip to main content

cadmpeg_ir/
subd.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Subdivision-surface control cages.
3
4use crate::ids::SubdId;
5use crate::math::Point3;
6use crate::provenance::SourceObjectAssociation;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9
10/// A subdivision surface represented by its control cage.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
12pub struct SubdSurface {
13    /// Arena identity.
14    pub id: SubdId,
15    /// Subdivision scheme.
16    pub scheme: SubdScheme,
17    /// Control-cage vertices.
18    pub vertices: Vec<SubdVertex>,
19    /// Control-cage edges.
20    pub edges: Vec<SubdEdge>,
21    /// Control-cage faces.
22    pub faces: Vec<SubdFace>,
23    /// Native source-object identity and effective display metadata.
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub source_object: Option<SourceObjectAssociation>,
26}
27
28/// Subdivision scheme used by a control cage.
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
30#[serde(rename_all = "snake_case")]
31pub enum SubdScheme {
32    /// Catmull-Clark subdivision.
33    CatmullClark,
34}
35
36/// A control-cage vertex and its subdivision tag.
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
38pub struct SubdVertex {
39    /// Vertex position.
40    pub point: Point3,
41    /// Subdivision vertex tag.
42    pub tag: SubdVertexTag,
43}
44
45/// A control-cage vertex tag.
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
47#[serde(rename_all = "snake_case")]
48pub enum SubdVertexTag {
49    /// Smooth vertex.
50    Smooth,
51    /// Crease vertex.
52    Crease,
53    /// Corner vertex.
54    Corner,
55    /// Dart vertex.
56    Dart,
57}
58
59/// A control-cage edge with endpoint sharpness and sector coefficients.
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
61pub struct SubdEdge {
62    /// Indices of the two distinct endpoint vertices.
63    pub vertices: [u32; 2],
64    /// Sharpness at the start and end endpoints.
65    pub sharpness: [f64; 2],
66    /// Subdivision edge tag.
67    pub tag: SubdEdgeTag,
68    /// Sector coefficients at the two endpoints.
69    pub sector_coefficients: [f64; 2],
70}
71
72/// A control-cage edge tag.
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
74#[serde(rename_all = "snake_case")]
75pub enum SubdEdgeTag {
76    /// Smooth edge.
77    Smooth,
78    /// Smooth-X edge with the source's distinct subdivision behavior.
79    SmoothX,
80    /// Crease edge.
81    Crease,
82}
83
84/// A subdivision face bounded by a directed edge ring.
85#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
86pub struct SubdFace {
87    /// Ordered directed edge uses forming the face boundary.
88    pub edges: Vec<SubdEdgeUse>,
89}
90
91/// One directed use of a subdivision edge in a face ring.
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
93pub struct SubdEdgeUse {
94    /// Index into the parent surface's edge array.
95    pub edge: u32,
96    /// Whether this use traverses the edge from its second endpoint.
97    pub reversed: bool,
98}