forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
geometry_properties.cc
149 lines (133 loc) · 5.02 KB
/
geometry_properties.cc
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
#include "drake/geometry/geometry_properties.h"
#include <fmt/format.h>
namespace drake {
namespace geometry {
using std::string;
const GeometryProperties::Group& GeometryProperties::GetPropertiesInGroup(
const string& group_name) const {
const auto iter = values_.find(group_name);
if (iter != values_.end()) {
return iter->second;
}
throw std::logic_error(
fmt::format("GetPropertiesInGroup(): Can't retrieve properties for a "
"group that doesn't exist: '{}'",
group_name));
}
std::set<string> GeometryProperties::GetGroupNames() const {
std::set<string> group_names;
for (const auto& pair : values_) {
group_names.insert(pair.first);
}
return group_names;
}
void GeometryProperties::AddPropertyAbstract(const string& group_name,
const string& name,
const AbstractValue& value) {
WritePropertyAbstract(
group_name, name, value, [&group_name, &name](const Group& group) {
const auto value_iter = group.find(name);
if (value_iter != group.end()) {
throw std::logic_error(
fmt::format("AddProperty(): Trying to add property ('{}', '{}'); "
"a property with that name already exists",
group_name, name));
}
});
}
void GeometryProperties::UpdatePropertyAbstract(const string& group_name,
const string& name,
const AbstractValue& value) {
WritePropertyAbstract(
group_name, name, value,
[&group_name, &name, &value](const Group& group) {
const auto value_iter = group.find(name);
if (value_iter != group.end() &&
group.at(name)->type_info() != value.type_info()) {
throw std::logic_error(
fmt::format("UpdateProperty(): Trying to update property ('{}', "
"'{}'); The property already exists and is of "
"different type. New type {}, existing type {}",
group_name, name, value.GetNiceTypeName(),
group.at(name)->GetNiceTypeName()));
}
});
}
bool GeometryProperties::HasProperty(const string& group_name,
const string& name) const {
return GetPropertyAbstractMaybe(group_name, name, false) != nullptr;
}
const AbstractValue& GeometryProperties::GetPropertyAbstract(
const string& group_name, const string& name) const {
const AbstractValue* abstract =
GetPropertyAbstractMaybe(group_name, name, true);
if (!abstract) {
throw std::logic_error(fmt::format(
"GetProperty(): There is no property ('{}', '{}')", group_name, name));
}
return *abstract;
}
bool GeometryProperties::RemoveProperty(const string& group_name,
const string& name) {
const auto iter = values_.find(group_name);
if (iter == values_.end()) return false;
Group& group = iter->second;
const auto value_iter = group.find(name);
if (value_iter == group.end()) return false;
group.erase(value_iter);
return true;
}
void GeometryProperties::WritePropertyAbstract(
const string& group_name, const string& name, const AbstractValue& value,
const std::function<void(const Group&)>& throw_if_invalid) {
auto iter = values_.find(group_name);
if (iter == values_.end()) {
auto result = values_.insert({group_name, Group{}});
DRAKE_DEMAND(result.second);
iter = result.first;
}
Group& group = iter->second;
throw_if_invalid(group);
group[name] = value.Clone();
}
const AbstractValue* GeometryProperties::GetPropertyAbstractMaybe(
const string& group_name, const string& name,
bool throw_for_bad_group) const {
const auto iter = values_.find(group_name);
if (iter == values_.end()) {
if (throw_for_bad_group) {
throw std::logic_error(fmt::format(
"GetProperty(): Trying to read property ('{}', '{}'), but the group "
"does not exist.",
group_name, name));
} else {
return nullptr;
}
}
const Group& group = iter->second;
const auto value_iter = group.find(name);
if (value_iter != group.end()) {
return value_iter->second.get();
} else {
return nullptr;
}
}
std::ostream& operator<<(std::ostream& out, const GeometryProperties& props) {
int i = 0;
for (const auto& group_pair : props.values_) {
const string& group_name = group_pair.first;
const GeometryProperties::Group& group_properties = group_pair.second;
out << "[" << group_name << "]";
for (const auto& property_pair : group_properties) {
const string& property_name = property_pair.first;
out << "\n " << property_name << ": "
<< property_pair.second->GetNiceTypeName();
// TODO(SeanCurtis-TRI): How do I print the value in an AbstractValue?
}
if (i < props.num_groups() - 1) out << "\n";
++i;
}
return out;
}
} // namespace geometry
} // namespace drake