31 #include <boost/algorithm/string/classification.hpp>
32 #include <boost/algorithm/string/split.hpp>
33 #include <Eigen/Geometry>
47 std::vector<tesseract_geometry::PolygonMesh::Ptr>
parseMesh(
const tinyxml2::XMLElement* xml_element,
54 std::throw_with_nested(std::runtime_error(
"Mesh: Missing or failed parsing attribute 'filename'!"));
56 std::string scale_string;
57 Eigen::Vector3d scale(1, 1, 1);
60 std::vector<std::string> tokens;
61 boost::split(tokens, scale_string, boost::is_any_of(
" "), boost::token_compress_on);
63 std::throw_with_nested(std::runtime_error(
"Mesh: Failed parsing attribute 'scale'!"));
65 double sx{ 0 }, sy{ 0 }, sz{ 0 };
72 std::throw_with_nested(std::runtime_error(
"Mesh: Scale x value is not greater than zero!"));
75 std::throw_with_nested(std::runtime_error(
"Mesh: Scale y value is not greater than zero!"));
78 std::throw_with_nested(std::runtime_error(
"Mesh: Scale z value is not greater than zero!"));
80 scale = Eigen::Vector3d(sx, sy, sz);
83 std::vector<tesseract_geometry::Mesh::Ptr> meshes;
86 meshes = tesseract_geometry::createMeshFromResource<tesseract_geometry::Mesh>(
87 locator.
locateResource(filename), scale,
true,
true,
true,
true,
true);
89 meshes = tesseract_geometry::createMeshFromResource<tesseract_geometry::Mesh>(
93 std::throw_with_nested(std::runtime_error(
"Mesh: Error importing meshes from filename: '" + filename +
"'!"));
95 bool make_convex_override =
false;
96 auto make_convex_override_status = xml_element->QueryBoolAttribute(
"tesseract:make_convex", &make_convex_override);
97 if (make_convex_override_status != tinyxml2::XML_NO_ATTRIBUTE)
101 if (make_convex_override_status != tinyxml2::XML_SUCCESS)
102 std::throw_with_nested(std::runtime_error(
"Mesh: Failed to parse attribute 'tesseract:make_convex'"));
105 make_convex = make_convex_override;
110 std::vector<tesseract_geometry::PolygonMesh::Ptr> convex_meshes;
111 convex_meshes.reserve(meshes.size());
113 for (
const auto& mesh : meshes)
117 convex_meshes.push_back(convex_mesh);
120 return convex_meshes;
124 std::vector<tesseract_geometry::PolygonMesh::Ptr> output;
125 output.reserve(meshes.size());
126 std::copy(meshes.begin(), meshes.end(), std::back_inserter(output));
131 tinyxml2::XMLElement*
writeMesh(
const std::shared_ptr<const tesseract_geometry::PolygonMesh>& mesh,
132 tinyxml2::XMLDocument& doc,
133 const std::string& package_path,
134 const std::string& filename)
137 std::throw_with_nested(std::runtime_error(
"Mesh is nullptr and cannot be converted to XML"));
139 Eigen::IOFormat eigen_format(Eigen::StreamPrecision, Eigen::DontAlignCols,
" ",
" ");
147 std::throw_with_nested(std::runtime_error(
"Failed to write mesh to file: " + package_path + filename));
149 xml_element->SetAttribute(
"filename",
makeURDFFilePath(package_path, filename).c_str());
151 if (!mesh->getScale().isOnes(std::numeric_limits<double>::epsilon()))
153 std::stringstream scale_string;
154 scale_string << mesh->getScale().format(eigen_format);
155 xml_element->SetAttribute(
"scale", scale_string.str().c_str());
161 if (std::dynamic_pointer_cast<const tesseract_geometry::ConvexMesh>(mesh))
163 xml_element->SetAttribute(
"tesseract:make_convex",
true);