Drake
GeometryProperties Class Reference

Detailed Description

The base class for defining a set of geometry properties.

Each property consists of a (group, property) name-pair and a typed value. The name pair allows for reuse of common property names (e.g., "diffuse") to be differentiated in interpretation by associating them with different groups. The only restriction on the value type is that it must be either cloneable or copy-constructible.

A set of geometry property values are defined when geometry is registered with SceneGraph by an instantiator and accessed by some downstream consumer entity. Each consumer specifies what properties it expects to find and what default values (if any) it provides. For example, the consumer could document that a particular property is always required and its absence would throw an exception. Alternatively, it could indicate that a property is optional and a default value will be used in its absence. It is the responsibility of the instantiator to make sure that the geometry property values are correctly defined according to the expected consumer's specification. Correctness includes such issues as key-value pairs placed into a correctly-spelled group, property keys being likewise correctly spelled, and values of the expected type. Correct spelling includes correct case. The instantiator uses the AddProperty() method to add new properties to the set.

To read the property (some_group, some_property) from a property set:

  1. Optionally test to see if the property exists by confirming the group some_group is in the set via HasGroup() and that the property some_property is in some_group via HasProperty(). Attempting to access a property with a non-existent (group, property) pair may lead to an exception (see API documentation below).
  2. Acquire a property value via the GetProperty() or GetPropertyOrDefault() methods. NOTE: Reading a property requires a compile-time declaration of the type of value being read. If the stored value is of a different type, an exception will be thrown.

Common workflows

The following examples outline a number of ways to create and consume geometry properties. By design, GeometryProperties cannot be constructed, copied, or moved directly. Only derived classes can do so. This facilitates strongly typed sets of properties associated with particular geometry roles. So, for these examples we'll exercise the derived class associated with proximity queries: ProximityProperties.

The string-based structure of GeometryProperties provides a great deal of flexibility at the cost of spelling sensitivity. It would be easy to introduce typos that would then "hide" property values in some group a consumer wouldn't look. In these examples, we avoid using string literals as group or property names (at least in the cases where the same name is used multiple times) to help avoid the possibility of typo-induced errors. That is not required and certainly not the only way to avoid such bugs.

Creating properties

Creating properties in a new group

This is a simple example in which a single group is added with properties of various types.

const std::string group_name("my_group");
ProximityProperties properties;
// This first invocation implicitly creates the group "my_group".
properties.AddProperty(group_name, "count", 7); // int type
properties.AddProperty(group_name, "length", 7.); // double type
properties.AddProperty(group_name, "name", "7"); // std::string type

Creating properties in the default group

Similar to the previous examples, the properties are added to the default group. Just be aware that if multiple sites in your code add properties to the default group, the possibility that names get repeated increases. Property names must be unique within a single group, including the default group.

ProximityProperties properties;
properties.AddProperty(ProximityProperties::default_group_name(), "count", 7);
properties.AddProperty(ProximityProperties::default_group_name(), "width", 7.);
properties.AddProperty(ProximityProperties::default_group_name(), "name", "7");

Aggregate properties in a struct

In some cases, there is a set of values that will always be accessed together (specified with coordinated semantics). In these cases, it makes sense to aggregate them into a struct and store that as a single value. This reduces the number of lookups required.

It's worth noting, that if the data value is a struct, calls to GetPropertyOrDefault() still operate as an "all-or-nothing" basis. If the property struct exists, it will be returned, if it's missing the default struct will be returned. There is no concept of a "partial" struct in which some undefined values in the struct will be replaced with their corresponding values in the default struct.

struct MyData {
int i{};
double d{};
std::string s;
};
ProximityProperties properties;
const std::string group_name("my_group");
MyData data{7, 7., "7"};
properties.AddProperty(group_name, "data1", data);
// These alternate forms are also acceptable (but not in succession, as the
// property name has already been used by the first invocation).
properties.AddProperty(group_name, "data2", MyData{6, 6., "6"});
properties.AddProperty<MyData>(group_name, "data2", {6, 6., "6"});

Reading properties

