GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
70 / 70
100.0%
Branches:
11 / 20
55.0%
Functions:
58 / 58
100.0%

scene/schema/geom.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file geom.h
3 /// @brief UsdGeom's base schemas, groupings and implicit shapes.
4 ///
5 /// References:
6 /// - Pixar, UsdGeom, https://openusd.org/release/api/usd_geom_page_front.html
7 #pragma once
8
9 #include "ernie/scene/tokens.h"
10 #include "ernie/scene/view.h"
11
12 #include <array>
13 #include <span>
14 #include <string>
15 #include <string_view>
16 #include <vector>
17
18 // clang-format off
19 #define ERNIE_IMAGEABLE_ATTRIBUTES(X) \
20 X(std::string, Visibility, "visibility", "inherited", \
21 "\"invisible\" hides the prim and its descendants.", \
22 .group = "Prim", .options = {tokens::kInherited, tokens::kInvisible}, \
23 .dirty = Dirty::Visibility, .inherited = true) \
24 X(std::string, Purpose, "purpose", "default", \
25 "Which renders include it and its descendants: default, render, proxy or guide.", \
26 .group = "Prim", \
27 .options = {tokens::kDefault, tokens::kRender, tokens::kProxy, tokens::kGuide}, \
28 .dirty = Dirty::Visibility, .inherited = true) \
29 X(int, World, "ernie:world", -1, \
30 "The batch world the prim and its descendants are in; -1 for every world.", \
31 .group = "Prim", .lower = AtLeast(-1.0), .dirty = Dirty::Visibility, .inherited = true)
32
33 #define ERNIE_XFORMABLE_ATTRIBUTES(X) \
34 X(std::vector<std::string>, XformOpOrder, "xformOpOrder", std::vector<std::string>{}, \
35 "The xformOp attributes composing the local transform, outermost first.", \
36 .group = "Transform", .dirty = Dirty::Transform)
37
38 #define ERNIE_BOUNDABLE_ATTRIBUTES(X) \
39 X(std::vector<float>, Extent, "extent", std::vector<float>{}, \
40 "Authored local bounds (min x, y, z, max x, y, z), read until the geometry is available.", \
41 .group = "Geometry")
42
43 #define ERNIE_GPRIM_ATTRIBUTES(X) \
44 X(glm::dvec3, DisplayColor, "primvars:displayColor", glm::dvec3(0.5), \
45 "Linear RGB of the whole prim.", .label = "Display colour", .group = "Geometry", \
46 .lower = AtLeast(0.0), .finite = true, .color = true, .dirty = Dirty::Primvars) \
47 X(double, DisplayOpacity, "primvars:displayOpacity", 1.0, "Opacity of the whole prim.", \
48 ERNIE_FRACTION("Geometry"), .dirty = Dirty::Primvars) \
49 X(bool, DoubleSided, "doubleSided", false, "Whether its back faces are seen too.", \
50 .group = "Geometry") \
51 X(std::string, Orientation, "orientation", "rightHanded", \
52 "The winding of its front faces.", .group = "Geometry", \
53 .options = {"rightHanded", "leftHanded"}, .dirty = Dirty::Topology)
54
55 #define ERNIE_CARD_TEXTURE(X, Name, usdName) \
56 X(std::string, Name, usdName, "", "The image on the card facing this way.", .group = "Model", \
57 .asset = true, .dirty = Dirty::Params)
58
59 #define ERNIE_MODEL_API_ATTRIBUTES(X) \
60 X(std::string, DrawMode, "model:drawMode", "inherited", \
61 "Draws the subtree as itself, or as a stand-in: its origin axes, its bounds or cards.", \
62 .group = "Model", .options = {"origin", "bounds", "cards", "default", "inherited"}, \
63 .dirty = Dirty::Visibility) \
64 X(bool, ApplyDrawMode, "model:applyDrawMode", false, \
65 "Whether this prim's draw mode replaces its subtree.", .group = "Model", \
66 .dirty = Dirty::Visibility) \
67 X(glm::dvec3, DrawModeColor, "model:drawModeColor", glm::dvec3(0.18), \
68 "Linear RGB of the stand-in.", .group = "Model", .lower = AtLeast(0.0), .color = true, \
69 .dirty = Dirty::Params) \
70 X(std::string, CardGeometry, "model:cardGeometry", "cross", \
71 "Cards through the centre, on the bounds' faces, or as the textures place them.", \
72 .group = "Model", .options = {"cross", "box", "fromTexture"}, .dirty = Dirty::Params) \
73 X(std::string, CardVisibility, "model:cardVisibility", "inherited", \
74 "Every textured card, or only one per axis.", .group = "Model", \
75 .options = {"full", "simple", "inherited"}, .dirty = Dirty::Params) \
76 ERNIE_CARD_TEXTURE(X, CardTextureXPos, "model:cardTextureXPos") \
77 ERNIE_CARD_TEXTURE(X, CardTextureYPos, "model:cardTextureYPos") \
78 ERNIE_CARD_TEXTURE(X, CardTextureZPos, "model:cardTextureZPos") \
79 ERNIE_CARD_TEXTURE(X, CardTextureXNeg, "model:cardTextureXNeg") \
80 ERNIE_CARD_TEXTURE(X, CardTextureYNeg, "model:cardTextureYNeg") \
81 ERNIE_CARD_TEXTURE(X, CardTextureZNeg, "model:cardTextureZNeg") \
82 X(std::vector<float>, ExtentsHint, "extentsHint", std::vector<float>{}, \
83 "The subtree's local bounds per purpose (default, render, proxy, guide), six floats each, " \
84 "read while it isn't loaded.", .group = "Model")
85
86 #define ERNIE_SUBSET_ATTRIBUTES(X) \
87 X(std::string, ElementType, "elementType", "face", "What its indices count.", \
88 .group = "Subset", .options = {"face", "point", "edge", "segment", "tetrahedron"}, \
89 .dirty = Dirty::Topology) \
90 X(Tensor, Indices, "indices", Tensor(), "The elements in the subset.", .group = "Subset", \
91 .integer = true, .dirty = Dirty::Topology) \
92 X(std::string, FamilyName, "familyName", "", \
93 "The family of subsets it is one of, as materialBind for per-face materials.", \
94 .group = "Subset", .dirty = Dirty::Topology)
95
96 #define ERNIE_SHAPE_LENGTH ERNIE_NONNEGATIVE("Shape")
97
98 #define ERNIE_AXIS_ATTRIBUTE(X) \
99 X(Choice<Axis>, Axis, "axis", Axis::Z, "The axis of its height, or a plane's normal.", \
100 .group = "Shape")
101
102 #define ERNIE_CUBE_ATTRIBUTES(X) \
103 X(double, Size, "size", 2.0, "Edge length, metres.", ERNIE_SHAPE_LENGTH)
104
105 #define ERNIE_SPHERE_ATTRIBUTES(X) \
106 X(double, Radius, "radius", 1.0, "Metres.", ERNIE_SHAPE_LENGTH)
107
108 #define ERNIE_CYLINDER_ATTRIBUTES(X) \
109 X(double, Radius, "radius", 1.0, "Metres.", ERNIE_SHAPE_LENGTH) \
110 X(double, Height, "height", 2.0, "Metres along the axis.", ERNIE_SHAPE_LENGTH) \
111 ERNIE_AXIS_ATTRIBUTE(X)
112
113 #define ERNIE_CAPSULE_ATTRIBUTES(X) \
114 X(double, Radius, "radius", 0.5, "Metres, of the cylinder and its end caps.", \
115 ERNIE_SHAPE_LENGTH) \
116 X(double, Height, "height", 1.0, "Metres along the axis between the caps.", \
117 ERNIE_SHAPE_LENGTH) \
118 ERNIE_AXIS_ATTRIBUTE(X)
119
120 #define ERNIE_PLANE_ATTRIBUTES(X) \
121 X(double, Width, "width", 2.0, "Metres along x, or z when the axis is X.", ERNIE_SHAPE_LENGTH) \
122 X(double, Length, "length", 2.0, "Metres along y, or z when the axis is Y.", \
123 ERNIE_SHAPE_LENGTH) \
124 ERNIE_AXIS_ATTRIBUTE(X)
125 // clang-format on
126
127 namespace ernie {
128
129 /// @return A Boundable's authored `extent` (min x, y, z, max x, y, z), which extent functions
130 /// read while the data they bound isn't on the host; empty when unset.
131 6 inline Box AuthoredExtent(std::span<const float> extent) {
132
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (extent.size() != 6) {
133 2 return {};
134 }
135 4 return {{extent[0], extent[1], extent[2]}, {extent[3], extent[4], extent[5]}};
136 }
137
138 enum class Axis { X, Y, Z };
139
140 template <> struct ChoiceTokens<Axis> {
141 static constexpr std::array<std::string_view, 3> kTokens{"X", "Y", "Z"};
142 };
143
144 1260 ERNIE_SCHEMA(Imageable, SchemaView, ERNIE_IMAGEABLE_ATTRIBUTES,
145 "What every prim has: visibility, purpose and the world it is in.");
146
6/12
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 24 taken 1 time.
✗ Branch 25 not taken.
✓ Branch 36 taken 3 times.
✗ Branch 37 not taken.
4779 ERNIE_SCHEMA(Xformable, Imageable, ERNIE_XFORMABLE_ATTRIBUTES,
147 "What has a transform, composed from its xformOps.");
148 4401 ERNIE_SCHEMA(Boundable, Xformable, ERNIE_BOUNDABLE_ATTRIBUTES,
149 "What has an extent in its own space, computed from its attributes.");
150
1/2
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
4520 ERNIE_SCHEMA(Gprim, Boundable, ERNIE_GPRIM_ATTRIBUTES,
151 "Geometry, drawn in a display colour or with a bound material.");
152 62 ERNIE_CONCRETE_SCHEMA(Xform, Xformable, ERNIE_NO_ATTRIBUTES, "A transform grouping its children.");
153 ERNIE_CONCRETE_SCHEMA(Scope, Imageable, ERNIE_NO_ATTRIBUTES,
154 "A grouping without a transform of its own.");
155
2/4
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 7 not taken.
4 ERNIE_API_SCHEMA(GeomModelAPI, ERNIE_MODEL_API_ATTRIBUTES,
156 "A model's stand-ins and the bounds hint used while its subtree isn't loaded.");
157 5 ERNIE_CONCRETE_SCHEMA(GeomSubset, SchemaView, ERNIE_SUBSET_ATTRIBUTES,
158 "Some faces, points, edges, segments or tetrahedra of its parent, to bind a "
159 "material to or select.");
160 23 ERNIE_CONCRETE_SCHEMA(Cube, Gprim, ERNIE_CUBE_ATTRIBUTES,
161 "A box centred on its origin, size along each axis.");
162 2937 ERNIE_CONCRETE_SCHEMA(Sphere, Gprim, ERNIE_SPHERE_ATTRIBUTES, "A sphere centred on its origin.");
163 15 ERNIE_CONCRETE_SCHEMA(Cylinder, Gprim, ERNIE_CYLINDER_ATTRIBUTES,
164 "A capped cylinder along its axis.");
165 3 ERNIE_CONCRETE_SCHEMA(Cone, Gprim, ERNIE_CYLINDER_ATTRIBUTES,
166 "A capped cone along its axis, its apex at +height / 2.");
167 3 ERNIE_CONCRETE_SCHEMA(Capsule, Gprim, ERNIE_CAPSULE_ATTRIBUTES,
168 "A cylinder with hemispherical caps along its axis.");
169 4 ERNIE_CONCRETE_SCHEMA(Plane, Gprim, ERNIE_PLANE_ATTRIBUTES,
170 "A one-sided rectangle facing along its axis.");
171
172 } // namespace ernie
173