From d1bfb4d5963b5549f79a08ec66276d767c4a55c5 Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 11 Jan 2024 17:23:57 +0100 Subject: [PATCH 1/7] improved Collada loader Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 636 ++++++++++++++++++++++------------ 1 file changed, 405 insertions(+), 231 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index cbcb0bf70..5ab4fbe42 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -40,7 +40,7 @@ using namespace gz; using namespace common; -using RawNodeAnim = std::map >; +using RawNodeAnim = std::map>; using RawSkeletonAnim = std::map; namespace gz @@ -48,7 +48,7 @@ namespace gz namespace common { /// \brief Private data for the ColladaLoader class - class ColladaLoader::Implementation + class ColladaLoader::Implementation { /// \brief scaling factor public: double meter; @@ -69,33 +69,37 @@ namespace gz public: std::string currentNodeName; /// \brief Map of collada POSITION ids to list of vectors. - public: std::map > positionIds; + public: std::map>> positionIds; /// \brief Map of collada NORMAL ids to list of normals. - public: std::map > normalIds; + public: std::map>> normalIds; /// \brief Map of collada TEXCOORD ids to list of texture coordinates. - public: std::map >texcoordIds; + public: std::unordered_map>> texcoordIds; /// \brief Map of collada Material ids to Gazebo materials. public: std::map materialIds; /// \brief Map of collada POSITION ids to a map of /// duplicate positions. - public: std::map > + public: std::map>> positionDuplicateMap; /// \brief Map of collada NORMAL ids to a map of /// duplicate normals. - public: std::map > - normalDuplicateMap; + public: + std::map>> normalDuplicateMap; /// \brief Map of collada TEXCOORD ids to a map of /// duplicate texture coordinates. - public: std::map > + public: + std::map>> texcoordDuplicateMap; /// \brief Current scene being parsed @@ -185,9 +189,9 @@ namespace gz /// \param[out] _verts Holds the resulting vertices /// \param[out] _norms Holds the resulting normals public: void LoadVertices(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_verts, - std::vector &_norms); + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_verts, + std::shared_ptr> &_norms); /// \brief Load vertices /// \param[in] _id String id of the vertices XML node @@ -197,11 +201,13 @@ namespace gz /// \param[out] _vertDup Holds a map of duplicate position indices /// \param[out] _normDup Holds a map of duplicate normal indices public: void LoadVertices(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_verts, - std::vector &_norms, - std::map &_vertDup, - std::map &_normDup); + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_verts, + std::shared_ptr> &_norms, + std::shared_ptr> &_vertDup, + std::shared_ptr> &_normDup); /// \brief Load positions /// \param[in] _id String id of the XML node @@ -209,9 +215,10 @@ namespace gz /// \param[out] _values Holds the resulting position values /// \param[out] _duplicates Holds a map of duplicate position indices public: void LoadPositions(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_values, - std::map &_duplicates); + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates); /// \brief Load normals /// \param[in] _id String id of the XML node @@ -219,17 +226,19 @@ namespace gz /// \param[out] _values Holds the resulting normal values /// \param[out] _duplicates Holds a map of duplicate normal indices public: void LoadNormals(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_values, - std::map &_duplicates); + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates); /// \brief Load texture coordinates /// \param[in] _id String id of the XML node /// \param[out] _values Holds the resulting uv values /// \param[out] _duplicates Holds a map of duplicate uv indices public: void LoadTexCoords(const std::string &_id, - std::vector &_values, - std::map &_duplicates); + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates); /// \brief Load a material /// \param _name Name of the material XML element @@ -248,25 +257,25 @@ namespace gz /// \param[in] _trianglesXml Pointer the triangles XML instance /// \param[in] _transform Transform to apply to all triangles /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadTriangles(tinyxml2::XMLElement *_trianglesXml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadTriangles(tinyxml2::XMLElement *_trianglesXml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load a polygon list /// \param[in] _polylistXml Pointer to the XML element /// \param[in] _transform Transform to apply to each polygon /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadPolylist(tinyxml2::XMLElement *_polylistXml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadPolylist(tinyxml2::XMLElement *_polylistXml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load lines /// \param[in] _xml Pointer to the XML element /// \param[in] _transform Transform to apply /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadLines(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadLines(tinyxml2::XMLElement *_xml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load an entire scene /// \param[out] _mesh Mesh that is currently being loaded @@ -330,7 +339,7 @@ namespace gz void hash_combine(std::size_t &_seed, const double &_v) { std::hash hasher; - _seed ^= hasher(_v) + 0x9e3779b9 + (_seed << 6) + (_seed >> 2); + _seed ^= hasher(_v) + (_seed << 6) + (_seed >> 2); } ///////////////////////////////////////////////// @@ -360,7 +369,7 @@ struct Vector2dHash ////////////////////////////////////////////////// ColladaLoader::ColladaLoader() -: MeshLoader(), dataPtr(gz::utils::MakeImpl()) + : MeshLoader(), dataPtr(gz::utils::MakeImpl()) { this->dataPtr->meter = 1.0; } @@ -510,7 +519,7 @@ void ColladaLoader::Implementation::LoadNode( if (_elem->FirstChildElement("instance_node")) { std::string nodeURLStr = - _elem->FirstChildElement("instance_node")->Attribute("url"); + _elem->FirstChildElement("instance_node")->Attribute("url"); nodeXml = this->ElementId("node", nodeURLStr); if (!nodeXml) @@ -556,7 +565,7 @@ void ColladaLoader::Implementation::LoadNode( } tinyxml2::XMLElement *instContrXml = - nodeXml->FirstChildElement("instance_controller"); + nodeXml->FirstChildElement("instance_controller"); while (instContrXml) { std::string contrURL = instContrXml->Attribute("url"); @@ -620,9 +629,9 @@ gz::math::Matrix4d ColladaLoader::Implementation::LoadNodeTransform( for (unsigned int i = 0; i < 16; ++i) iss >> values[i]; transform.Set(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); } else { @@ -748,7 +757,8 @@ void ColladaLoader::Implementation::LoadController( if (!jointsXml) { gzerr << "Could not find node [" << jointsURL << "]. " - << "Failed to parse skinning information in Collada file." << std::endl; + << "Failed to parse skinning information in Collada file." + << std::endl; return; } @@ -791,7 +801,7 @@ void ColladaLoader::Implementation::LoadController( if (rootXml && rootXml->FirstChildElement("library_animations")) { this->LoadAnimations(rootXml->FirstChildElement("library_animations"), - skeleton); + skeleton); } tinyxml2::XMLElement *invBMXml = this->ElementId("source", invBindMatURL); @@ -799,7 +809,8 @@ void ColladaLoader::Implementation::LoadController( if (nullptr == invBMXml) { gzerr << "Could not find node[" << invBindMatURL << "]. " - << "Faild to parse skinning information in Collada file." << std::endl; + << "Failed to parse skinning information in Collada file." + << std::endl; return; } @@ -818,16 +829,16 @@ void ColladaLoader::Implementation::LoadController( unsigned int id = i * 16; gz::math::Matrix4d mat; - mat.Set(gz::math::parseFloat(strs[id + 0]), - gz::math::parseFloat(strs[id + 1]), - gz::math::parseFloat(strs[id + 2]), - gz::math::parseFloat(strs[id + 3]), - gz::math::parseFloat(strs[id + 4]), - gz::math::parseFloat(strs[id + 5]), - gz::math::parseFloat(strs[id + 6]), - gz::math::parseFloat(strs[id + 7]), - gz::math::parseFloat(strs[id + 8]), - gz::math::parseFloat(strs[id + 9]), + mat.Set(gz::math::parseFloat(strs[id + 0]), + gz::math::parseFloat(strs[id + 1]), + gz::math::parseFloat(strs[id + 2]), + gz::math::parseFloat(strs[id + 3]), + gz::math::parseFloat(strs[id + 4]), + gz::math::parseFloat(strs[id + 5]), + gz::math::parseFloat(strs[id + 6]), + gz::math::parseFloat(strs[id + 7]), + gz::math::parseFloat(strs[id + 8]), + gz::math::parseFloat(strs[id + 9]), gz::math::parseFloat(strs[id + 10]), gz::math::parseFloat(strs[id + 11]), gz::math::parseFloat(strs[id + 12]), @@ -913,7 +924,7 @@ void ColladaLoader::Implementation::LoadController( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadAnimations(tinyxml2::XMLElement *_xml, - SkeletonPtr _skel) + SkeletonPtr _skel) { tinyxml2::XMLElement *childXml = _xml->FirstChildElement("animation"); if (childXml->FirstChildElement("animation")) @@ -930,7 +941,7 @@ void ColladaLoader::Implementation::LoadAnimations(tinyxml2::XMLElement *_xml, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, - SkeletonPtr _skel) + SkeletonPtr _skel) { std::stringstream animName; if (_xml->Attribute("name")) @@ -970,7 +981,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, targetTrans = targetStr.substr(targetStr.find('/') + 1); else targetTrans = targetStr.substr(targetStr.find('/') + 1, - targetStr.find(sep) - targetStr.find('/') - 1); + targetStr.find(sep) - targetStr.find('/') - 1); std::string idxStr = targetStr.substr(targetStr.find(sep) + 1); int idx1 = -1; @@ -1033,7 +1044,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, values.push_back(math::parseFloat(outputStrs[i])); tinyxml2::XMLElement *accessor = - frameTransXml->FirstChildElement("technique_common"); + frameTransXml->FirstChildElement("technique_common"); accessor = accessor->FirstChildElement("accessor"); // stride is optional, default to 1 @@ -1053,7 +1064,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, if (targetNodeXml == nullptr) { gzerr << "Failed to load animation, [" << targetBone << "] not found" - << std::endl; + << std::endl; continue; } targetNode = this->LoadSkeletonNodes(targetNodeXml, nullptr); @@ -1082,7 +1093,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, else { gzerr << "Failed to find node with ID [" << targetBone << "]" - << std::endl; + << std::endl; } } @@ -1102,7 +1113,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, else { for (unsigned int k = 0; k < stride; k++) - nt->SetComponent(k, values[(i*stride) + k]); + nt->SetComponent(k, values[(i * stride) + k]); } } } @@ -1117,9 +1128,9 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, SkeletonAnimation *anim = new SkeletonAnimation(animName.str()); for (RawSkeletonAnim::iterator iter = animation.begin(); - iter != animation.end(); ++iter) + iter != animation.end(); ++iter) for (RawNodeAnim::iterator niter = iter->second.begin(); - niter != iter->second.end(); ++niter) + niter != iter->second.end(); ++niter) { gz::math::Matrix4d transform(gz::math::Matrix4d::Identity); for (unsigned int i = 0; i < niter->second.size(); ++i) @@ -1156,10 +1167,10 @@ SkeletonNode *ColladaLoader::Implementation::LoadSingleSkeletonNode( return nullptr; } - SkeletonNode* node = new SkeletonNode(_parent, name, _xml->Attribute("id")); + SkeletonNode *node = new SkeletonNode(_parent, name, _xml->Attribute("id")); - if (!_xml->Attribute("type") - || std::string(_xml->Attribute("type")) == "NODE") + if (!_xml->Attribute("type") || + std::string(_xml->Attribute("type")) == "NODE") { node->SetType(SkeletonNode::NODE); } @@ -1187,7 +1198,7 @@ SkeletonNode *ColladaLoader::Implementation::LoadSkeletonNodes( if (std::string(_xml->Value()) != "node") { gzwarn << "Failed to load element [" << _xml->Value() - << "] as skeleton node." << std::endl; + << "] as skeleton node." << std::endl; return nullptr; } @@ -1229,9 +1240,9 @@ void ColladaLoader::Implementation::SetSkeletonNodeTransform( for (unsigned int i = 0; i < 16; ++i) iss >> values[i]; transform.Set(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); NodeTransform nt(transform); nt.SetSourceValues(transform); @@ -1313,7 +1324,7 @@ void ColladaLoader::Implementation::SetSkeletonNodeTransform( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadGeometry(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, Mesh *_mesh) + const gz::math::Matrix4d &_transform, Mesh *_mesh) { tinyxml2::XMLElement *meshXml = _xml->FirstChildElement("mesh"); tinyxml2::XMLElement *childXml; @@ -1355,9 +1366,9 @@ tinyxml2::XMLElement *ColladaLoader::Implementation::ElementId( tinyxml2::XMLElement *_parent, const std::string &_name, const std::string &_id) { - std::string id = _id; - if (id.length() > 0 && id[0] == '#') - id.erase(0, 1); + std::string_view id = _id; + if (!id.empty() && id[0] == '#') + id.remove_prefix(1); if ((id.empty() && _parent->Value() == _name) || (_parent->Attribute("id") && _parent->Attribute("id") == id) || @@ -1383,25 +1394,25 @@ tinyxml2::XMLElement *ColladaLoader::Implementation::ElementId( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadVertices(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_verts, - std::vector &_norms) + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_verts, + std::shared_ptr> &_norms) { - std::map vertDup; - std::map normDup; + std::shared_ptr> vertDup; + std::shared_ptr> normDup; this->LoadVertices(_id, _transform, _verts, _norms, vertDup, normDup); } ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadVertices(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_verts, - std::vector &_norms, - std::map &_vertDups, - std::map &_normDups) + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_verts, + std::shared_ptr> &_norms, + std::shared_ptr> &_vertDups, + std::shared_ptr> &_normDups) { tinyxml2::XMLElement *verticesXml = this->ElementId(this->colladaXml, - "vertices", _id); + "vertices", _id); if (!verticesXml) { @@ -1429,9 +1440,10 @@ void ColladaLoader::Implementation::LoadVertices(const std::string &_id, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadPositions(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_values, - std::map &_duplicates) + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates) { if (this->positionIds.find(_id) != this->positionIds.end()) { @@ -1447,6 +1459,9 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, return; } + int totCount = 0; + int stride = 0; + tinyxml2::XMLElement *floatArrayXml = sourceXml->FirstChildElement("float_array"); if (!floatArrayXml || !floatArrayXml->GetText()) @@ -1458,7 +1473,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch(...) + catch (...) { // Do nothing. Messages are printed out below. } @@ -1467,38 +1482,116 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, if (count) { gzerr << "Vertex source missing float_array element, " - << "or count is invalid.\n"; + << "or count is invalid.\n"; } else { gzlog << "Vertex source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; } + // Read in the total number of position coordinate values + else if (floatArrayXml->Attribute("count")) + totCount = std::stoi(floatArrayXml->Attribute("count")); + else + { + gzerr << " has no count attribute in position coordinate " + << "element with id[" << _id << "]\n"; + return; + } + + sourceXml = sourceXml->FirstChildElement("technique_common"); + if (!sourceXml) + { + gzerr << "Unable to find technique_common element for texture " + << "coordinates with id[" << _id << "]\n"; + return; + } + + // Get the accessor XML element. + sourceXml = sourceXml->FirstChildElement("accessor"); + if (!sourceXml) + { + gzerr << "Unable to find as a child of " + << "for texture coordinates with id[" << _id << "]\n"; + return; + } + + // Read in the stride for the texture coordinate values. The stride + // indicates the number of values in the float array the comprise + // a complete texture coordinate. + if (sourceXml->Attribute("stride")) + { + stride = std::stoi(sourceXml->Attribute("stride")); + } + else + { + gzerr << " has no stride attribute in texture coordinate " + << "element with id[" << _id << "]\n"; + return; + } + + // Nothing to read. Don't print a warning because the collada file is + // correct. + if (totCount == 0) + return; + std::string valueStr = floatArrayXml->GetText(); std::unordered_map unique; + unsigned int, Vector3Hash> + unique; - std::vector::iterator iter, end; - std::vector strs = split(valueStr, " \t\r\n"); - end = strs.end(); - for (iter = strs.begin(); iter != end; iter += 3) + auto to_double_vec = [](std::string_view sv, size_t total_count) + { + std::vector result; + result.reserve(total_count * 3); + const char *start = sv.data(); + char *end{}; + while (true) + { + double d = std::strtod(start, &end); + if (start == end) + break; + start = end; + if (errno == ERANGE) + throw std::runtime_error("strtod() overflow"); + result.push_back(d); + } + return result; + }; + + auto values = to_double_vec(valueStr, totCount); + for (int i = 0; i < totCount; i += stride) { - gz::math::Vector3d vec(math::parseFloat(*iter), - gz::math::parseFloat(*(iter+1)), - gz::math::parseFloat(*(iter+2))); + gz::math::Vector3d vec(values[i], + values[i+1], + values[i+2]); vec = _transform * vec; - _values.push_back(vec); + if (!_values) + { + _values = std::make_shared>(); + } + (*_values).push_back(vec); + + if (!_duplicates) + { + _duplicates = std::make_shared>(); + } // create a map of duplicate indices if (unique.find(vec) != unique.end()) - _duplicates[_values.size()-1] = unique[vec]; + { + (*_duplicates)[(*_values).size() - 1] = unique[vec]; + } else - unique[vec] = _values.size()-1; + { + unique[vec] = (*_values).size() - 1; + } } this->positionDuplicateMap[_id] = _duplicates; @@ -1507,9 +1600,10 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadNormals(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::vector &_values, - std::map &_duplicates) + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates) { if (this->normalIds.find(_id) != this->normalIds.end()) { @@ -1539,7 +1633,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch(...) + catch (...) { // Do nothing. Messages are printed out below. } @@ -1548,19 +1642,20 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, if (count) { gzwarn << "Normal source missing float_array element, or count is " - << "invalid.\n"; + << "invalid.\n"; } else { gzlog << "Normal source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; } std::unordered_map unique; + unsigned int, Vector3Hash> + unique; std::string valueStr = floatArrayXml->GetText(); std::istringstream iss(valueStr); @@ -1572,13 +1667,27 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, { vec = rotMat * vec; vec.Normalize(); - _values.push_back(vec); + if (!_values) + { + _values = std::make_shared>(); + } + (*_values).push_back(vec); + + if (!_duplicates) + { + _duplicates = std::make_shared>(); + } // create a map of duplicate indices if (unique.find(vec) != unique.end()) - _duplicates[_values.size()-1] = unique[vec]; + { + (*_duplicates)[(*_values).size() - 1] = unique[vec]; + } else - unique[vec] = _values.size()-1; + { + unique[vec] = (*_values).size() - 1; + } } } while (iss); @@ -1588,8 +1697,9 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, - std::vector &_values, - std::map &_duplicates) + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates) { if (this->texcoordIds.find(_id) != this->texcoordIds.end()) { @@ -1622,7 +1732,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch(...) + catch (...) { // Do nothing. Messages are printed out below. } @@ -1631,12 +1741,12 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, if (count) { gzerr << "Normal source missing float_array element, or count is " - << "invalid.\n"; + << "invalid.\n"; } else { gzlog << "Normal source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; @@ -1710,27 +1820,59 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, return; std::unordered_map unique; + unsigned int, Vector2dHash> + unique; + + + auto to_double_vec = [](std::string_view sv, size_t total_count) + { + std::vector result; + result.reserve(total_count * 2); + const char *start = sv.data(); + char *end{}; + while (true) + { + double d = std::strtod(start, &end); + if (start == end) + break; + start = end; + if (errno == ERANGE) + throw std::runtime_error("strtod() overflow"); + result.push_back(d); + } + return result; + }; // Read the raw texture values, and split them on spaces. std::string valueStr = floatArrayXml->GetText(); - std::vector values = split(valueStr, " \t\r\n"); + auto values = to_double_vec(valueStr, totCount); // Read in all the texture coordinates. for (int i = 0; i < totCount; i += stride) { // We only handle 2D texture coordinates right now. - gz::math::Vector2d vec(std::stod(values[i]), - 1.0 - std::stod(values[i+1])); - _values.push_back(vec); + gz::math::Vector2d vec(values[i], + 1.0 - values[i + 1]); + + if (!_values) + { + _values = std::make_shared>(); + } + (*_values).push_back(vec); + + if (!_duplicates) + { + _duplicates = std::make_shared>(); + } // create a map of duplicate indices if (unique.find(vec) != unique.end()) { - _duplicates[_values.size()-1] = unique[vec]; + (*_duplicates)[(*_values).size() - 1] = unique[vec]; } else - unique[vec] = _values.size()-1; + unique[vec] = (*_values).size() - 1; } this->texcoordDuplicateMap[_id] = _duplicates; @@ -1741,8 +1883,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, MaterialPtr ColladaLoader::Implementation::LoadMaterial( const std::string &_name) { - if (this->materialIds.find(_name) - != this->materialIds.end()) + if (this->materialIds.find(_name) != this->materialIds.end()) { return this->materialIds[_name]; } @@ -1753,17 +1894,17 @@ MaterialPtr ColladaLoader::Implementation::LoadMaterial( MaterialPtr mat(new Material()); std::string effectName = - matXml->FirstChildElement("instance_effect")->Attribute("url"); + matXml->FirstChildElement("instance_effect")->Attribute("url"); tinyxml2::XMLElement *effectXml = this->ElementId("effect", effectName); tinyxml2::XMLElement *commonXml = - effectXml->FirstChildElement("profile_COMMON"); + effectXml->FirstChildElement("profile_COMMON"); if (commonXml) { tinyxml2::XMLElement *techniqueXml = - commonXml->FirstChildElement("technique"); + commonXml->FirstChildElement("technique"); tinyxml2::XMLElement *lambertXml = - techniqueXml->FirstChildElement("lambert"); + techniqueXml->FirstChildElement("lambert"); tinyxml2::XMLElement *phongXml = techniqueXml->FirstChildElement("phong"); tinyxml2::XMLElement *blinnXml = techniqueXml->FirstChildElement("blinn"); @@ -1902,8 +2043,7 @@ void ColladaLoader::Implementation::LoadColorOrTexture( // rendering pipeline doesn't respect the blend mode, here we set // the diffuse to full white as a workaround. - if (_type == "diffuse" - && _mat->Blend() == Material::BlendMode::REPLACE) + if (_type == "diffuse" && _mat->Blend() == Material::BlendMode::REPLACE) { _mat->SetDiffuse(math::Color(1, 1, 1, 1)); } @@ -1911,7 +2051,7 @@ void ColladaLoader::Implementation::LoadColorOrTexture( _mat->SetLighting(true); tinyxml2::XMLElement *imageXml = NULL; std::string textureName = - typeElem->FirstChildElement("texture")->Attribute("texture"); + typeElem->FirstChildElement("texture")->Attribute("texture"); tinyxml2::XMLElement *textureXml = this->ElementId("newparam", textureName); if (textureXml) { @@ -1936,7 +2076,7 @@ void ColladaLoader::Implementation::LoadColorOrTexture( if (surfaceXml && surfaceXml->FirstChildElement("init_from")) { imageXml = this->ElementId("image", - surfaceXml->FirstChildElement("init_from")->GetText()); + surfaceXml->FirstChildElement("init_from")->GetText()); } } } @@ -1949,9 +2089,8 @@ void ColladaLoader::Implementation::LoadColorOrTexture( if (imageXml && imageXml->FirstChildElement("init_from")) { - std::string imgFile = - imageXml->FirstChildElement("init_from")->GetText(); - _mat->SetTextureImage(imgFile, this->path); + _mat->SetTextureImage(imageXml->FirstChildElement( + "init_from")->GetText(), this->path); } } } @@ -1964,7 +2103,7 @@ void ColladaLoader::Implementation::LoadPolylist( { // This function parses polylist types in collada into // a set of triangle meshes. The assumption is that - // each polylist polygon is convex, and we do decomposion + // each polylist polygon is convex, and we do decomposition // by anchoring each triangle about vertex 0 or each polygon std::unique_ptr subMesh(new SubMesh); subMesh->SetName(this->currentNodeName); @@ -1997,9 +2136,10 @@ void ColladaLoader::Implementation::LoadPolylist( tinyxml2::XMLElement *polylistInputXml = _polylistXml->FirstChildElement("input"); - std::vector verts; - std::vector norms; - std::map> texcoords; + std::shared_ptr> verts; + std::shared_ptr> norms; + std::unordered_map>> texcoords; std::vector> texcoordsOffsetToSet; const unsigned int VERTEX = 0; @@ -2008,10 +2148,14 @@ void ColladaLoader::Implementation::LoadPolylist( unsigned int otherSemantics = TEXCOORD + 1; // look up table of position/normal/texcoord duplicate indices - std::unordered_map> + std::unordered_map>> texDupMap; - std::map normalDupMap; - std::map positionDupMap; + std::shared_ptr> normalDupMap; + std::shared_ptr> positionDupMap; gz::math::Matrix4d bindShapeMat(gz::math::Matrix4d::Identity); if (_mesh->HasSkeleton()) @@ -2028,10 +2172,10 @@ void ColladaLoader::Implementation::LoadPolylist( std::string offset = polylistInputXml->Attribute("offset"); if (semantic == "VERTEX") { - unsigned int count = norms.size(); + unsigned int count = (*norms).size(); this->LoadVertices(source, _transform, verts, norms, - positionDupMap, normalDupMap); - if (norms.size() > count) + positionDupMap, normalDupMap); + if ((*norms).size() > count) combinedVertNorms = true; inputs[VERTEX].insert(gz::math::parseInt(offset)); } @@ -2056,7 +2200,7 @@ void ColladaLoader::Implementation::LoadPolylist( { inputs[otherSemantics++].insert(gz::math::parseInt(offset)); gzwarn << "Polylist input semantic: '" << semantic << "' is currently" - << " not supported" << std::endl; + << " not supported" << std::endl; } polylistInputXml = polylistInputXml->NextSiblingElement("input"); @@ -2082,7 +2226,7 @@ void ColladaLoader::Implementation::LoadPolylist( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map > vertexIndexMap; + std::map> vertexIndexMap; unsigned int *values = new unsigned int[inputSize]; memset(values, 0, inputSize); @@ -2092,7 +2236,7 @@ void ColladaLoader::Implementation::LoadPolylist( { // put us at the beginning of the polygon list if (l > 0) - strs_iter += inputSize * vcounts[l-1]; + strs_iter += inputSize * vcounts[l - 1]; for (unsigned int k = 2; k < static_cast(vcounts[l]); ++k) { @@ -2107,13 +2251,13 @@ void ColladaLoader::Implementation::LoadPolylist( if (j == 0) triangle_index = 0; if (j == 1) - triangle_index = (k-1)*inputSize; + triangle_index = (k - 1) * inputSize; if (j == 2) triangle_index = (k)*inputSize; for (unsigned int i = 0; i < inputSize; ++i) { - values[i] = gz::math::parseInt(strs_iter[triangle_index+i]); + values[i] = gz::math::parseInt(strs_iter[triangle_index + i]); } unsigned int daeVertIndex = 0; @@ -2126,8 +2270,8 @@ void ColladaLoader::Implementation::LoadPolylist( // Get the vertex position index value. If it is a duplicate then use // the existing index instead daeVertIndex = values[*inputs[VERTEX].begin()]; - if (positionDupMap.find(daeVertIndex) != positionDupMap.end()) - daeVertIndex = positionDupMap[daeVertIndex]; + if ((*positionDupMap).find(daeVertIndex) != (*positionDupMap).end()) + daeVertIndex = (*positionDupMap)[daeVertIndex]; // if the vertex index has not been previously added then just add it. if (vertexIndexMap.find(daeVertIndex) == vertexIndexMap.end()) @@ -2155,12 +2299,12 @@ void ColladaLoader::Implementation::LoadPolylist( // duplicate then reset the index to the first instance of the // duplicated position unsigned int remappedNormalIndex = - values[*inputs[NORMAL].begin()]; - if (normalDupMap.find(remappedNormalIndex) - != normalDupMap.end()) - { - remappedNormalIndex = normalDupMap[remappedNormalIndex]; - } + values[*inputs[NORMAL].begin()]; + if ((*normalDupMap).find(remappedNormalIndex) != + (*normalDupMap).end()) + { + remappedNormalIndex = (*normalDupMap)[remappedNormalIndex]; + } if (iv.normalIndex == remappedNormalIndex) normEqual = true; @@ -2177,8 +2321,8 @@ void ColladaLoader::Implementation::LoadPolylist( // duplicate then reset the index to the first instance of the // duplicated texcoord unsigned int remappedTexcoordIndex = - values[offset]; - auto &texDupMapSet = texDupMap[set]; + values[offset]; + auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find( remappedTexcoordIndex); if (texDupMapSetIt != texDupMapSet.end()) @@ -2213,25 +2357,25 @@ void ColladaLoader::Implementation::LoadPolylist( GeometryIndices input; if (!inputs[VERTEX].empty()) { - subMesh->AddVertex(verts[daeVertIndex]); - unsigned int newVertIndex = subMesh->VertexCount()-1; + subMesh->AddVertex((*verts)[daeVertIndex]); + unsigned int newVertIndex = subMesh->VertexCount() - 1; subMesh->AddIndex(newVertIndex); if (combinedVertNorms) - subMesh->AddNormal(norms[daeVertIndex]); + subMesh->AddNormal((*norms)[daeVertIndex]); if (_mesh->HasSkeleton()) { subMesh->SetVertex(newVertIndex, bindShapeMat * - subMesh->Vertex(newVertIndex)); + subMesh->Vertex(newVertIndex)); SkeletonPtr skel = _mesh->MeshSkeleton(); for (unsigned int i = 0; - i < skel->VertNodeWeightCount(daeVertIndex); ++i) + i < skel->VertNodeWeightCount(daeVertIndex); ++i) { std::pair node_weight = - skel->VertNodeWeight(daeVertIndex, i); + skel->VertNodeWeight(daeVertIndex, i); SkeletonNode *node = _mesh->MeshSkeleton()->NodeByName(node_weight.first); - subMesh->AddNodeAssignment(subMesh->VertexCount()-1, - node->Handle(), node_weight.second); + subMesh->AddNodeAssignment(subMesh->VertexCount() - 1, + node->Handle(), node_weight.second); } } input.vertexIndex = daeVertIndex; @@ -2240,17 +2384,18 @@ void ColladaLoader::Implementation::LoadPolylist( if (!inputs[NORMAL].empty()) { unsigned int inputRemappedNormalIndex = - values[*inputs[NORMAL].begin()]; + values[*inputs[NORMAL].begin()]; - if (normalDupMap.find(inputRemappedNormalIndex) - != normalDupMap.end()) + if ((*normalDupMap).find(inputRemappedNormalIndex) != + (*normalDupMap).end()) { - inputRemappedNormalIndex = normalDupMap[inputRemappedNormalIndex]; + inputRemappedNormalIndex = + (*normalDupMap)[inputRemappedNormalIndex]; } - if (norms.size() > inputRemappedNormalIndex) + if ((*norms).size() > inputRemappedNormalIndex) { - subMesh->AddNormal(norms[inputRemappedNormalIndex]); + subMesh->AddNormal((*norms)[inputRemappedNormalIndex]); input.normalIndex = inputRemappedNormalIndex; } } @@ -2263,17 +2408,17 @@ void ColladaLoader::Implementation::LoadPolylist( unsigned int set = pair.second; unsigned int inputRemappedTexcoordIndex = - values[offset]; + values[offset]; - auto &texDupMapSet = texDupMap[set]; + auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find( inputRemappedTexcoordIndex); if (texDupMapSetIt != texDupMapSet.end()) inputRemappedTexcoordIndex = texDupMapSetIt->second; auto &texcoordsSet = texcoords[set]; subMesh->AddTexCoordBySet( - texcoordsSet[inputRemappedTexcoordIndex].X(), - texcoordsSet[inputRemappedTexcoordIndex].Y(), set); + (*texcoordsSet)[inputRemappedTexcoordIndex].X(), + (*texcoordsSet)[inputRemappedTexcoordIndex].Y(), set); input.texcoordIndex[set] = inputRemappedTexcoordIndex; } } @@ -2289,7 +2434,7 @@ void ColladaLoader::Implementation::LoadPolylist( } } } - delete [] values; + delete[] values; _mesh->AddSubMesh(std::move(subMesh)); } @@ -2329,9 +2474,11 @@ void ColladaLoader::Implementation::LoadTriangles( tinyxml2::XMLElement *trianglesInputXml = _trianglesXml->FirstChildElement("input"); - std::vector verts; - std::vector norms; - std::map> texcoords; + + std::shared_ptr> verts; + std::shared_ptr> norms; + std::unordered_map>> texcoords; std::vector> texcoordsOffsetToSet; const unsigned int VERTEX = 0; @@ -2348,10 +2495,13 @@ void ColladaLoader::Implementation::LoadTriangles( std::map> inputs; // look up table of position/normal/texcoord duplicate indices - std::unordered_map> - texDupMap; - std::map normalDupMap; - std::map positionDupMap; + std::unordered_map>> texDupMap; + std::shared_ptr> normalDupMap; + std::shared_ptr> positionDupMap; + while (trianglesInputXml) { @@ -2360,11 +2510,25 @@ void ColladaLoader::Implementation::LoadTriangles( std::string offset = trianglesInputXml->Attribute("offset"); if (semantic == "VERTEX") { - unsigned int count = norms.size(); + unsigned int count; + if (!norms || norms->empty()) + { + count = 0; + } + else + { + count = (*norms).size(); + } this->LoadVertices(source, _transform, verts, norms, - positionDupMap, normalDupMap); - if (norms.size() > count) - combinedVertNorms = true; + positionDupMap, normalDupMap); + + if (norms && !norms->empty()) + { + if ((*norms).size() > count) + { + combinedVertNorms = true; + } + } inputs[VERTEX].insert(gz::math::parseInt(offset)); hasVertices = true; } @@ -2373,8 +2537,14 @@ void ColladaLoader::Implementation::LoadTriangles( this->LoadNormals(source, _transform, norms, normalDupMap); combinedVertNorms = false; inputs[NORMAL].insert(gz::math::parseInt(offset)); - if (norms.size() > 0) - hasNormals = true; + + if (norms && !norms->empty()) + { + if ((*norms).size() > 0) + { + hasNormals = true; + } + } } else if (semantic == "TEXCOORD") { @@ -2392,7 +2562,7 @@ void ColladaLoader::Implementation::LoadTriangles( { inputs[otherSemantics++].insert(gz::math::parseInt(offset)); gzwarn << "Triangle input semantic: '" << semantic << "' is currently" - << " not supported" << std::endl; + << " not supported" << std::endl; } trianglesInputXml = trianglesInputXml->NextSiblingElement("input"); } @@ -2421,12 +2591,12 @@ void ColladaLoader::Implementation::LoadTriangles( if (count) { gzerr << "Collada file[" << this->filename - << "] is invalid. Loading what we can...\n"; + << "] is invalid. Loading what we can...\n"; } else { gzlog << "Triangle input has a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; @@ -2441,7 +2611,7 @@ void ColladaLoader::Implementation::LoadTriangles( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map > vertexIndexMap; + std::map> vertexIndexMap; std::vector values(offsetSize); std::vector strs = split(pStr, " \t\r\n"); @@ -2449,7 +2619,7 @@ void ColladaLoader::Implementation::LoadTriangles( for (unsigned int j = 0; j < strs.size(); j += offsetSize) { for (unsigned int i = 0; i < offsetSize; ++i) - values.at(i) = gz::math::parseInt(strs[j+i]); + values.at(i) = gz::math::parseInt(strs[j + i]); unsigned int daeVertIndex = 0; bool addIndex = !hasVertices; @@ -2461,8 +2631,8 @@ void ColladaLoader::Implementation::LoadTriangles( // Get the vertex position index value. If the position is a duplicate // then reset the index to the first instance of the duplicated position daeVertIndex = values.at(*inputs[VERTEX].begin()); - if (positionDupMap.find(daeVertIndex) != positionDupMap.end()) - daeVertIndex = positionDupMap[daeVertIndex]; + if ((*positionDupMap).find(daeVertIndex) != (*positionDupMap).end()) + daeVertIndex = (*positionDupMap)[daeVertIndex]; // if the vertex index has not been previously added then just add it. if (vertexIndexMap.find(daeVertIndex) == vertexIndexMap.end()) @@ -2489,8 +2659,9 @@ void ColladaLoader::Implementation::LoadTriangles( // position unsigned int remappedNormalIndex = values.at( *inputs[NORMAL].begin()); - if (normalDupMap.find(remappedNormalIndex) != normalDupMap.end()) - remappedNormalIndex = normalDupMap[remappedNormalIndex]; + if ((*normalDupMap).find(remappedNormalIndex) != + (*normalDupMap).end()) + remappedNormalIndex = (*normalDupMap)[remappedNormalIndex]; if (iv.normalIndex == remappedNormalIndex) normEqual = true; @@ -2508,7 +2679,7 @@ void ColladaLoader::Implementation::LoadTriangles( // duplicated texcoord unsigned int remappedTexcoordIndex = values.at(offset); - auto &texDupMapSet = texDupMap[set]; + auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find(remappedTexcoordIndex); if (texDupMapSetIt != texDupMapSet.end()) remappedTexcoordIndex = texDupMapSetIt->second; @@ -2542,30 +2713,30 @@ void ColladaLoader::Implementation::LoadTriangles( GeometryIndices input; if (hasVertices) { - subMesh->AddVertex(verts[daeVertIndex]); - unsigned int newVertIndex = subMesh->VertexCount()-1; + subMesh->AddVertex((*verts)[daeVertIndex]); + unsigned int newVertIndex = subMesh->VertexCount() - 1; subMesh->AddIndex(newVertIndex); if (combinedVertNorms) - subMesh->AddNormal(norms[daeVertIndex]); + subMesh->AddNormal((*norms)[daeVertIndex]); if (_mesh->HasSkeleton()) { SkeletonPtr skel = _mesh->MeshSkeleton(); for (unsigned int i = 0; - i < skel->VertNodeWeightCount(daeVertIndex); ++i) + i < skel->VertNodeWeightCount(daeVertIndex); ++i) { std::pair node_weight = - skel->VertNodeWeight(daeVertIndex, i); + skel->VertNodeWeight(daeVertIndex, i); SkeletonNode *node = _mesh->MeshSkeleton()->NodeByName(node_weight.first); if (nullptr == node) { gzerr << "Failed to find skeleton node named [" - << node_weight.first << "]" << std::endl; + << node_weight.first << "]" << std::endl; continue; } - subMesh->AddNodeAssignment(subMesh->VertexCount()-1, - node->Handle(), node_weight.second); + subMesh->AddNodeAssignment(subMesh->VertexCount() - 1, + node->Handle(), node_weight.second); } } input.vertexIndex = daeVertIndex; @@ -2575,9 +2746,10 @@ void ColladaLoader::Implementation::LoadTriangles( { unsigned int inputRemappedNormalIndex = values.at( *inputs[NORMAL].begin()); - if (normalDupMap.find(inputRemappedNormalIndex) != normalDupMap.end()) - inputRemappedNormalIndex = normalDupMap[inputRemappedNormalIndex]; - subMesh->AddNormal(norms[inputRemappedNormalIndex]); + if ((*normalDupMap).find(inputRemappedNormalIndex) != + (*normalDupMap).end()) + inputRemappedNormalIndex = (*normalDupMap)[inputRemappedNormalIndex]; + subMesh->AddNormal((*norms)[inputRemappedNormalIndex]); input.normalIndex = inputRemappedNormalIndex; } if (hasTexcoords) @@ -2590,14 +2762,14 @@ void ColladaLoader::Implementation::LoadTriangles( unsigned int inputRemappedTexcoordIndex = values.at(offset); - auto &texDupMapSet = texDupMap[set]; + auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find(inputRemappedTexcoordIndex); if (texDupMapSetIt != texDupMapSet.end()) inputRemappedTexcoordIndex = texDupMapSetIt->second; auto &texcoordsSet = texcoords[set]; subMesh->AddTexCoordBySet( - texcoordsSet[inputRemappedTexcoordIndex].X(), - texcoordsSet[inputRemappedTexcoordIndex].Y(), set); + (*texcoordsSet)[inputRemappedTexcoordIndex].X(), + (*texcoordsSet)[inputRemappedTexcoordIndex].Y(), set); input.texcoordIndex[set] = inputRemappedTexcoordIndex; } } @@ -2612,12 +2784,13 @@ void ColladaLoader::Implementation::LoadTriangles( } } + _mesh->AddSubMesh(std::move(subMesh)); } ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadLines(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, Mesh *_mesh) + const gz::math::Matrix4d &_transform, Mesh *_mesh) { std::unique_ptr subMesh(new SubMesh); subMesh->SetName(this->currentNodeName); @@ -2627,8 +2800,8 @@ void ColladaLoader::Implementation::LoadLines(tinyxml2::XMLElement *_xml, // std::string semantic = inputXml->Attribute("semantic"); std::string source = inputXml->Attribute("source"); - std::vector verts; - std::vector norms; + std::shared_ptr> verts; + std::shared_ptr> norms; this->LoadVertices(source, _transform, verts, norms); tinyxml2::XMLElement *pXml = _xml->FirstChildElement("p"); @@ -2642,9 +2815,9 @@ void ColladaLoader::Implementation::LoadLines(tinyxml2::XMLElement *_xml, if (!iss) break; - subMesh->AddVertex(verts[a]); + subMesh->AddVertex((*verts)[a]); subMesh->AddIndex(subMesh->VertexCount() - 1); - subMesh->AddVertex(verts[b]); + subMesh->AddVertex((*verts)[b]); subMesh->AddIndex(subMesh->VertexCount() - 1); } while (iss); @@ -2659,15 +2832,16 @@ float ColladaLoader::Implementation::LoadFloat(tinyxml2::XMLElement *_elem) if (_elem->FirstChildElement("float")) { value = - gz::math::parseFloat(_elem->FirstChildElement("float")->GetText()); + gz::math::parseFloat(_elem->FirstChildElement("float")->GetText()); } return value; } ///////////////////////////////////////////////// -void ColladaLoader::Implementation::LoadTransparent(tinyxml2::XMLElement *_elem, - MaterialPtr _mat) +void ColladaLoader::Implementation::LoadTransparent( + tinyxml2::XMLElement *_elem, + MaterialPtr _mat) { const char *opaqueCStr = _elem->Attribute("opaque"); if (!opaqueCStr) @@ -2773,7 +2947,7 @@ void ColladaLoader::Implementation::LoadTransparent(tinyxml2::XMLElement *_elem, ///////////////////////////////////////////////// void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton, - SkeletonNode *_mergeNode) + SkeletonNode *_mergeNode) { if (nullptr == _skeleton) { @@ -2812,7 +2986,7 @@ void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton, // Check if the node that will be merged contains the dummy-root // if so, replace dummyRoot bool mergeNodeContainsRoot = true; - for (unsigned int i=0; i < currentRoot->ChildCount(); ++i) + for (unsigned int i = 0; i < currentRoot->ChildCount(); ++i) { if (_mergeNode->ChildById(currentRoot->Child(i)->Id()) == nullptr) { From c22b4d99effb5ee151d6353b9cf5d7cd6bda6652 Mon Sep 17 00:00:00 2001 From: frederik Date: Fri, 12 Jan 2024 10:17:32 +0100 Subject: [PATCH 2/7] remove pure linter changes and fix camel cases Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 254 ++++++++++++++++------------------ 1 file changed, 123 insertions(+), 131 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index 5ab4fbe42..c69dd4e84 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -40,7 +40,7 @@ using namespace gz; using namespace common; -using RawNodeAnim = std::map>; +using RawNodeAnim = std::map >; using RawSkeletonAnim = std::map; namespace gz @@ -48,7 +48,7 @@ namespace gz namespace common { /// \brief Private data for the ColladaLoader class - class ColladaLoader::Implementation + class ColladaLoader::Implementation { /// \brief scaling factor public: double meter; @@ -91,16 +91,13 @@ namespace gz /// \brief Map of collada NORMAL ids to a map of /// duplicate normals. - public: - std::map>> normalDuplicateMap; + public: std::map>> normalDuplicateMap; /// \brief Map of collada TEXCOORD ids to a map of /// duplicate texture coordinates. - public: - std::map>> - texcoordDuplicateMap; + public: std::map>> texcoordDuplicateMap; /// \brief Current scene being parsed public: tinyxml2::XMLElement *currentScene = nullptr; @@ -257,25 +254,25 @@ namespace gz /// \param[in] _trianglesXml Pointer the triangles XML instance /// \param[in] _transform Transform to apply to all triangles /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadTriangles(tinyxml2::XMLElement *_trianglesXml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadTriangles(tinyxml2::XMLElement *_trianglesXml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load a polygon list /// \param[in] _polylistXml Pointer to the XML element /// \param[in] _transform Transform to apply to each polygon /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadPolylist(tinyxml2::XMLElement *_polylistXml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadPolylist(tinyxml2::XMLElement *_polylistXml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load lines /// \param[in] _xml Pointer to the XML element /// \param[in] _transform Transform to apply /// \param[out] _mesh Mesh that is currently being loaded - public: void LoadLines(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, - Mesh *_mesh); + public: void LoadLines(tinyxml2::XMLElement *_xml, + const gz::math::Matrix4d &_transform, + Mesh *_mesh); /// \brief Load an entire scene /// \param[out] _mesh Mesh that is currently being loaded @@ -369,7 +366,7 @@ struct Vector2dHash ////////////////////////////////////////////////// ColladaLoader::ColladaLoader() - : MeshLoader(), dataPtr(gz::utils::MakeImpl()) +: MeshLoader(), dataPtr(gz::utils::MakeImpl()) { this->dataPtr->meter = 1.0; } @@ -519,7 +516,7 @@ void ColladaLoader::Implementation::LoadNode( if (_elem->FirstChildElement("instance_node")) { std::string nodeURLStr = - _elem->FirstChildElement("instance_node")->Attribute("url"); + _elem->FirstChildElement("instance_node")->Attribute("url"); nodeXml = this->ElementId("node", nodeURLStr); if (!nodeXml) @@ -565,7 +562,7 @@ void ColladaLoader::Implementation::LoadNode( } tinyxml2::XMLElement *instContrXml = - nodeXml->FirstChildElement("instance_controller"); + nodeXml->FirstChildElement("instance_controller"); while (instContrXml) { std::string contrURL = instContrXml->Attribute("url"); @@ -629,9 +626,9 @@ gz::math::Matrix4d ColladaLoader::Implementation::LoadNodeTransform( for (unsigned int i = 0; i < 16; ++i) iss >> values[i]; transform.Set(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); } else { @@ -757,8 +754,7 @@ void ColladaLoader::Implementation::LoadController( if (!jointsXml) { gzerr << "Could not find node [" << jointsURL << "]. " - << "Failed to parse skinning information in Collada file." - << std::endl; + << "Failed to parse skinning information in Collada file." << std::endl; return; } @@ -801,7 +797,7 @@ void ColladaLoader::Implementation::LoadController( if (rootXml && rootXml->FirstChildElement("library_animations")) { this->LoadAnimations(rootXml->FirstChildElement("library_animations"), - skeleton); + skeleton); } tinyxml2::XMLElement *invBMXml = this->ElementId("source", invBindMatURL); @@ -809,8 +805,7 @@ void ColladaLoader::Implementation::LoadController( if (nullptr == invBMXml) { gzerr << "Could not find node[" << invBindMatURL << "]. " - << "Failed to parse skinning information in Collada file." - << std::endl; + << "Faild to parse skinning information in Collada file." << std::endl; return; } @@ -829,16 +824,16 @@ void ColladaLoader::Implementation::LoadController( unsigned int id = i * 16; gz::math::Matrix4d mat; - mat.Set(gz::math::parseFloat(strs[id + 0]), - gz::math::parseFloat(strs[id + 1]), - gz::math::parseFloat(strs[id + 2]), - gz::math::parseFloat(strs[id + 3]), - gz::math::parseFloat(strs[id + 4]), - gz::math::parseFloat(strs[id + 5]), - gz::math::parseFloat(strs[id + 6]), - gz::math::parseFloat(strs[id + 7]), - gz::math::parseFloat(strs[id + 8]), - gz::math::parseFloat(strs[id + 9]), + mat.Set(gz::math::parseFloat(strs[id + 0]), + gz::math::parseFloat(strs[id + 1]), + gz::math::parseFloat(strs[id + 2]), + gz::math::parseFloat(strs[id + 3]), + gz::math::parseFloat(strs[id + 4]), + gz::math::parseFloat(strs[id + 5]), + gz::math::parseFloat(strs[id + 6]), + gz::math::parseFloat(strs[id + 7]), + gz::math::parseFloat(strs[id + 8]), + gz::math::parseFloat(strs[id + 9]), gz::math::parseFloat(strs[id + 10]), gz::math::parseFloat(strs[id + 11]), gz::math::parseFloat(strs[id + 12]), @@ -924,7 +919,7 @@ void ColladaLoader::Implementation::LoadController( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadAnimations(tinyxml2::XMLElement *_xml, - SkeletonPtr _skel) + SkeletonPtr _skel) { tinyxml2::XMLElement *childXml = _xml->FirstChildElement("animation"); if (childXml->FirstChildElement("animation")) @@ -941,7 +936,7 @@ void ColladaLoader::Implementation::LoadAnimations(tinyxml2::XMLElement *_xml, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, - SkeletonPtr _skel) + SkeletonPtr _skel) { std::stringstream animName; if (_xml->Attribute("name")) @@ -981,7 +976,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, targetTrans = targetStr.substr(targetStr.find('/') + 1); else targetTrans = targetStr.substr(targetStr.find('/') + 1, - targetStr.find(sep) - targetStr.find('/') - 1); + targetStr.find(sep) - targetStr.find('/') - 1); std::string idxStr = targetStr.substr(targetStr.find(sep) + 1); int idx1 = -1; @@ -1044,7 +1039,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, values.push_back(math::parseFloat(outputStrs[i])); tinyxml2::XMLElement *accessor = - frameTransXml->FirstChildElement("technique_common"); + frameTransXml->FirstChildElement("technique_common"); accessor = accessor->FirstChildElement("accessor"); // stride is optional, default to 1 @@ -1064,7 +1059,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, if (targetNodeXml == nullptr) { gzerr << "Failed to load animation, [" << targetBone << "] not found" - << std::endl; + << std::endl; continue; } targetNode = this->LoadSkeletonNodes(targetNodeXml, nullptr); @@ -1093,7 +1088,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, else { gzerr << "Failed to find node with ID [" << targetBone << "]" - << std::endl; + << std::endl; } } @@ -1113,7 +1108,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, else { for (unsigned int k = 0; k < stride; k++) - nt->SetComponent(k, values[(i * stride) + k]); + nt->SetComponent(k, values[(i*stride) + k]); } } } @@ -1128,9 +1123,9 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, SkeletonAnimation *anim = new SkeletonAnimation(animName.str()); for (RawSkeletonAnim::iterator iter = animation.begin(); - iter != animation.end(); ++iter) + iter != animation.end(); ++iter) for (RawNodeAnim::iterator niter = iter->second.begin(); - niter != iter->second.end(); ++niter) + niter != iter->second.end(); ++niter) { gz::math::Matrix4d transform(gz::math::Matrix4d::Identity); for (unsigned int i = 0; i < niter->second.size(); ++i) @@ -1167,10 +1162,10 @@ SkeletonNode *ColladaLoader::Implementation::LoadSingleSkeletonNode( return nullptr; } - SkeletonNode *node = new SkeletonNode(_parent, name, _xml->Attribute("id")); + SkeletonNode* node = new SkeletonNode(_parent, name, _xml->Attribute("id")); - if (!_xml->Attribute("type") || - std::string(_xml->Attribute("type")) == "NODE") + if (!_xml->Attribute("type") + || std::string(_xml->Attribute("type")) == "NODE") { node->SetType(SkeletonNode::NODE); } @@ -1198,7 +1193,7 @@ SkeletonNode *ColladaLoader::Implementation::LoadSkeletonNodes( if (std::string(_xml->Value()) != "node") { gzwarn << "Failed to load element [" << _xml->Value() - << "] as skeleton node." << std::endl; + << "] as skeleton node." << std::endl; return nullptr; } @@ -1240,9 +1235,9 @@ void ColladaLoader::Implementation::SetSkeletonNodeTransform( for (unsigned int i = 0; i < 16; ++i) iss >> values[i]; transform.Set(values[0], values[1], values[2], values[3], - values[4], values[5], values[6], values[7], - values[8], values[9], values[10], values[11], - values[12], values[13], values[14], values[15]); + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); NodeTransform nt(transform); nt.SetSourceValues(transform); @@ -1324,7 +1319,7 @@ void ColladaLoader::Implementation::SetSkeletonNodeTransform( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadGeometry(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, Mesh *_mesh) + const gz::math::Matrix4d &_transform, Mesh *_mesh) { tinyxml2::XMLElement *meshXml = _xml->FirstChildElement("mesh"); tinyxml2::XMLElement *childXml; @@ -1412,7 +1407,7 @@ void ColladaLoader::Implementation::LoadVertices(const std::string &_id, std::shared_ptr> &_normDups) { tinyxml2::XMLElement *verticesXml = this->ElementId(this->colladaXml, - "vertices", _id); + "vertices", _id); if (!verticesXml) { @@ -1473,7 +1468,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch (...) + catch(...) { // Do nothing. Messages are printed out below. } @@ -1482,12 +1477,12 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, if (count) { gzerr << "Vertex source missing float_array element, " - << "or count is invalid.\n"; + << "or count is invalid.\n"; } else { gzlog << "Vertex source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; @@ -1541,13 +1536,12 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, std::string valueStr = floatArrayXml->GetText(); std::unordered_map - unique; + unsigned int, Vector3Hash> unique; - auto to_double_vec = [](std::string_view sv, size_t total_count) + auto toDoubleVec = [](std::string_view sv, size_t totalCount) { std::vector result; - result.reserve(total_count * 3); + result.reserve(totalCount * 3); const char *start = sv.data(); char *end{}; while (true) @@ -1563,7 +1557,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, return result; }; - auto values = to_double_vec(valueStr, totCount); + auto values = toDoubleVec(valueStr, totCount); for (int i = 0; i < totCount; i += stride) { gz::math::Vector3d vec(values[i], @@ -1586,11 +1580,11 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, // create a map of duplicate indices if (unique.find(vec) != unique.end()) { - (*_duplicates)[(*_values).size() - 1] = unique[vec]; + (*_duplicates)[(*_values).size()-1] = unique[vec]; } else { - unique[vec] = (*_values).size() - 1; + unique[vec] = (*_values).size()-1; } } @@ -1600,10 +1594,10 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadNormals(const std::string &_id, - const gz::math::Matrix4d &_transform, - std::shared_ptr> &_values, - std::shared_ptr> &_duplicates) + const gz::math::Matrix4d &_transform, + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates) { if (this->normalIds.find(_id) != this->normalIds.end()) { @@ -1633,7 +1627,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch (...) + catch(...) { // Do nothing. Messages are printed out below. } @@ -1642,20 +1636,19 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, if (count) { gzwarn << "Normal source missing float_array element, or count is " - << "invalid.\n"; + << "invalid.\n"; } else { gzlog << "Normal source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; } std::unordered_map - unique; + unsigned int, Vector3Hash> unique; std::string valueStr = floatArrayXml->GetText(); std::istringstream iss(valueStr); @@ -1682,11 +1675,11 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, // create a map of duplicate indices if (unique.find(vec) != unique.end()) { - (*_duplicates)[(*_values).size() - 1] = unique[vec]; + (*_duplicates)[(*_values).size()-1] = unique[vec]; } else { - unique[vec] = (*_values).size() - 1; + unique[vec] = (*_values).size()-1; } } } while (iss); @@ -1697,9 +1690,9 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, - std::shared_ptr> &_values, - std::shared_ptr> &_duplicates) + std::shared_ptr> &_values, + std::shared_ptr> &_duplicates) { if (this->texcoordIds.find(_id) != this->texcoordIds.end()) { @@ -1732,7 +1725,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, { count = std::stoi(floatArrayXml->Attribute("count")); } - catch (...) + catch(...) { // Do nothing. Messages are printed out below. } @@ -1741,12 +1734,12 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, if (count) { gzerr << "Normal source missing float_array element, or count is " - << "invalid.\n"; + << "invalid.\n"; } else { gzlog << "Normal source has a float_array with a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; @@ -1824,10 +1817,10 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, unique; - auto to_double_vec = [](std::string_view sv, size_t total_count) + auto toDoubleVec = [](std::string_view sv, size_t totalCount) { std::vector result; - result.reserve(total_count * 2); + result.reserve(totalCount * 2); const char *start = sv.data(); char *end{}; while (true) @@ -1845,7 +1838,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, // Read the raw texture values, and split them on spaces. std::string valueStr = floatArrayXml->GetText(); - auto values = to_double_vec(valueStr, totCount); + auto values = toDoubleVec(valueStr, totCount); // Read in all the texture coordinates. for (int i = 0; i < totCount; i += stride) @@ -1869,10 +1862,10 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, // create a map of duplicate indices if (unique.find(vec) != unique.end()) { - (*_duplicates)[(*_values).size() - 1] = unique[vec]; + (*_duplicates)[(*_values).size()-1] = unique[vec]; } else - unique[vec] = (*_values).size() - 1; + unique[vec] = (*_values).size()-1; } this->texcoordDuplicateMap[_id] = _duplicates; @@ -1883,7 +1876,8 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, MaterialPtr ColladaLoader::Implementation::LoadMaterial( const std::string &_name) { - if (this->materialIds.find(_name) != this->materialIds.end()) + if (this->materialIds.find(_name) + != this->materialIds.end()) { return this->materialIds[_name]; } @@ -1894,7 +1888,7 @@ MaterialPtr ColladaLoader::Implementation::LoadMaterial( MaterialPtr mat(new Material()); std::string effectName = - matXml->FirstChildElement("instance_effect")->Attribute("url"); + matXml->FirstChildElement("instance_effect")->Attribute("url"); tinyxml2::XMLElement *effectXml = this->ElementId("effect", effectName); tinyxml2::XMLElement *commonXml = @@ -2043,7 +2037,8 @@ void ColladaLoader::Implementation::LoadColorOrTexture( // rendering pipeline doesn't respect the blend mode, here we set // the diffuse to full white as a workaround. - if (_type == "diffuse" && _mat->Blend() == Material::BlendMode::REPLACE) + if (_type == "diffuse" + && _mat->Blend() == Material::BlendMode::REPLACE) { _mat->SetDiffuse(math::Color(1, 1, 1, 1)); } @@ -2051,7 +2046,7 @@ void ColladaLoader::Implementation::LoadColorOrTexture( _mat->SetLighting(true); tinyxml2::XMLElement *imageXml = NULL; std::string textureName = - typeElem->FirstChildElement("texture")->Attribute("texture"); + typeElem->FirstChildElement("texture")->Attribute("texture"); tinyxml2::XMLElement *textureXml = this->ElementId("newparam", textureName); if (textureXml) { @@ -2076,7 +2071,7 @@ void ColladaLoader::Implementation::LoadColorOrTexture( if (surfaceXml && surfaceXml->FirstChildElement("init_from")) { imageXml = this->ElementId("image", - surfaceXml->FirstChildElement("init_from")->GetText()); + surfaceXml->FirstChildElement("init_from")->GetText()); } } } @@ -2149,9 +2144,7 @@ void ColladaLoader::Implementation::LoadPolylist( // look up table of position/normal/texcoord duplicate indices std::unordered_map>> - texDupMap; + >> texDupMap; std::shared_ptr> normalDupMap; std::shared_ptrLoadVertices(source, _transform, verts, norms, - positionDupMap, normalDupMap); + positionDupMap, normalDupMap); if ((*norms).size() > count) combinedVertNorms = true; inputs[VERTEX].insert(gz::math::parseInt(offset)); @@ -2200,7 +2193,7 @@ void ColladaLoader::Implementation::LoadPolylist( { inputs[otherSemantics++].insert(gz::math::parseInt(offset)); gzwarn << "Polylist input semantic: '" << semantic << "' is currently" - << " not supported" << std::endl; + << " not supported" << std::endl; } polylistInputXml = polylistInputXml->NextSiblingElement("input"); @@ -2226,7 +2219,7 @@ void ColladaLoader::Implementation::LoadPolylist( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map> vertexIndexMap; + std::map > vertexIndexMap; unsigned int *values = new unsigned int[inputSize]; memset(values, 0, inputSize); @@ -2236,7 +2229,7 @@ void ColladaLoader::Implementation::LoadPolylist( { // put us at the beginning of the polygon list if (l > 0) - strs_iter += inputSize * vcounts[l - 1]; + strs_iter += inputSize * vcounts[l-1]; for (unsigned int k = 2; k < static_cast(vcounts[l]); ++k) { @@ -2251,13 +2244,13 @@ void ColladaLoader::Implementation::LoadPolylist( if (j == 0) triangle_index = 0; if (j == 1) - triangle_index = (k - 1) * inputSize; + triangle_index = (k-1)*inputSize; if (j == 2) triangle_index = (k)*inputSize; for (unsigned int i = 0; i < inputSize; ++i) { - values[i] = gz::math::parseInt(strs_iter[triangle_index + i]); + values[i] = gz::math::parseInt(strs_iter[triangle_index+i]); } unsigned int daeVertIndex = 0; @@ -2321,7 +2314,7 @@ void ColladaLoader::Implementation::LoadPolylist( // duplicate then reset the index to the first instance of the // duplicated texcoord unsigned int remappedTexcoordIndex = - values[offset]; + values[offset]; auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find( remappedTexcoordIndex); @@ -2358,24 +2351,24 @@ void ColladaLoader::Implementation::LoadPolylist( if (!inputs[VERTEX].empty()) { subMesh->AddVertex((*verts)[daeVertIndex]); - unsigned int newVertIndex = subMesh->VertexCount() - 1; + unsigned int newVertIndex = subMesh->VertexCount()-1; subMesh->AddIndex(newVertIndex); if (combinedVertNorms) subMesh->AddNormal((*norms)[daeVertIndex]); if (_mesh->HasSkeleton()) { subMesh->SetVertex(newVertIndex, bindShapeMat * - subMesh->Vertex(newVertIndex)); + subMesh->Vertex(newVertIndex)); SkeletonPtr skel = _mesh->MeshSkeleton(); for (unsigned int i = 0; - i < skel->VertNodeWeightCount(daeVertIndex); ++i) + i < skel->VertNodeWeightCount(daeVertIndex); ++i) { std::pair node_weight = - skel->VertNodeWeight(daeVertIndex, i); + skel->VertNodeWeight(daeVertIndex, i); SkeletonNode *node = _mesh->MeshSkeleton()->NodeByName(node_weight.first); - subMesh->AddNodeAssignment(subMesh->VertexCount() - 1, - node->Handle(), node_weight.second); + subMesh->AddNodeAssignment(subMesh->VertexCount()-1, + node->Handle(), node_weight.second); } } input.vertexIndex = daeVertIndex; @@ -2384,7 +2377,7 @@ void ColladaLoader::Implementation::LoadPolylist( if (!inputs[NORMAL].empty()) { unsigned int inputRemappedNormalIndex = - values[*inputs[NORMAL].begin()]; + values[*inputs[NORMAL].begin()]; if ((*normalDupMap).find(inputRemappedNormalIndex) != (*normalDupMap).end()) @@ -2408,7 +2401,7 @@ void ColladaLoader::Implementation::LoadPolylist( unsigned int set = pair.second; unsigned int inputRemappedTexcoordIndex = - values[offset]; + values[offset]; auto &texDupMapSet = (*texDupMap[set]); auto texDupMapSetIt = texDupMapSet.find( @@ -2434,7 +2427,7 @@ void ColladaLoader::Implementation::LoadPolylist( } } } - delete[] values; + delete [] values; _mesh->AddSubMesh(std::move(subMesh)); } @@ -2562,7 +2555,7 @@ void ColladaLoader::Implementation::LoadTriangles( { inputs[otherSemantics++].insert(gz::math::parseInt(offset)); gzwarn << "Triangle input semantic: '" << semantic << "' is currently" - << " not supported" << std::endl; + << " not supported" << std::endl; } trianglesInputXml = trianglesInputXml->NextSiblingElement("input"); } @@ -2591,12 +2584,12 @@ void ColladaLoader::Implementation::LoadTriangles( if (count) { gzerr << "Collada file[" << this->filename - << "] is invalid. Loading what we can...\n"; + << "] is invalid. Loading what we can...\n"; } else { gzlog << "Triangle input has a count of zero. " - << "This is likely not desired\n"; + << "This is likely not desired\n"; } return; @@ -2611,7 +2604,7 @@ void ColladaLoader::Implementation::LoadTriangles( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map> vertexIndexMap; + std::map > vertexIndexMap; std::vector values(offsetSize); std::vector strs = split(pStr, " \t\r\n"); @@ -2619,7 +2612,7 @@ void ColladaLoader::Implementation::LoadTriangles( for (unsigned int j = 0; j < strs.size(); j += offsetSize) { for (unsigned int i = 0; i < offsetSize; ++i) - values.at(i) = gz::math::parseInt(strs[j + i]); + values.at(i) = gz::math::parseInt(strs[j+i]); unsigned int daeVertIndex = 0; bool addIndex = !hasVertices; @@ -2714,7 +2707,7 @@ void ColladaLoader::Implementation::LoadTriangles( if (hasVertices) { subMesh->AddVertex((*verts)[daeVertIndex]); - unsigned int newVertIndex = subMesh->VertexCount() - 1; + unsigned int newVertIndex = subMesh->VertexCount()-1; subMesh->AddIndex(newVertIndex); if (combinedVertNorms) @@ -2723,20 +2716,20 @@ void ColladaLoader::Implementation::LoadTriangles( { SkeletonPtr skel = _mesh->MeshSkeleton(); for (unsigned int i = 0; - i < skel->VertNodeWeightCount(daeVertIndex); ++i) + i < skel->VertNodeWeightCount(daeVertIndex); ++i) { std::pair node_weight = - skel->VertNodeWeight(daeVertIndex, i); + skel->VertNodeWeight(daeVertIndex, i); SkeletonNode *node = _mesh->MeshSkeleton()->NodeByName(node_weight.first); if (nullptr == node) { gzerr << "Failed to find skeleton node named [" - << node_weight.first << "]" << std::endl; + << node_weight.first << "]" << std::endl; continue; } - subMesh->AddNodeAssignment(subMesh->VertexCount() - 1, - node->Handle(), node_weight.second); + subMesh->AddNodeAssignment(subMesh->VertexCount()-1, + node->Handle(), node_weight.second); } } input.vertexIndex = daeVertIndex; @@ -2790,7 +2783,7 @@ void ColladaLoader::Implementation::LoadTriangles( ///////////////////////////////////////////////// void ColladaLoader::Implementation::LoadLines(tinyxml2::XMLElement *_xml, - const gz::math::Matrix4d &_transform, Mesh *_mesh) + const gz::math::Matrix4d &_transform, Mesh *_mesh) { std::unique_ptr subMesh(new SubMesh); subMesh->SetName(this->currentNodeName); @@ -2832,16 +2825,15 @@ float ColladaLoader::Implementation::LoadFloat(tinyxml2::XMLElement *_elem) if (_elem->FirstChildElement("float")) { value = - gz::math::parseFloat(_elem->FirstChildElement("float")->GetText()); + gz::math::parseFloat(_elem->FirstChildElement("float")->GetText()); } return value; } ///////////////////////////////////////////////// -void ColladaLoader::Implementation::LoadTransparent( - tinyxml2::XMLElement *_elem, - MaterialPtr _mat) +void ColladaLoader::Implementation::LoadTransparent(tinyxml2::XMLElement *_elem, + MaterialPtr _mat) { const char *opaqueCStr = _elem->Attribute("opaque"); if (!opaqueCStr) @@ -2947,7 +2939,7 @@ void ColladaLoader::Implementation::LoadTransparent( ///////////////////////////////////////////////// void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton, - SkeletonNode *_mergeNode) + SkeletonNode *_mergeNode) { if (nullptr == _skeleton) { @@ -2986,7 +2978,7 @@ void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton, // Check if the node that will be merged contains the dummy-root // if so, replace dummyRoot bool mergeNodeContainsRoot = true; - for (unsigned int i = 0; i < currentRoot->ChildCount(); ++i) + for (unsigned int i=0; i < currentRoot->ChildCount(); ++i) { if (_mergeNode->ChildById(currentRoot->Child(i)->Id()) == nullptr) { From f0ff34f5f6802a8cb64105268fe67ae67d03b036 Mon Sep 17 00:00:00 2001 From: frederik Date: Fri, 12 Jan 2024 10:25:41 +0100 Subject: [PATCH 3/7] more linting changes Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index c69dd4e84..c01571371 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -1088,7 +1088,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, else { gzerr << "Failed to find node with ID [" << targetBone << "]" - << std::endl; + << std::endl; } } @@ -1892,13 +1892,13 @@ MaterialPtr ColladaLoader::Implementation::LoadMaterial( tinyxml2::XMLElement *effectXml = this->ElementId("effect", effectName); tinyxml2::XMLElement *commonXml = - effectXml->FirstChildElement("profile_COMMON"); + effectXml->FirstChildElement("profile_COMMON"); if (commonXml) { tinyxml2::XMLElement *techniqueXml = - commonXml->FirstChildElement("technique"); + commonXml->FirstChildElement("technique"); tinyxml2::XMLElement *lambertXml = - techniqueXml->FirstChildElement("lambert"); + techniqueXml->FirstChildElement("lambert"); tinyxml2::XMLElement *phongXml = techniqueXml->FirstChildElement("phong"); tinyxml2::XMLElement *blinnXml = techniqueXml->FirstChildElement("blinn"); @@ -2725,7 +2725,7 @@ void ColladaLoader::Implementation::LoadTriangles( if (nullptr == node) { gzerr << "Failed to find skeleton node named [" - << node_weight.first << "]" << std::endl; + << node_weight.first << "]" << std::endl; continue; } subMesh->AddNodeAssignment(subMesh->VertexCount()-1, @@ -2777,7 +2777,6 @@ void ColladaLoader::Implementation::LoadTriangles( } } - _mesh->AddSubMesh(std::move(subMesh)); } From baa748a4c9df0f7f1edf34996fbfebdd9e15a956 Mon Sep 17 00:00:00 2001 From: frederik Date: Fri, 12 Jan 2024 12:20:26 +0100 Subject: [PATCH 4/7] more optimizations. Remove iss, move ptr check conditions outside of loop, use emplace_back Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 202 +++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 75 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index c01571371..b36c270b5 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -884,7 +884,7 @@ void ColladaLoader::Implementation::LoadController( std::vector weights; for (unsigned int i = 0; i < wStrs.size(); ++i) - weights.push_back(math::parseFloat(wStrs[i])); + weights.emplace_back(math::parseFloat(wStrs[i])); std::string cString = vertWeightsXml->FirstChildElement("vcount")->GetText(); std::string vString = vertWeightsXml->FirstChildElement("v")->GetText(); @@ -895,10 +895,10 @@ void ColladaLoader::Implementation::LoadController( std::vector v; for (unsigned int i = 0; i < vCountStrs.size(); ++i) - vCount.push_back(math::parseInt(vCountStrs[i])); + vCount.emplace_back(math::parseInt(vCountStrs[i])); for (unsigned int i = 0; i < vStrs.size(); ++i) - v.push_back(math::parseInt(vStrs[i])); + v.emplace_back(math::parseInt(vStrs[i])); skeleton->SetNumVertAttached(vCount.size()); @@ -1027,7 +1027,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, std::vector times; for (unsigned int i = 0; i < timeStrs.size(); ++i) - times.push_back(math::parseFloat(timeStrs[i])); + times.emplace_back(math::parseFloat(timeStrs[i])); tinyxml2::XMLElement *output = frameTransXml->FirstChildElement("float_array"); @@ -1036,7 +1036,7 @@ void ColladaLoader::Implementation::LoadAnimationSet(tinyxml2::XMLElement *_xml, std::vector values; for (unsigned int i = 0; i < outputStrs.size(); ++i) - values.push_back(math::parseFloat(outputStrs[i])); + values.emplace_back(math::parseFloat(outputStrs[i])); tinyxml2::XMLElement *accessor = frameTransXml->FirstChildElement("technique_common"); @@ -1541,6 +1541,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, auto toDoubleVec = [](std::string_view sv, size_t totalCount) { std::vector result; + // Preallocate memory based on known count result.reserve(totalCount * 3); const char *start = sv.data(); char *end{}; @@ -1552,40 +1553,33 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, start = end; if (errno == ERANGE) throw std::runtime_error("strtod() overflow"); - result.push_back(d); + result.emplace_back(d); } return result; }; auto values = toDoubleVec(valueStr, totCount); + + gz::math::Vector3d vec; + if (!_values) + _values = std::make_shared>(); + if (!_duplicates) + _duplicates = std::make_shared>(); for (int i = 0; i < totCount; i += stride) { - gz::math::Vector3d vec(values[i], - values[i+1], - values[i+2]); + vec.Set(values[i], + values[i+1], + values[i+2]); vec = _transform * vec; - if (!_values) - { - _values = std::make_shared>(); - } - (*_values).push_back(vec); - - if (!_duplicates) - { - _duplicates = std::make_shared>(); - } + (*_values).emplace_back(vec); // create a map of duplicate indices if (unique.find(vec) != unique.end()) - { (*_duplicates)[(*_values).size()-1] = unique[vec]; - } else - { unique[vec] = (*_values).size()-1; - } } this->positionDuplicateMap[_id] = _duplicates; @@ -1618,6 +1612,10 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, tinyxml2::XMLElement *floatArrayXml = normalsXml->FirstChildElement("float_array"); + + int totCount = 0; + int stride = 0; + if (!floatArrayXml || !floatArrayXml->GetText()) { int count = 1; @@ -1635,7 +1633,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, if (count) { - gzwarn << "Normal source missing float_array element, or count is " + gzerr << "Normal source missing float_array element, or count is " << "invalid.\n"; } else @@ -1646,43 +1644,103 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, return; } + // Read in the total number of normal coordinate values + else if (floatArrayXml->Attribute("count")) + totCount = std::stoi(floatArrayXml->Attribute("count")); + else + { + gzerr << " has no count attribute in normal coordinate " + << "element with id[" << _id << "]\n"; + return; + } + + normalsXml = normalsXml->FirstChildElement("technique_common"); + if (!normalsXml) + { + gzerr << "Unable to find technique_common element for normals " + << "coordinates with id[" << _id << "]\n"; + return; + } + + // Get the accessor XML element. + normalsXml = normalsXml->FirstChildElement("accessor"); + if (!normalsXml) + { + gzerr << "Unable to find as a child of " + << "for normals coordinates with id[" << _id << "]\n"; + return; + } + + // Read in the stride for the normals coordinate values. The stride + // indicates the number of values in the float array the comprise + // a complete normal coordinate. + if (normalsXml->Attribute("stride")) + { + stride = std::stoi(normalsXml->Attribute("stride")); + } + else + { + gzerr << " has no stride attribute in normal coordinate " + << "element with id[" << _id << "]\n"; + return; + } + + // Nothing to read. Don't print a warning because the collada file is + // correct. + if (totCount == 0) + return; std::unordered_map unique; std::string valueStr = floatArrayXml->GetText(); - std::istringstream iss(valueStr); - do + // std::istringstream iss(valueStr); + + auto toDoubleVec = [](std::string_view sv, size_t totalCount) { - gz::math::Vector3d vec; - iss >> vec.X() >> vec.Y() >> vec.Z(); - if (iss) + std::vector result; + // Preallocate memory based on known count + result.reserve(totalCount * 3); + const char *start = sv.data(); + char *end{}; + while (true) { - vec = rotMat * vec; - vec.Normalize(); - if (!_values) - { - _values = std::make_shared>(); - } - (*_values).push_back(vec); + double d = std::strtod(start, &end); + if (start == end) + break; + start = end; + if (errno == ERANGE) + throw std::runtime_error("strtod() overflow"); + result.emplace_back(d); + } + return result; + }; - if (!_duplicates) - { + auto values = toDoubleVec(valueStr, totCount); + + gz::math::Vector3d vec; + if (!_values) + _values = std::make_shared>(); + if (!_duplicates) _duplicates = std::make_shared>(); - } - // create a map of duplicate indices - if (unique.find(vec) != unique.end()) - { - (*_duplicates)[(*_values).size()-1] = unique[vec]; - } - else - { - unique[vec] = (*_values).size()-1; - } - } - } while (iss); + for (int i = 0; i < totCount; i += stride) + { + vec.Set(values[i], + values[i+1], + values[i+2]); + + vec = rotMat * vec; + vec.Normalize(); + (*_values).emplace_back(vec); + + // create a map of duplicate indices + if (unique.find(vec) != unique.end()) + (*_duplicates)[(*_values).size()-1] = unique[vec]; + else + unique[vec] = (*_values).size()-1; + } this->normalDuplicateMap[_id] = _duplicates; this->normalIds[_id] = _values; @@ -1820,6 +1878,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, auto toDoubleVec = [](std::string_view sv, size_t totalCount) { std::vector result; + // Preallocate memory based on known count result.reserve(totalCount * 2); const char *start = sv.data(); char *end{}; @@ -1831,7 +1890,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, start = end; if (errno == ERANGE) throw std::runtime_error("strtod() overflow"); - result.push_back(d); + result.emplace_back(d); } return result; }; @@ -1840,30 +1899,23 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, std::string valueStr = floatArrayXml->GetText(); auto values = toDoubleVec(valueStr, totCount); + gz::math::Vector2d vec; + if (!_values) + _values = std::make_shared>(); + if (!_duplicates) + _duplicates = std::make_shared>(); // Read in all the texture coordinates. for (int i = 0; i < totCount; i += stride) { // We only handle 2D texture coordinates right now. - gz::math::Vector2d vec(values[i], - 1.0 - values[i + 1]); - - if (!_values) - { - _values = std::make_shared>(); - } - (*_values).push_back(vec); - - if (!_duplicates) - { - _duplicates = std::make_shared>(); - } + vec.Set(values[i], + 1.0 - values[i + 1]); + (*_values).emplace_back(vec); // create a map of duplicate indices if (unique.find(vec) != unique.end()) - { (*_duplicates)[(*_values).size()-1] = unique[vec]; - } else unique[vec] = (*_values).size()-1; } @@ -2187,7 +2239,7 @@ void ColladaLoader::Implementation::LoadPolylist( set = gz::math::parseInt(setStr); this->LoadTexCoords(source, texcoords[set], texDupMap[set]); inputs[TEXCOORD].insert(offsetInt); - texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set)); + texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set)); } else { @@ -2211,7 +2263,7 @@ void ColladaLoader::Implementation::LoadPolylist( std::vector vcountStrs = split(vcountStr, " \t\r\n"); std::vector vcounts; for (unsigned int j = 0; j < vcountStrs.size(); ++j) - vcounts.push_back(math::parseInt(vcountStrs[j])); + vcounts.emplace_back(math::parseInt(vcountStrs[j])); // read p tinyxml2::XMLElement *pXml = _polylistXml->FirstChildElement("p"); @@ -2420,7 +2472,7 @@ void ColladaLoader::Implementation::LoadPolylist( if (!inputs[VERTEX].empty()) { std::vector inputValues; - inputValues.push_back(input); + inputValues.emplace_back(input); vertexIndexMap[daeVertIndex] = inputValues; } } @@ -2548,7 +2600,7 @@ void ColladaLoader::Implementation::LoadTriangles( set = gz::math::parseInt(setStr); this->LoadTexCoords(source, texcoords[set], texDupMap[set]); inputs[TEXCOORD].insert(offsetInt); - texcoordsOffsetToSet.push_back(std::make_pair(offsetInt, set)); + texcoordsOffsetToSet.emplace_back(std::make_pair(offsetInt, set)); hasTexcoords = true; } else @@ -2771,7 +2823,7 @@ void ColladaLoader::Implementation::LoadTriangles( if (hasVertices) { std::vector inputValues; - inputValues.push_back(input); + inputValues.emplace_back(input); vertexIndexMap[daeVertIndex] = inputValues; } } @@ -3014,7 +3066,7 @@ void ColladaLoader::Implementation::MergeSkeleton(SkeletonPtr _skeleton, void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton) { std::list queue; - queue.push_back(_skeleton->RootNode()); + queue.emplace_back(_skeleton->RootNode()); while (!queue.empty()) { @@ -3026,6 +3078,6 @@ void ColladaLoader::Implementation::ApplyInvBindTransform(SkeletonPtr _skeleton) if (node->HasInvBindTransform()) node->SetModelTransform(node->InverseBindTransform().Inverse(), false); for (unsigned int i = 0; i < node->ChildCount(); i++) - queue.push_back(node->Child(i)); + queue.emplace_back(node->Child(i)); } } From d5322d281faad700eca513cb6b8b47230a79b564 Mon Sep 17 00:00:00 2001 From: frederik Date: Fri, 12 Jan 2024 13:40:03 +0100 Subject: [PATCH 5/7] more improvements, reduce find() time Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index b36c270b5..ba896b100 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -1561,6 +1561,7 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector3d vec; + std::shared_ptr prev_vec = std::make_shared(gz::math::Vector3d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1576,10 +1577,16 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, (*_values).emplace_back(vec); // create a map of duplicate indices - if (unique.find(vec) != unique.end()) - (*_duplicates)[(*_values).size()-1] = unique[vec]; + if((*prev_vec) != vec){ + if (unique.find(vec) != unique.end()) + (*_duplicates)[(*_values).size()-1] = unique[vec]; + else + unique[vec] = (*_values).size()-1; + } else unique[vec] = (*_values).size()-1; + + (*prev_vec) = vec; } this->positionDuplicateMap[_id] = _duplicates; @@ -1719,6 +1726,7 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector3d vec; + std::shared_ptr prev_vec = std::make_shared(gz::math::Vector3d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1736,10 +1744,16 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, (*_values).emplace_back(vec); // create a map of duplicate indices - if (unique.find(vec) != unique.end()) - (*_duplicates)[(*_values).size()-1] = unique[vec]; + if((*prev_vec) != vec){ + if (unique.find(vec) != unique.end()) + (*_duplicates)[(*_values).size()-1] = unique[vec]; + else + unique[vec] = (*_values).size()-1; + } else unique[vec] = (*_values).size()-1; + + (*prev_vec) = vec; } this->normalDuplicateMap[_id] = _duplicates; @@ -1900,6 +1914,7 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector2d vec; + std::shared_ptr prev_vec = std::make_shared(gz::math::Vector2d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1911,13 +1926,20 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, // We only handle 2D texture coordinates right now. vec.Set(values[i], 1.0 - values[i + 1]); + // std::cout << "vector is: " << vec << std::endl; (*_values).emplace_back(vec); // create a map of duplicate indices - if (unique.find(vec) != unique.end()) - (*_duplicates)[(*_values).size()-1] = unique[vec]; + if((*prev_vec) != vec){ + if (unique.find(vec) != unique.end()) + (*_duplicates)[(*_values).size()-1] = unique[vec]; + else + unique[vec] = (*_values).size()-1; + } else unique[vec] = (*_values).size()-1; + + (*prev_vec) = vec; } this->texcoordDuplicateMap[_id] = _duplicates; From 6911db6a9c890bedcb4ddd04f018f56902fb3117 Mon Sep 17 00:00:00 2001 From: frederik Date: Fri, 12 Jan 2024 14:04:09 +0100 Subject: [PATCH 6/7] more minor improvements Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index ba896b100..d87c079ee 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -1561,7 +1561,8 @@ void ColladaLoader::Implementation::LoadPositions(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector3d vec; - std::shared_ptr prev_vec = std::make_shared(gz::math::Vector3d::Zero); + std::shared_ptr prev_vec = + std::make_shared(gz::math::Vector3d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1726,7 +1727,8 @@ void ColladaLoader::Implementation::LoadNormals(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector3d vec; - std::shared_ptr prev_vec = std::make_shared(gz::math::Vector3d::Zero); + std::shared_ptr prev_vec = + std::make_shared(gz::math::Vector3d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1914,7 +1916,8 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, auto values = toDoubleVec(valueStr, totCount); gz::math::Vector2d vec; - std::shared_ptr prev_vec = std::make_shared(gz::math::Vector2d::Zero); + std::shared_ptr prev_vec = + std::make_shared(gz::math::Vector2d::Zero); if (!_values) _values = std::make_shared>(); if (!_duplicates) @@ -1926,7 +1929,6 @@ void ColladaLoader::Implementation::LoadTexCoords(const std::string &_id, // We only handle 2D texture coordinates right now. vec.Set(values[i], 1.0 - values[i + 1]); - // std::cout << "vector is: " << vec << std::endl; (*_values).emplace_back(vec); // create a map of duplicate indices @@ -2293,7 +2295,7 @@ void ColladaLoader::Implementation::LoadPolylist( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map > vertexIndexMap; + std::unordered_map> vertexIndexMap; unsigned int *values = new unsigned int[inputSize]; memset(values, 0, inputSize); @@ -2678,7 +2680,7 @@ void ColladaLoader::Implementation::LoadTriangles( // vertexIndexMap is a map of collada vertex index to Gazebo submesh vertex // indices, used for identifying vertices that can be shared. - std::map > vertexIndexMap; + std::unordered_map> vertexIndexMap; std::vector values(offsetSize); std::vector strs = split(pStr, " \t\r\n"); From f4962c00209c6dfa8b52f48245810443940d392a Mon Sep 17 00:00:00 2001 From: frederik Date: Sat, 13 Jan 2024 13:37:17 +0100 Subject: [PATCH 7/7] fix two of three seg faults Signed-off-by: frederik --- graphics/src/ColladaLoader.cc | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/graphics/src/ColladaLoader.cc b/graphics/src/ColladaLoader.cc index d87c079ee..f8ddcb850 100644 --- a/graphics/src/ColladaLoader.cc +++ b/graphics/src/ColladaLoader.cc @@ -2241,11 +2241,21 @@ void ColladaLoader::Implementation::LoadPolylist( std::string offset = polylistInputXml->Attribute("offset"); if (semantic == "VERTEX") { - unsigned int count = (*norms).size(); + unsigned int count; + if (!norms || norms->empty()) + count = 0; + else + count = (*norms).size(); + this->LoadVertices(source, _transform, verts, norms, positionDupMap, normalDupMap); - if ((*norms).size() > count) - combinedVertNorms = true; + + if (norms && !norms->empty()) + { + if ((*norms).size() > count) + combinedVertNorms = true; + } + inputs[VERTEX].insert(gz::math::parseInt(offset)); } else if (semantic == "NORMAL") @@ -2581,22 +2591,17 @@ void ColladaLoader::Implementation::LoadTriangles( { unsigned int count; if (!norms || norms->empty()) - { count = 0; - } else - { count = (*norms).size(); - } + this->LoadVertices(source, _transform, verts, norms, positionDupMap, normalDupMap); if (norms && !norms->empty()) { if ((*norms).size() > count) - { combinedVertNorms = true; - } } inputs[VERTEX].insert(gz::math::parseInt(offset)); hasVertices = true; @@ -2610,9 +2615,7 @@ void ColladaLoader::Implementation::LoadTriangles( if (norms && !norms->empty()) { if ((*norms).size() > 0) - { hasNormals = true; - } } } else if (semantic == "TEXCOORD")