This section describes how to read properties under several different scenarios: (a) when specific properties are required, (b) when the consumer provides a default value for missing properties, and (c) when the consumer needs to inspect what properties are available.

Look up specific, required properties

In this case, the consumer of the properties is looking for one or more specific properties. It will ignore any other properties. More particularly, if those properties are missing, it is considered a runtime error and an exception is thrown.

The error can be handled in one of two ways: simply let the generic exception generated by GeometryProperties propagate upward, or detect the missing property and throw an exception with a custom message. The example below shows both approaches.

const IllustrationProperties& properties = FunctionThatReturnsProperties();
// Looking for a Rgba of rgba colors named "rgba" - send generic error that
// the property set is missing the required property.
const Rgba rgba =
properties.GetProperty<Rgba>("MyGroup", "rgba");
// Explicitly detect missing property and throw exception with custom message.
if (!properties.HasProperty("MyGroup", "rgba")) {
throw std::logic_error(
"ThisClass: Missing the necessary 'rgba' property; the object cannot be "
"rendered");
}
// Otherwise acquire value, confident that no exception will be thrown.
const Rgba rgba =
properties.GetProperty<Rgba>("MyGroup", "rgba");
Note
calls to GetProperty() always require the return type template value (e.g., Rgba) to be specified in the call.

Look up specific properties with default property values

As with the previous case, the consumer is looking for one or more specific properties. However, in this case, the consumer provides a default value to use in case the target property is not defined. In this invocation, the template parameter need not be explicitly declared – the inferred return type will be the same as the default value.

const IllustrationProperties& properties = FunctionThatReturnsProperties();
// Looking for a Rgba of rgba colors named "rgba".
const Rgba default_color{0.9, 0.9, 0.9};
const Rgba rgba =
properties.GetPropertyOrDefault("MyGroup", "rgba", default_color);

Alternatively, the default value can be provided in one of the following forms:

properties.GetPropertyOrDefault("MyGroup", "rgba",
Rgba{0.9, 0.9, 0.9});
properties.GetPropertyOrDefault<Rgba>("MyGroup", "rgba",
{0.9, 0.9, 0.9});

Iterating through provided properties

Another alternative is to iterate through the properties that have been provided. This might be done for several reasons, e.g.:

  • the consumer wants to validate the set of properties, giving the user feedback if an unsupported property has been provided, and/or
  • the consumer has a default value for every property and allows the registering code to define only those properties that deviate from the specified default.

Working with properties in this manner requires knowledge of how to work with AbstractValue.

