Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USD -> SDF: Parse Physics and generated SDF file #863

Merged
merged 22 commits into from
Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions usd/src/cmd/usd2sdf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <iostream>
#include <string>

#include <ignition/utils/cli/CLI.hpp>
Expand Down
22 changes: 17 additions & 5 deletions usd/src/usd_parser/Parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "sdf/usd/usd_parser/Parser.hh"
#include "USD2SDF.hh"

#include "sdf/Root.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE {
Expand All @@ -29,14 +31,24 @@ namespace usd
{
UsdErrors errors;
USD2SDF usd2sdf;
auto doc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE);
auto readErrors = usd2sdf.Read(_inputFilenameUsd, &doc);
if (!readErrors.empty())
sdf::Root root;
errors = usd2sdf.Read(_inputFilenameUsd, root);
if (!errors.empty())
{
return errors;
}

std::ofstream out(_outputFilenameSdf.c_str(), std::ios::out);
std::string string = root.ToElement()->ToString("");
if (!out)
{
errors.insert(errors.end(), readErrors.begin(), readErrors.end());
errors.emplace_back(UsdError(
UsdErrorCode::SDF_TO_USD_PARSING_ERROR,
"Unable to open file [" + _outputFilenameSdf + "] for writing"));
return errors;
}
doc.SaveFile(_outputFilenameSdf.c_str());
out << string;
out.close();
return errors;
}
}
Expand Down
112 changes: 16 additions & 96 deletions usd/src/usd_parser/USD2SDF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,23 @@

#include "sdf/Console.hh"
#include "sdf/Types.hh"
#include "usd_model/WorldInterface.hh"
#include "USDWorld.hh"

#include "sdf/Root.hh"
#include "sdf/World.hh"

