Concepts and Hierarchies¶
Concepts are the abstract building blocks of your data model. They represent entities that exist only through their instances (keys).
Basic Concepts¶
A concept declares an abstract entity from your domain:
// From Graph Editor: Three independent concepts
concept Graph;
concept Vertex;
concept Edge;
These concepts have no concrete implementation—only their keys exist at runtime:
# Python: Creating concept instances
vertex_key = Graph_VertexKey.create()
print(vertex_key.instance_id()) # fc472756-8f9e-42aa-a06f-051d330d0108
Concept Inheritance¶
Concepts can form hierarchies using is a:
// From Raptor Editor: Material hierarchy
concept Material;
concept MaterialStandard is a Material;
concept MaterialMultilayer is a Material;
concept MaterialMirror is a Material;
concept MaterialMatte is a Material;
concept MaterialEnvironment is a Material;
concept MaterialSeam is a Material;
concept MaterialAxfCpa2 is a Material;
This hierarchy enables polymorphism: a key<Material> can reference any
material subtype.
Light Hierarchy Example¶
// From Raptor Editor: Light types
concept Light;
concept LightSpot is a Light;
concept LightOmni is a Light;
concept LightSun is a Light;
concept LightSky is a Light;
concept LightAreaPlane is a Light;
concept LightAreaCylinder is a Light;
concept LightAreaMesh is a Light;
Each light type has its own properties structure:
// Base properties (all lights have these)
struct LightProperties {
string name;
bool enabled = true;
Vector color = {1.0, 1.0, 1.0};
float intensity = 1.0;
Vector position = {0.0, 0.1, 0.0};
Vector orientation;
};
// Spot-specific properties
struct LightSpotProperties {
float diameter = 0.05;
Vector target = {0.0, 0.0, 1.0};
float falloff = 45.0; // Degrees
float hotSpot = 43.0; // Degrees
LightShadow shadow;
LightAttenuation attenuation;
};
// Area light properties
struct LightAreaPlaneProperties {
float width = 1.0; // Meters
float height = 1.0; // Meters
LightShadow shadow;
LightAttenuation attenuation;
};
Multi-level Hierarchies¶
Hierarchies can have multiple levels:
// From Raptor Editor: Environment generator hierarchy
concept EnvironmentGenerator;
concept EnvironmentGeneratorHdrls is a EnvironmentGenerator;
concept EnvironmentGeneratorLocal is a EnvironmentGenerator;
// From Raptor Editor: Kinematics node hierarchy
concept KinematicsNode;
concept KinematicsNodeAxis is a KinematicsNode;
concept KinematicsNodeNull is a KinematicsNode;
concept KinematicsNodeVector is a KinematicsNode;
// Kinematics constraint hierarchy
concept KinematicsConstraint;
concept KinematicsConstraintCopyOrientation is a KinematicsConstraint;
concept KinematicsConstraintCopyPosition is a KinematicsConstraint;
concept KinematicsConstraintFollowPath is a KinematicsConstraint;
concept KinematicsConstraintLookAt is a KinematicsConstraint;
Key Polymorphism¶
Keys respect the inheritance hierarchy:
// A structure that accepts any material
struct MaterialAssignment {
key<Material> materialKey; // Can hold any material subtype
Transform transform;
int8 uvSet;
};
At runtime, the generated code provides type-safe conversions between parent and child keys:
# Generated code from red/data.py
# Parent key can try to convert to a specific child (returns None if not that type)
light_key = Raptor_LightKey.create()
spot_key = light_key.to_raptor_light_spot_key() # -> Raptor_LightSpotKey | None
# Child key can convert to parent key
spot_key = Raptor_LightSpotKey.create()
parent_key = spot_key.to_parent_key() # -> Raptor_LightKey
# Parent key can be constructed from any child key
omni_key = Raptor_LightOmniKey.create()
light_key = Raptor_LightKey.from_raptor_light_omni_key(omni_key) # -> Raptor_LightKey
Concept vs Club¶
Aspect |
Concept Hierarchy |
Club |
|---|---|---|
Relationship |
“is a” (inheritance) |
“member of” (grouping) |
Use case |
Related types with shared semantics |
Unrelated types with shared usage |
Example |
|
|
Membership |
Single parent |
Multiple clubs allowed |
A concept can be a member of multiple clubs:
RuntimeId Generation¶
Each concept receives a unique RuntimeId computed deterministically from its definition within its namespace. This means:
The same concept definition always produces the same RuntimeId
Different namespaces produce different RuntimeIds even for identically-named concepts
RuntimeIds enable type-safe serialization and persistence
namespace Graph {27c49329-a399-415c-baf0-db42949d2ba2} {
concept Vertex; // RuntimeId computed from namespace UUID + "Vertex"
};
namespace Other {12345678-1234-1234-1234-123456789abc} {
concept Vertex; // Different RuntimeId (different namespace)
};
What’s Next¶
Attachments - Associate data with concept instances
Function Pools - Define operations on your data model