const IllustrationProperties& properties = FunctionThatReturnsProperties();
for (const auto& pair : properties.GetGroupProperties("MyGroup") {
const std::string& name = pair.first;
if (name == "rgba") {
// Throws an exception if the named parameter is of the wrong type.
const Rgba& rgba =
pair.second->GetValueOrThrow<Rgba>();
}
}

#include <drake/geometry/geometry_properties.h>

Public Types

using Group = std::unordered_map< std::string, copyable_unique_ptr< AbstractValue > >
 The properties for a single group as a property name-value map. More...
 

Public Member Functions

virtual ~GeometryProperties ()=default
 
bool HasGroup (const std::string &group_name) const
 Reports if the given named group is part of this property set. More...
 
int num_groups () const
 Reports the number of property groups in this set. More...
 
const GroupGetPropertiesInGroup (const std::string &group_name) const
 Retrieves the indicated property group. More...
 
std::set< std::string > GetGroupNames () const
 Returns all of the defined group names. More...
 
template<typename ValueType >
void AddProperty (const std::string &group_name, const std::string &name, const ValueType &value)
 Adds the named property (group_name, name) with the given value. More...
 
template<typename ValueType >
void UpdateProperty (const std::string &group_name, const std::string &name, const ValueType &value)
 Updates the named property (group_name, name) with the given value. More...
 
void AddPropertyAbstract (const std::string &group_name, const std::string &name, const AbstractValue &value)
 Adds the named property (group_name, name) with the given type-erased value. More...
 
void UpdatePropertyAbstract (const std::string &group_name, const std::string &name, const AbstractValue &value)
 Updates the named property (group_name, name) with the given type-erased value. More...
 
bool HasProperty (const std::string &group_name, const std::string &name) const
 Reports if the property (group_name, name) exists in the group. More...
 
template<typename ValueType >
decltype(auto) GetProperty (const std::string &group_name, const std::string &name) const
 Retrieves the typed value for the property (group_name, name) from this set of properties. More...
 
const AbstractValueGetPropertyAbstract (const std::string &group_name, const std::string &name) const
 Retrieves the type-erased value for the property (group_name, name) from this set of properties. More...
 
template<typename ValueType >
ValueType GetPropertyOrDefault (const std::string &group_name, const std::string &name, ValueType default_value) const
 Retrieves the typed value for the property (group_name, name) from the set of properties (if it exists), otherwise returns the given default value. More...
 
bool RemoveProperty (const std::string &group_name, const std::string &name)
 Removes the (group_name, name) property (if it exists). More...
 

Static Public Member Functions

static const std::string & default_group_name ()
 Returns the default group name. More...
 

Protected Member Functions

 GeometryProperties ()
 Constructs a property set with the default group. More...
 
Implements CopyConstructible, CopyAssignable, MoveConstructible, MoveAssignable
 GeometryProperties (const GeometryProperties &)=default
 
GeometryPropertiesoperator= (const GeometryProperties &)=default
 
 GeometryProperties (GeometryProperties &&)=default
 
GeometryPropertiesoperator= (GeometryProperties &&)=default
 

Friends

std::ostream & operator<< (std::ostream &out, const GeometryProperties &props)
 

Member Typedef Documentation

◆ Group

using Group = std::unordered_map<std::string, copyable_unique_ptr<AbstractValue> >

The properties for a single group as a property name-value map.

Constructor & Destructor Documentation

◆ ~GeometryProperties()

virtual ~GeometryProperties ( )
virtualdefault

◆ GeometryProperties() [1/3]

GeometryProperties ( )
protected

Constructs a property set with the default group.

Only invoked by final subclasses.

◆ GeometryProperties() [2/3]

GeometryProperties ( const GeometryProperties )
protecteddefault

◆ GeometryProperties() [3/3]

GeometryProperties ( GeometryProperties &&  )
protecteddefault

Member Function Documentation

◆ AddProperty()

void AddProperty ( const std::string &  group_name,
const std::string &  name,
const ValueType &  value 
)

Adds the named property (group_name, name) with the given value.

Adds the group if it doesn't already exist.

Parameters
group_nameThe group name.
nameThe name of the property – must be unique in the group.
valueThe value to assign to the property.
Exceptions
std::exceptionif the property already exists.
Template Parameters
ValueTypeThe type of data to store with the attribute – must be copy constructible or cloneable (see Value).

◆ AddPropertyAbstract()

void AddPropertyAbstract ( const std::string &  group_name,
const std::string &  name,
const AbstractValue value 
)

Adds the named property (group_name, name) with the given type-erased value.

Adds the group if it doesn't already exist.

Parameters
group_nameThe group name.
nameThe name of the property – must be unique in the group.
valueThe value to assign to the property.
Exceptions
std::exceptionif the property already exists.

◆ default_group_name()

static const std::string& default_group_name ( )
static

Returns the default group name.

There is no guarantee as to what string corresponds to the default group. Therefore it should always be accessed via this method.

◆ GetGroupNames()

std::set<std::string> GetGroupNames ( ) const

Returns all of the defined group names.

◆ GetPropertiesInGroup()

const Group& GetPropertiesInGroup ( const std::string &  group_name) const

Retrieves the indicated property group.

The returned group is valid for as long as this instance.

Exceptions
std::exceptionif there is no group with the given name.

◆ GetProperty()

decltype(auto) GetProperty ( const std::string &  group_name,
const std::string &  name 
) const

Retrieves the typed value for the property (group_name, name) from this set of properties.

Parameters
group_nameThe name of the group to which the property belongs.
nameThe name of the desired property.
Exceptions
std::exceptionif a) the group name is invalid, b) the property name is invalid, or c) the property type is not that specified.
Template Parameters
ValueTypeThe expected type of the desired property.
Returns
const ValueType& of stored value. If ValueType is Eigen::Vector4d, the return type will be a copy translated from Rgba.

