30 #include <unordered_map>
32 #include <boost/algorithm/string.hpp>
33 #include <console_bridge/console.h>
34 #include <Eigen/Geometry>
46 std::unordered_map<std::string, tesseract_scene_graph::Material::Ptr>& available_materials,
49 std::string material_name;
51 std::throw_with_nested(std::runtime_error(
"Material: Missing or failed parsing attribute 'name'!"));
53 auto m = std::make_shared<tesseract_scene_graph::Material>(material_name);
55 m->texture_filename =
"";
56 const tinyxml2::XMLElement* texture = xml_element->FirstChildElement(
"texture");
57 if (texture !=
nullptr)
60 std::throw_with_nested(std::runtime_error(
"Material: Missing or failed parsing texture attribute 'filename'!"));
63 const tinyxml2::XMLElement* color = xml_element->FirstChildElement(
"color");
66 std::string color_string;
68 std::throw_with_nested(std::runtime_error(
"Material: Missing or failed parsing color attribute 'rgba'!"));
70 if (!color_string.empty())
72 std::vector<std::string> tokens;
73 boost::split(tokens, color_string, boost::is_any_of(
" "), boost::token_compress_on);
75 std::throw_with_nested(std::runtime_error(
"Material: Failed to parse color attribute 'rgba' from string!"));
77 double r{ 0 }, g{ 0 }, b{ 0 }, a{ 0 };
84 m->color = Eigen::Vector4d(
r, g, b, a);
88 std::throw_with_nested(std::runtime_error(
"Material: Missing or failed parsing color attribute 'rgba'!"));
92 if (color ==
nullptr && texture ==
nullptr)
94 if (available_materials.empty())
95 std::throw_with_nested(
96 std::runtime_error(
"Material: Material name '" + material_name +
"' only is not allowed!"));
98 auto it = available_materials.find(material_name);
99 if (it == available_materials.end())
100 std::throw_with_nested(std::runtime_error(
"Material with name only '" + material_name +
101 "' was not located in available materials!"));
107 if (!material_name.empty())
109 auto it = available_materials.find(material_name);
110 if (it != available_materials.end())
111 CONSOLE_BRIDGE_logDebug(
"Multiple materials with the same name '%s' exist!", material_name.c_str());
113 available_materials[material_name] = m;
115 else if (!allow_anonymous)
117 std::throw_with_nested(std::runtime_error(
"Anonymous material names (empty string) not allowed!"));
124 tinyxml2::XMLElement*
writeMaterial(
const std::shared_ptr<const tesseract_scene_graph::Material>& material,
125 tinyxml2::XMLDocument& doc)
127 if (material ==
nullptr)
128 std::throw_with_nested(std::runtime_error(
"Material is nullptr and cannot be converted to XML"));
130 Eigen::IOFormat eigen_format(Eigen::StreamPrecision, Eigen::DontAlignCols,
" ",
" ");
132 xml_element->SetAttribute(
"name", material->getName().c_str());
134 if (!material->texture_filename.empty())
136 tinyxml2::XMLElement* xml_texture = doc.NewElement(
"texture");
137 xml_texture->SetAttribute(
"filename", material->texture_filename.c_str());
138 xml_element->InsertEndChild(xml_texture);
141 tinyxml2::XMLElement* xml_color = doc.NewElement(
"color");
142 std::stringstream color_string;
143 color_string << material->color.format(eigen_format);
144 xml_color->SetAttribute(
"rgba", color_string.str().c_str());
145 xml_element->InsertEndChild(xml_color);