namespace sdf {
inline namespace SDF_VERSION_NAMESPACE {
namespace usd {
/////////////////////////////////////////////////
USD2SDF::USD2SDF()
{
}

/////////////////////////////////////////////////
USD2SDF::~USD2SDF()
{
}

/////////////////////////////////////////////////
////////////////////////////////////////////////
UsdErrors USD2SDF::Read(const std::string &_fileName,
tinyxml2::XMLDocument *_sdfXmlOut)
sdf::Root &_root)
{
UsdErrors errors;

std::shared_ptr<WorldInterface> worldInterface =
std::make_shared<WorldInterface>();
sdf::World sdfWorld;

const auto errorsParseUSD = parseUSDWorld(_fileName, worldInterface);
const auto errorsParseUSD = parseUSDWorld(_fileName, sdfWorld);
if (!errorsParseUSD.empty())
{
errors.emplace_back(UsdError(
Expand All @@ -53,91 +44,20 @@ UsdErrors USD2SDF::Read(const std::string &_fileName,
return errors;
}

tinyxml2::XMLElement *sdf = nullptr;
sdf = _sdfXmlOut->NewElement("sdf");
sdf->SetAttribute("version", "1.7");

tinyxml2::XMLElement *world = nullptr;
world = _sdfXmlOut->NewElement("world");
std::string worldName = worldInterface->worldName;
if (worldName.empty())
{
worldName = "world_name";
}
world->SetAttribute("name", (worldName + "_world").c_str());

this->AddKeyValue(world, "gravity", Vector32Str(
worldInterface->gravity * worldInterface->magnitude));

sdf->LinkEndChild(world);
_sdfXmlOut->LinkEndChild(sdf);
return errors;
}

/////////////////////////////////////////////////
std::string USD2SDF::GetKeyValueAsString(
const tinyxml2::XMLElement *_elem) const
{
std::string valueStr;
if (_elem->Attribute("value"))
{
valueStr = _elem->Attribute("value");
}
else if (_elem->FirstChild())
auto addWorldErrors = _root.AddWorld(sdfWorld);
if (!addWorldErrors.empty())
{
// Check that this node is a XMLText
if (_elem->FirstChild()->ToText())
for (auto & error: addWorldErrors)
{
valueStr = _elem->FirstChild()->Value();
errors.emplace_back(error);
}
else
{
sdfwarn << "Attribute value string not set\n";
}
}
return trim(valueStr);
}

/////////////////////////////////////////////////
void USD2SDF::AddKeyValue(
tinyxml2::XMLElement *_elem,
const std::string &_key,
const std::string &_value)
{
tinyxml2::XMLElement *childElem = _elem->FirstChildElement(_key.c_str());
if (childElem)
{
std::string oldValue = this->GetKeyValueAsString(childElem);
if (oldValue != _value)
{
sdferr << "multiple inconsistent <" << _key
<< "> exists due to fixed joint reduction"
<< " overwriting previous value [" << oldValue
<< "] with [" << _value << "].\n";
}
else
{
sdferr << "multiple consistent <" << _key
<< "> exists with [" << _value
<< "] due to fixed joint reduction.\n";
}
// remove old _elem
_elem->DeleteChild(childElem);
errors.emplace_back(UsdError(
UsdErrorCode::SDF_ERROR,
ahcorde marked this conversation as resolved.
Show resolved Hide resolved
"Error adding the world [" + sdfWorld.Name() + "]"));
return errors;
}

auto *doc = _elem->GetDocument();
tinyxml2::XMLElement *ekey = doc->NewElement(_key.c_str());
tinyxml2::XMLText *textEkey = doc->NewText(_value.c_str());
ekey->LinkEndChild(textEkey);
_elem->LinkEndChild(ekey);
}

/////////////////////////////////////////////////
std::string USD2SDF::Vector32Str(const ignition::math::Vector3d &_vector) const
{
std::stringstream ss;
ss << _vector;
return ss.str();
return errors;
}
}
}
Expand Down
33 changes: 4 additions & 29 deletions usd/src/usd_parser/USD2SDF.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@

#include <string>

#include <ignition/math/Vector3.hh>
#include <tinyxml2.h>

#include "sdf/sdf_config.h"
#include "sdf/usd/UsdError.hh"

#include "sdf/Root.hh"

namespace sdf
{
// Inline bracket to help doxygen filtering.
Expand All @@ -37,10 +36,7 @@ inline namespace SDF_VERSION_NAMESPACE {
class USD2SDF
{
/// \brief constructor
public: USD2SDF();

/// \brief destructor
public: ~USD2SDF();
public: USD2SDF() = default;

/// \brief convert USD file to sdf xml document
/// \param[in] _fileMame string containing USD filename.
Expand All @@ -50,28 +46,7 @@ inline namespace SDF_VERSION_NAMESPACE {
/// of _fileName
public: UsdErrors Read(
const std::string &_fileName,
tinyxml2::XMLDocument *_sdfXmlOut);

/// \brief get value from <key value="..."/> pair and return it as string
/// \param[in] _elem pointer to xml element
/// return a string with the key
private: std::string GetKeyValueAsString(
const tinyxml2::XMLElement *_elem) const;

/// \brief append key value pair to the end of the xml element
/// \param[in] _elem pointer to xml element
/// \param[in] _key string containing key to add to xml element
/// \param[in] _value string containing value for the key added
private: void AddKeyValue(
tinyxml2::XMLElement *_elem,
const std::string &_key,
const std::string &_value);

/// \brief convert Vector3 to string
/// \param[in] _vector a ignition::math::Vector3d
/// \return string representation of Vector3
private: std::string Vector32Str(
const ignition::math::Vector3d &_vector) const;
sdf::Root &_root);
};
}
}
Expand Down
22 changes: 14 additions & 8 deletions usd/src/usd_parser/USDPhysics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,45 @@
#include <pxr/usd/usdPhysics/scene.h>
#pragma pop_macro ("__DEPRECATED")

#include "sdf/World.hh"

namespace sdf
{
inline namespace SDF_VERSION_NAMESPACE {
namespace usd
{
void ParseUSDPhysicsScene(
const pxr::UsdPhysicsScene &_scene,
std::shared_ptr<WorldInterface> &_world,
sdf::World &_world,
double _metersPerUnit)
{
if (const auto gravityAttr = _scene.GetGravityDirectionAttr())
ignition::math::Vector3d worldGravity{0, 0, -1};
float magnitude {9.8f};
const auto gravityAttr = _scene.GetGravityDirectionAttr();
if (gravityAttr)
{
pxr::GfVec3f gravity;
gravityAttr.Get(&gravity);
if (!ignition::math::equal(0.0f, gravity[0]) &&
!ignition::math::equal(0.0f, gravity[1]) &&
!ignition::math::equal(0.0f, gravity[2]))
{
_world->gravity[0] = gravity[0];
_world->gravity[1] = gravity[1];
_world->gravity[2] = gravity[2];
worldGravity[0] = gravity[0];
worldGravity[1] = gravity[1];
worldGravity[2] = gravity[2];
}
}

if (const auto magnitudeAttr = _scene.GetGravityMagnitudeAttr())
const auto magnitudeAttr = _scene.GetGravityMagnitudeAttr();
if (magnitudeAttr)
{
float magnitude;
magnitudeAttr.Get(&magnitude);
if (!std::isnan(magnitude) && !std::isinf(magnitude))
{
_world->magnitude = magnitude * _metersPerUnit;
magnitude = magnitude * _metersPerUnit;
}
}
_world.SetGravity(worldGravity * magnitude);
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions usd/src/usd_parser/USDPhysics.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#ifndef USD_PARSER_PHYSYCS_HH
#define USD_PARSER_PHYSYCS_HH

#include "usd_model/WorldInterface.hh"

#pragma push_macro ("__DEPRECATED")
#undef __DEPRECATED
#include <pxr/usd/usdPhysics/scene.h>
Expand All @@ -28,6 +26,7 @@
#include "sdf/config.hh"
#include "sdf/usd/Export.hh"

#include "sdf/World.hh"
namespace sdf
{
// Inline bracket to help doxygen filtering.
Expand All @@ -41,7 +40,7 @@ namespace sdf
/// \param[in] _metersPerUnit meters per unit in the USD
azeey marked this conversation as resolved.
Show resolved Hide resolved
void IGNITION_SDFORMAT_USD_VISIBLE ParseUSDPhysicsScene(
azeey marked this conversation as resolved.
Show resolved Hide resolved
const pxr::UsdPhysicsScene &_scene,
std::shared_ptr<WorldInterface> &_world,
sdf::World &_world,
double _metersPerUnit);
}
}
Expand Down
17 changes: 6 additions & 11 deletions usd/src/usd_parser/USDPhysics_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "test_utils.hh"

#include "USDPhysics.hh"
#include "usd_model/WorldInterface.hh"

/////////////////////////////////////////////////
TEST(USDPhysicsTest, AvailablePhysics)
Expand All @@ -46,15 +45,13 @@ TEST(USDPhysicsTest, AvailablePhysics)
pxr::UsdPhysicsScene(stage->GetPrimAtPath(pxr::SdfPath("/shapes/physics")));
EXPECT_TRUE(physicsScene);

std::shared_ptr<sdf::usd::WorldInterface> worldInterface =
std::make_shared<sdf::usd::WorldInterface>();
sdf::World world;

const double metersPerUnit = 1.0;

sdf::usd::ParseUSDPhysicsScene(
physicsScene, worldInterface, metersPerUnit);
EXPECT_EQ(ignition::math::Vector3d(0, 0, -1), worldInterface->gravity);
EXPECT_FLOAT_EQ(9.8f, worldInterface->magnitude);
physicsScene, world, metersPerUnit);
EXPECT_EQ(ignition::math::Vector3d(0, 0, -9.8), world.Gravity());
}

/////////////////////////////////////////////////
Expand All @@ -68,13 +65,11 @@ TEST(USDPhysicsTest, UnavailablePhysics)
pxr::UsdPhysicsScene(stage->GetPrimAtPath(pxr::SdfPath("/shapes/physics")));
EXPECT_FALSE(physicsScene);

std::shared_ptr<sdf::usd::WorldInterface> worldInterface =
std::make_shared<sdf::usd::WorldInterface>();
sdf::World world;

const double metersPerUnit = 1.0;

sdf::usd::ParseUSDPhysicsScene(
physicsScene, worldInterface, metersPerUnit);
EXPECT_EQ(ignition::math::Vector3d(0, 0, -1), worldInterface->gravity);
EXPECT_FLOAT_EQ(9.8f, worldInterface->magnitude);
physicsScene, world, metersPerUnit);
EXPECT_EQ(ignition::math::Vector3d(0, 0, -9.8), world.Gravity());
}
2 changes: 1 addition & 1 deletion usd/src/usd_parser/USDStage_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ TEST(USDStage, Constructor)

EXPECT_EQ("Y", stage.UpAxis());
EXPECT_DOUBLE_EQ(1.0, stage.MetersPerUnit());
EXPECT_EQ(10u, stage.USDPaths().size());
EXPECT_EQ(9u, stage.USDPaths().size());
}

// Wrong upaxis
Expand Down
Loading