◆ GetPropertyAbstract()

const AbstractValue& GetPropertyAbstract ( const std::string &  group_name,
const std::string &  name 
) const

Retrieves the type-erased value for the property (group_name, name) from this set of properties.

Parameters
group_nameThe name of the group to which the property belongs.
nameThe name of the desired property.
Exceptions
std::exceptionif a) the group name is invalid, or b) the property name is invalid.

◆ GetPropertyOrDefault()

ValueType GetPropertyOrDefault ( const std::string &  group_name,
const std::string &  name,
ValueType  default_value 
) const

Retrieves the typed value for the property (group_name, name) from the set of properties (if it exists), otherwise returns the given default value.

The given default_value is returned only if the property is missing. If the property exists and is of a different type, an exception will be thrown. If it is of the expected type, the stored value will be returned.

Generally, it is unnecessary to explicitly declare the ValueType of the property value; it will be inferred from the provided default value. Sometimes it is convenient to provide the default value in a form that can be implicitly converted to the final type. In that case, it is necessary to explicitly declare the desired ValueType so the compiler does not infer the wrong type, e.g.:

// Note the _integer_ value as default value.
const double my_value = properties.GetPropertyOrDefault<double>("g", "p", 2);
Parameters
group_nameThe name of the group to which the property belongs.
nameThe name of the desired property.
default_valueThe alternate value to return if the property cannot be acquired.
Exceptions
std::exceptionif a property of the given name exists but is not of ValueType.

◆ HasGroup()

bool HasGroup ( const std::string &  group_name) const

Reports if the given named group is part of this property set.

◆ HasProperty()

bool HasProperty ( const std::string &  group_name,
const std::string &  name 
) const

Reports if the property (group_name, name) exists in the group.

Parameters
group_nameThe name of the group to which the tested property should belong.
nameThe name of the property under question.
Returns
true iff the group exists and a property with the given name exists in that group.

◆ num_groups()

int num_groups ( ) const

Reports the number of property groups in this set.

◆ operator=() [1/2]

GeometryProperties& operator= ( GeometryProperties &&  )
protecteddefault

◆ operator=() [2/2]

GeometryProperties& operator= ( const GeometryProperties )
protecteddefault

◆ RemoveProperty()

bool RemoveProperty ( const std::string &  group_name,
const std::string &  name 
)

Removes the (group_name, name) property (if it exists).

Upon completion the property will not be in the set.

Returns
true if the property existed prior to the call.

◆ UpdateProperty()

void UpdateProperty ( const std::string &  group_name,
const std::string &  name,
const ValueType &  value 
)

Updates the named property (group_name, name) with the given value.

If the property doesn't already exist, it is equivalent to calling AddProperty. If the property does exist, its value (which must have the same type as value) will be replaced.

Parameters
group_nameThe group name.
nameThe name of the property – must be unique in the group.
valueThe value to assign to the property.
Exceptions
std::exceptionif the property exists with a different type.
Template Parameters
ValueTypeThe type of data to store with the attribute – must be copy constructible or cloneable (see Value).

◆ UpdatePropertyAbstract()

void UpdatePropertyAbstract ( const std::string &  group_name,
const std::string &  name,
const AbstractValue value 
)

Updates the named property (group_name, name) with the given type-erased value.

If the property doesn't already exist, it is equivalent to calling AddPropertyAbstract. If the property does exist, its value (which must have the same type as value) will be replaced.

Parameters
group_nameThe group name.
nameThe name of the property – must be unique in the group.
valueThe value to assign to the property.
Exceptions
std::exceptionif the property exists with a different type.

Friends And Related Function Documentation

◆ operator<<

std::ostream& operator<< ( std::ostream &  out,
const GeometryProperties props 
)
friend

The documentation for this class was generated from the following file: