diff --git a/include/sdf/Box.hh b/include/sdf/Box.hh index 9ac7fa219..2ba1ee9fa 100644 --- a/include/sdf/Box.hh +++ b/include/sdf/Box.hh @@ -65,6 +65,11 @@ namespace sdf /// \return A reference to an ignition::math::Boxd object. public: ignition::math::Boxd &Shape(); + /// \brief Create and return an SDF element filled with data from this + /// box. + /// \return SDF element pointer with updated box values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Capsule.hh b/include/sdf/Capsule.hh index 76a91f077..56ffbe6b3 100644 --- a/include/sdf/Capsule.hh +++ b/include/sdf/Capsule.hh @@ -72,6 +72,11 @@ namespace sdf /// \return A reference to an ignition::math::Capsuled object. public: ignition::math::Capsuled &Shape(); + /// \brief Create and return an SDF element filled with data from this + /// capsule. + /// \return SDF element pointer with updated capsule values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Cylinder.hh b/include/sdf/Cylinder.hh index 9a48b59a5..606399b21 100644 --- a/include/sdf/Cylinder.hh +++ b/include/sdf/Cylinder.hh @@ -72,6 +72,11 @@ namespace sdf /// \return A reference to an ignition::math::Cylinderd object. public: ignition::math::Cylinderd &Shape(); + /// \brief Create and return an SDF element filled with data from this + /// cylinder. + /// \return SDF element pointer with updated cylinder values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Ellipsoid.hh b/include/sdf/Ellipsoid.hh index fadd4ed81..fa18e9eed 100644 --- a/include/sdf/Ellipsoid.hh +++ b/include/sdf/Ellipsoid.hh @@ -64,6 +64,11 @@ namespace sdf /// \return A reference to an ignition::math::Ellipsoidd object. public: ignition::math::Ellipsoidd &Shape(); + /// \brief Create and return an SDF element filled with data from this + /// ellipsoid. + /// \return SDF element pointer with updated ellipsoid values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Heightmap.hh b/include/sdf/Heightmap.hh index 11a664b56..a08a1706d 100644 --- a/include/sdf/Heightmap.hh +++ b/include/sdf/Heightmap.hh @@ -47,8 +47,8 @@ namespace sdf public: double Size() const; /// \brief Set the size of the texture in meters. - /// \param[in] _uri The size of the texture in meters. - public: void SetSize(double _uri); + /// \param[in] _size The size of the texture in meters. + public: void SetSize(double _size); /// \brief Get the heightmap texture's diffuse map. /// \return The diffuse map of the heightmap texture. @@ -214,6 +214,11 @@ namespace sdf /// not been called. public: sdf::ElementPtr Element() const; + /// \brief Create and return an SDF element filled with data from this + /// heightmap. + /// \return SDF element pointer with updated heightmap values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Mesh.hh b/include/sdf/Mesh.hh index b75349200..7636534d3 100644 --- a/include/sdf/Mesh.hh +++ b/include/sdf/Mesh.hh @@ -97,6 +97,11 @@ namespace sdf /// not been called. public: sdf::ElementPtr Element() const; + /// \brief Create and return an SDF element filled with data from this + /// mesh. + /// \return SDF element pointer with updated mesh values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Plane.hh b/include/sdf/Plane.hh index c0ea5a4d7..e02de22e1 100644 --- a/include/sdf/Plane.hh +++ b/include/sdf/Plane.hh @@ -80,6 +80,11 @@ namespace sdf /// \return A reference to an ignition::math::Planed object. public: ignition::math::Planed &Shape(); + /// \brief Create and return an SDF element filled with data from this + /// plane. + /// \return SDF element pointer with updated plane values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/include/sdf/Sphere.hh b/include/sdf/Sphere.hh index 10d91b897..42f8da4c5 100644 --- a/include/sdf/Sphere.hh +++ b/include/sdf/Sphere.hh @@ -65,6 +65,11 @@ namespace sdf /// not been called. public: sdf::ElementPtr Element() const; + /// \brief Create and return an SDF element filled with data from this + /// sphere. + /// \return SDF element pointer with updated sphere values. + public: sdf::ElementPtr ToElement() const; + /// \brief Private data pointer. IGN_UTILS_IMPL_PTR(dataPtr) }; diff --git a/src/Box.cc b/src/Box.cc index 90ceb26e3..6c029dac0 100644 --- a/src/Box.cc +++ b/src/Box.cc @@ -16,6 +16,7 @@ */ #include #include "sdf/Box.hh" +#include "sdf/parser.hh" using namespace sdf; @@ -112,3 +113,15 @@ ignition::math::Boxd &Box::Shape() { return this->dataPtr->box; } + +///////////////////////////////////////////////// +sdf::ElementPtr Box::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("box_shape.sdf", elem); + + sdf::ElementPtr sizeElem = elem->GetElement("size"); + sizeElem->Set(this->Size()); + + return elem; +} diff --git a/src/Box_TEST.cc b/src/Box_TEST.cc index b77bd23a7..762d0a0b9 100644 --- a/src/Box_TEST.cc +++ b/src/Box_TEST.cc @@ -143,3 +143,19 @@ TEST(DOMBox, Shape) box.Shape().SetSize(ignition::math::Vector3d(1, 2, 3)); EXPECT_EQ(ignition::math::Vector3d(1, 2, 3), box.Size()); } + +///////////////////////////////////////////////// +TEST(DOMBox, ToElement) +{ + sdf::Box box; + + box.SetSize(ignition::math::Vector3d(1, 2, 3)); + + sdf::ElementPtr elem = box.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Box box2; + box2.Load(elem); + + EXPECT_EQ(box.Size(), box2.Size()); +} diff --git a/src/Capsule.cc b/src/Capsule.cc index 507cbe0c4..a99159d69 100644 --- a/src/Capsule.cc +++ b/src/Capsule.cc @@ -16,6 +16,7 @@ */ #include #include "sdf/Capsule.hh" +#include "sdf/parser.hh" using namespace sdf; @@ -134,3 +135,18 @@ ignition::math::Capsuled &Capsule::Shape() { return this->dataPtr->capsule; } + +///////////////////////////////////////////////// +sdf::ElementPtr Capsule::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("capsule_shape.sdf", elem); + + sdf::ElementPtr radiusElem = elem->GetElement("radius"); + radiusElem->Set(this->Radius()); + + sdf::ElementPtr lengthElem = elem->GetElement("length"); + lengthElem->Set(this->Length()); + + return elem; +} diff --git a/src/Capsule_TEST.cc b/src/Capsule_TEST.cc index 20b55c644..9c66d9797 100644 --- a/src/Capsule_TEST.cc +++ b/src/Capsule_TEST.cc @@ -179,3 +179,21 @@ TEST(DOMCapsule, Shape) EXPECT_DOUBLE_EQ(0.123, capsule.Radius()); EXPECT_DOUBLE_EQ(0.456, capsule.Length()); } + +///////////////////////////////////////////////// +TEST(DOMCapsule, ToElement) +{ + sdf::Capsule capsule; + + capsule.SetRadius(1.2); + capsule.SetLength(0.5); + + sdf::ElementPtr elem = capsule.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Capsule capsule2; + capsule2.Load(elem); + + EXPECT_DOUBLE_EQ(capsule.Radius(), capsule2.Radius()); + EXPECT_DOUBLE_EQ(capsule.Length(), capsule2.Length()); +} diff --git a/src/Cylinder.cc b/src/Cylinder.cc index c04de1592..681ea8440 100644 --- a/src/Cylinder.cc +++ b/src/Cylinder.cc @@ -16,6 +16,7 @@ */ #include #include "sdf/Cylinder.hh" +#include "sdf/parser.hh" using namespace sdf; @@ -134,3 +135,18 @@ ignition::math::Cylinderd &Cylinder::Shape() { return this->dataPtr->cylinder; } + +///////////////////////////////////////////////// +sdf::ElementPtr Cylinder::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("cylinder_shape.sdf", elem); + + sdf::ElementPtr radiusElem = elem->GetElement("radius"); + radiusElem->Set(this->Radius()); + + sdf::ElementPtr lengthElem = elem->GetElement("length"); + lengthElem->Set(this->Length()); + + return elem; +} diff --git a/src/Cylinder_TEST.cc b/src/Cylinder_TEST.cc index 741dc77d4..7493f6f8b 100644 --- a/src/Cylinder_TEST.cc +++ b/src/Cylinder_TEST.cc @@ -175,3 +175,21 @@ TEST(DOMCylinder, Shape) EXPECT_DOUBLE_EQ(0.123, cylinder.Radius()); EXPECT_DOUBLE_EQ(0.456, cylinder.Length()); } + +///////////////////////////////////////////////// +TEST(DOMCylinder, ToElement) +{ + sdf::Cylinder cylinder; + + cylinder.SetRadius(1.2); + cylinder.SetLength(0.5); + + sdf::ElementPtr elem = cylinder.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Cylinder cylinder2; + cylinder2.Load(elem); + + EXPECT_DOUBLE_EQ(cylinder.Radius(), cylinder2.Radius()); + EXPECT_DOUBLE_EQ(cylinder.Length(), cylinder2.Length()); +} diff --git a/src/Ellipsoid.cc b/src/Ellipsoid.cc index 694b9a1e1..8ef41b49a 100644 --- a/src/Ellipsoid.cc +++ b/src/Ellipsoid.cc @@ -16,6 +16,7 @@ */ #include #include "sdf/Ellipsoid.hh" +#include "sdf/parser.hh" using namespace sdf; @@ -113,3 +114,15 @@ ignition::math::Ellipsoidd &Ellipsoid::Shape() { return this->dataPtr->ellipsoid; } + +///////////////////////////////////////////////// +sdf::ElementPtr Ellipsoid::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("ellipsoid_shape.sdf", elem); + + sdf::ElementPtr radiiElem = elem->GetElement("radii"); + radiiElem->Set(this->Radii()); + + return elem; +} diff --git a/src/Ellipsoid_TEST.cc b/src/Ellipsoid_TEST.cc index 8a4bf4138..d05556f68 100644 --- a/src/Ellipsoid_TEST.cc +++ b/src/Ellipsoid_TEST.cc @@ -139,3 +139,19 @@ TEST(DOMEllipsoid, Shape) ellipsoid.Shape().SetRadii(expectedRadii); EXPECT_EQ(expectedRadii, ellipsoid.Radii()); } + +///////////////////////////////////////////////// +TEST(DOMEllipsoid, ToElement) +{ + sdf::Ellipsoid ellipsoid; + + ellipsoid.SetRadii(ignition::math::Vector3d(0.1, 1.2, 3.4)); + + sdf::ElementPtr elem = ellipsoid.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Ellipsoid ellipsoid2; + ellipsoid2.Load(elem); + + EXPECT_EQ(ellipsoid.Radii(), ellipsoid2.Radii()); +} diff --git a/src/Heightmap.cc b/src/Heightmap.cc index 8d018730f..9583192f1 100644 --- a/src/Heightmap.cc +++ b/src/Heightmap.cc @@ -19,6 +19,7 @@ #include "Utils.hh" #include "sdf/Heightmap.hh" +#include "sdf/parser.hh" using namespace sdf; @@ -459,3 +460,49 @@ void Heightmap::AddBlend(const HeightmapBlend &_blend) { this->dataPtr->blends.push_back(_blend); } + +///////////////////////////////////////////////// +sdf::ElementPtr Heightmap::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("heightmap_shape.sdf", elem); + + // Uri + sdf::ElementPtr uriElem = elem->GetElement("uri"); + uriElem->Set(this->Uri()); + + // Size + sdf::ElementPtr sizeElem = elem->GetElement("size"); + sizeElem->Set(this->Size()); + + // Position + sdf::ElementPtr posElem = elem->GetElement("pos"); + posElem->Set(this->Position()); + + // Terrain paging + sdf::ElementPtr pagingElem = elem->GetElement("use_terrain_paging"); + pagingElem->Set(this->UseTerrainPaging()); + + // Sampling + sdf::ElementPtr samplingElem = elem->GetElement("sampling"); + samplingElem->Set(this->Sampling()); + + // Textures + for (const HeightmapTexture &tex : this->dataPtr->textures) + { + sdf::ElementPtr texElem = elem->AddElement("texture"); + texElem->GetElement("size")->Set(tex.Size()); + texElem->GetElement("diffuse")->Set(tex.Diffuse()); + texElem->GetElement("normal")->Set(tex.Normal()); + } + + // Blends + for (const HeightmapBlend &blend : this->dataPtr->blends) + { + sdf::ElementPtr blendElem = elem->AddElement("blend"); + blendElem->GetElement("min_height")->Set(blend.MinHeight()); + blendElem->GetElement("fade_dist")->Set(blend.FadeDistance()); + } + + return elem; +} diff --git a/src/Heightmap_TEST.cc b/src/Heightmap_TEST.cc index 4cd1b1dc9..fe45184a9 100644 --- a/src/Heightmap_TEST.cc +++ b/src/Heightmap_TEST.cc @@ -406,3 +406,53 @@ TEST(DOMHeightmap, LoadErrors) "missing a ")); EXPECT_NE(nullptr, heightmapBlend.Element()); } + +///////////////////////////////////////////////// +TEST(DOMHeightmap, ToElement) +{ + sdf::Heightmap heightmap; + + heightmap.SetUri("https://test-uri.org"); + heightmap.SetSize(ignition::math::Vector3d(1, 2, 3)); + heightmap.SetPosition(ignition::math::Vector3d(4, 5, 6)); + heightmap.SetUseTerrainPaging(true); + heightmap.SetSampling(2); + + sdf::HeightmapTexture texture; + texture.SetSize(1.2); + texture.SetDiffuse("diffuse_map"); + texture.SetNormal("normal_map"); + heightmap.AddTexture(texture); + + sdf::HeightmapBlend blend; + blend.SetMinHeight(1.2); + blend.SetFadeDistance(3.4); + heightmap.AddBlend(blend); + + sdf::ElementPtr elem = heightmap.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Heightmap heightmap2; + heightmap2.Load(elem); + + EXPECT_EQ(heightmap.Uri(), heightmap2.Uri()); + EXPECT_EQ(heightmap.Size(), heightmap2.Size()); + EXPECT_EQ(heightmap.Position(), heightmap2.Position()); + EXPECT_EQ(heightmap.UseTerrainPaging(), heightmap2.UseTerrainPaging()); + EXPECT_EQ(heightmap.Sampling(), heightmap2.Sampling()); + EXPECT_EQ(heightmap.TextureCount(), heightmap2.TextureCount()); + ASSERT_EQ(1u, heightmap2.TextureCount()); + EXPECT_DOUBLE_EQ(heightmap.TextureByIndex(0)->Size(), + heightmap2.TextureByIndex(0)->Size()); + EXPECT_EQ(heightmap.TextureByIndex(0)->Diffuse(), + heightmap2.TextureByIndex(0)->Diffuse()); + EXPECT_EQ(heightmap.TextureByIndex(0)->Normal(), + heightmap2.TextureByIndex(0)->Normal()); + + EXPECT_EQ(heightmap.BlendCount(), heightmap2.BlendCount()); + ASSERT_EQ(1u, heightmap2.BlendCount()); + EXPECT_DOUBLE_EQ(heightmap.BlendByIndex(0)->MinHeight(), + heightmap2.BlendByIndex(0)->MinHeight()); + EXPECT_DOUBLE_EQ(heightmap.BlendByIndex(0)->FadeDistance(), + heightmap2.BlendByIndex(0)->FadeDistance()); +} diff --git a/src/Mesh.cc b/src/Mesh.cc index 553623c3f..b517b98c0 100644 --- a/src/Mesh.cc +++ b/src/Mesh.cc @@ -14,6 +14,7 @@ * limitations under the License. * */ +#include "sdf/parser.hh" #include "sdf/Mesh.hh" using namespace sdf; @@ -176,3 +177,32 @@ void Mesh::SetCenterSubmesh(const bool _center) { this->dataPtr->centerSubmesh = _center; } + +///////////////////////////////////////////////// +sdf::ElementPtr Mesh::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("mesh_shape.sdf", elem); + + // Uri + sdf::ElementPtr uriElem = elem->GetElement("uri"); + uriElem->Set(this->Uri()); + + // Submesh + if (!this->dataPtr->submesh.empty()) + { + sdf::ElementPtr subMeshElem = elem->GetElement("submesh"); + + sdf::ElementPtr subMeshNameElem = subMeshElem->GetElement("name"); + subMeshNameElem->Set(this->dataPtr->submesh); + + sdf::ElementPtr subMeshCenterElem = subMeshElem->GetElement("center"); + subMeshCenterElem->Set(this->dataPtr->centerSubmesh); + } + + // Scale + sdf::ElementPtr scaleElem = elem->GetElement("scale"); + scaleElem->Set(this->Scale()); + + return elem; +} diff --git a/src/Mesh_TEST.cc b/src/Mesh_TEST.cc index 41ecfe2c6..12a448a42 100644 --- a/src/Mesh_TEST.cc +++ b/src/Mesh_TEST.cc @@ -179,3 +179,25 @@ TEST(DOMMesh, Load) EXPECT_NE(std::string::npos, errors[0].Message().find("missing a ")); EXPECT_NE(nullptr, mesh.Element()); } + +///////////////////////////////////////////////// +TEST(DOMMesh, ToElement) +{ + sdf::Mesh mesh; + + mesh.SetUri("mesh-uri"); + mesh.SetScale(ignition::math::Vector3d(1, 2, 3)); + mesh.SetSubmesh("submesh"); + mesh.SetCenterSubmesh(false); + + sdf::ElementPtr elem = mesh.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Mesh mesh2; + mesh2.Load(elem); + + EXPECT_EQ(mesh.Uri(), mesh2.Uri()); + EXPECT_EQ(mesh.Scale(), mesh2.Scale()); + EXPECT_EQ(mesh.Submesh(), mesh2.Submesh()); + EXPECT_EQ(mesh.CenterSubmesh(), mesh2.CenterSubmesh()); +} diff --git a/src/Plane.cc b/src/Plane.cc index a24542080..408f72161 100644 --- a/src/Plane.cc +++ b/src/Plane.cc @@ -16,6 +16,7 @@ */ #include #include +#include "sdf/parser.hh" #include "sdf/Plane.hh" using namespace sdf; @@ -150,3 +151,18 @@ ignition::math::Planed &Plane::Shape() { return this->dataPtr->plane; } + +///////////////////////////////////////////////// +sdf::ElementPtr Plane::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("plane_shape.sdf", elem); + + sdf::ElementPtr normalElem = elem->GetElement("normal"); + normalElem->Set(this->Normal()); + + sdf::ElementPtr sizeElem = elem->GetElement("size"); + sizeElem->Set(this->Size()); + + return elem; +} diff --git a/src/Plane_TEST.cc b/src/Plane_TEST.cc index 97fd5f780..04aa0be11 100644 --- a/src/Plane_TEST.cc +++ b/src/Plane_TEST.cc @@ -167,3 +167,21 @@ TEST(DOMPlane, Shape) plane.Shape().Offset()); EXPECT_EQ(ignition::math::Vector2d(1, 2), plane.Size()); } + +///////////////////////////////////////////////// +TEST(DOMPlane, ToElement) +{ + sdf::Plane plane; + + plane.SetNormal(ignition::math::Vector3d(0, 1, 0)); + plane.SetSize(ignition::math::Vector2d(2, 4)); + + sdf::ElementPtr elem = plane.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Plane plane2; + plane2.Load(elem); + + EXPECT_EQ(plane.Normal(), plane2.Normal()); + EXPECT_EQ(plane.Size(), plane2.Size()); +} diff --git a/src/Sphere.cc b/src/Sphere.cc index e1c8ad3ed..df666c58b 100644 --- a/src/Sphere.cc +++ b/src/Sphere.cc @@ -14,6 +14,7 @@ * limitations under the License. * */ +#include "sdf/parser.hh" #include "sdf/Sphere.hh" using namespace sdf; @@ -111,3 +112,15 @@ sdf::ElementPtr Sphere::Element() const { return this->dataPtr->sdf; } + +///////////////////////////////////////////////// +sdf::ElementPtr Sphere::ToElement() const +{ + sdf::ElementPtr elem(new sdf::Element); + sdf::initFile("sphere_shape.sdf", elem); + + sdf::ElementPtr radiusElem = elem->GetElement("radius"); + radiusElem->Set(this->Radius()); + + return elem; +} diff --git a/src/Sphere_TEST.cc b/src/Sphere_TEST.cc index 107ccac36..5e8d0407d 100644 --- a/src/Sphere_TEST.cc +++ b/src/Sphere_TEST.cc @@ -133,3 +133,19 @@ TEST(DOMSphere, Shape) sphere.Shape().SetRadius(0.123); EXPECT_DOUBLE_EQ(0.123, sphere.Radius()); } + +///////////////////////////////////////////////// +TEST(DOMSphere, ToElement) +{ + sdf::Sphere sphere; + + sphere.SetRadius(1.2); + + sdf::ElementPtr elem = sphere.ToElement(); + ASSERT_NE(nullptr, elem); + + sdf::Sphere sphere2; + sphere2.Load(elem); + + EXPECT_DOUBLE_EQ(sphere.Radius(), sphere2.Radius()); +}