diff --git a/Migration.md b/Migration.md
index a9cc6a395..68d8d3275 100644
--- a/Migration.md
+++ b/Migration.md
@@ -45,6 +45,10 @@ but with improved human-readability..
+ const Frame \*FrameByIndex(const uint64\_t) const
+ const Frame \*FrameByName(const std::string &) const
+ bool FrameNameExists(const std::string &) const
+ + uint64\_t ModelCount() const
+ + const Model \*ModelByIndex(const uint64\_t) const
+ + const Model \*ModelByName(const std::string &) const
+ + bool ModelNameExists(const std::string &) const
+ sdf::SemanticPose SemanticPose() const
1. **sdf/SDFImpl.hh**
diff --git a/include/sdf/Model.hh b/include/sdf/Model.hh
index 018801982..d63899807 100644
--- a/include/sdf/Model.hh
+++ b/include/sdf/Model.hh
@@ -198,6 +198,29 @@ namespace sdf
/// \return True if there exists an explicit frame with the given name.
public: bool FrameNameExists(const std::string &_name) const;
+ /// \brief Get the number of nested models.
+ /// \return Number of nested models contained in this Model object.
+ public: uint64_t ModelCount() const;
+
+ /// \brief Get a nested model based on an index.
+ /// \param[in] _index Index of the nested model. The index should be in the
+ /// range [0..ModelCount()).
+ /// \return Pointer to the model. Nullptr if the index does not exist.
+ /// \sa uint64_t ModelCount() const
+ public: const Model *ModelByIndex(const uint64_t _index) const;
+
+ /// \brief Get whether a nested model name exists.
+ /// \param[in] _name Name of the nested model to check.
+ /// \return True if there exists a nested model with the given name.
+ public: bool ModelNameExists(const std::string &_name) const;
+
+ /// \brief Get a nested model based on a name.
+ /// \param[in] _name Name of the nested model.
+ /// \return Pointer to the model. Nullptr if a model with the given name
+ /// does not exist.
+ /// \sa bool ModelNameExists(const std::string &_name) const
+ public: const Model *ModelByName(const std::string &_name) const;
+
/// \brief Get the pose of the model. This is the pose of the model
/// as specified in SDF ( ... ), and is
/// typically used to express the position and rotation of a model in a
diff --git a/src/Model.cc b/src/Model.cc
index fe8be53ee..656ba2977 100644
--- a/src/Model.cc
+++ b/src/Model.cc
@@ -67,6 +67,9 @@ class sdf::ModelPrivate
/// \brief The frames specified in this model.
public: std::vector frames;
+ /// \brief The nested models specified in this model.
+ public: std::vector models;
+
/// \brief The SDF element pointer used during load.
public: sdf::ElementPtr sdf;
@@ -527,6 +530,46 @@ const Frame *Model::FrameByName(const std::string &_name) const
return nullptr;
}
+/////////////////////////////////////////////////
+uint64_t Model::ModelCount() const
+{
+ return this->dataPtr->models.size();
+}
+
+/////////////////////////////////////////////////
+const Model *Model::ModelByIndex(const uint64_t _index) const
+{
+ if (_index < this->dataPtr->models.size())
+ return &this->dataPtr->models[_index];
+ return nullptr;
+}
+
+/////////////////////////////////////////////////
+bool Model::ModelNameExists(const std::string &_name) const
+{
+ for (auto const &m : this->dataPtr->models)
+ {
+ if (m.Name() == _name)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+/////////////////////////////////////////////////
+const Model *Model::ModelByName(const std::string &_name) const
+{
+ for (auto const &m : this->dataPtr->models)
+ {
+ if (m.Name() == _name)
+ {
+ return &m;
+ }
+ }
+ return nullptr;
+}
+
/////////////////////////////////////////////////
const Link *Model::CanonicalLink() const
{