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

SDF to USD (main) #763

Closed
Closed
Changes from all 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
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -98,13 +98,20 @@ find_package(pxr REQUIRED)

include_directories(${PXR_INCLUDE_DIRS})
set(sources ${sources}
# source files for parsing from USD to SDF
usd/usd_parser/parser_usd.cc
usd/usd_parser/physics.cc
usd/usd_parser/joints.cc
usd/usd_parser/lights.cc
usd/usd_parser/links.cc
usd/usd_parser/sensors.cc
usd/usd_parser/utils.cc
# source files for parsing from SDF to USD
usd/sdf_parser/geometry.cc
usd/sdf_parser/link.cc
usd/sdf_parser/model.cc
usd/sdf_parser/visual.cc
usd/sdf_parser/world.cc
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/usd)

21 changes: 21 additions & 0 deletions src/cmd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -43,6 +43,8 @@ file(GENERATE
# Install the ruby command line library in an unversioned location.
install(FILES ${cmd_script_generated} DESTINATION lib/ruby/ignition)

#===============================================================================
# USD -> SDF converter
add_executable(sdfconverter
sdfconverter.cpp
)
@@ -60,3 +62,22 @@ install(
DESTINATION
${BIN_INSTALL_DIR}
)

#===============================================================================
# SDF -> USD converter
add_executable(usdConverter
usdConverter.cc
)

target_link_libraries(usdConverter
PUBLIC
ignition-common${IGN_COMMON_VER}::graphics
${sdf_target}
)

install(
TARGETS
usdConverter
DESTINATION
${BIN_INSTALL_DIR}
)
72 changes: 72 additions & 0 deletions src/cmd/usdConverter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include <iostream>

#include <pxr/usd/usd/stage.h>

#include "sdf/sdf.hh"
// TODO(adlarkin) verify that this line works (using usd/ as prefix)
#include "usd/sdf_parser/world.hh"

int main(int argc, const char* argv[])
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " <sdf-path> <usd-path>\n";
return -1;
}

sdf::Root root;
auto errors = root.Load(argv[1]);
if (!errors.empty())
{
std::cerr << "Errors encountered:\n";
for (const auto &e : errors)
std::cout << e << "\n";
return -2;
}

// only support SDF files with exactly 1 world for now
if (root.WorldCount() != 1u)
{
std::cerr << argv[1] << " does not have exactly 1 world.\n";
return -3;
}

auto world = root.WorldByIndex(0u);
if (!world)
{
std::cerr << "Error retrieving the world from " << argv[1] << "\n";
return -4;
}

auto stage = pxr::UsdStage::CreateInMemory();

const auto worldPath = std::string("/" + world->Name());
if (!usd::ParseSdfWorld(*world, stage, worldPath))
{
std::cerr << "Error parsing world [" << world->Name() << "]\n";
return -5;
}

if (!stage->GetRootLayer()->Export(argv[2]))
{
std::cerr << "Issue saving USD to " << argv[2] << "\n";
return -6;
}
}
96 changes: 96 additions & 0 deletions src/usd/sdf_parser/geometry.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "geometry.hh"

#include <iostream>
#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Geometry.hh"

namespace usd
{
bool ParseSdfBoxGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish this
return false;
}

bool ParseSdfCylinderGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish this
return false;
}

bool ParseSdfSphereGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish this
return false;
}

bool ParseSdfMeshGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish this
return false;
}

bool ParseSdfCapsuleGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish this
return false;
}
}

using namespace usd;

bool ParseSdfGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
bool typeParsed = false;
switch (_geometry.Type())
{
case sdf::GeometryType::BOX:
typeParsed = ParseSdfBoxGeometry(_geometry, _stage, _path);
break;
case sdf::GeometryType::CYLINDER:
typeParsed = ParseSdfCylinderGeometry(_geometry, _stage, _path);
break;
case sdf::GeometryType::SPHERE:
typeParsed = ParseSdfSphereGeometry(_geometry, _stage, _path);
break;
case sdf::GeometryType::MESH:
typeParsed = ParseSdfMeshGeometry(_geometry, _stage, _path);
break;
case sdf::GeometryType::CAPSULE:
typeParsed = ParseSdfCapsuleGeometry(_geometry, _stage, _path);
break;
case sdf::GeometryType::PLANE:
case sdf::GeometryType::ELLIPSOID:
case sdf::GeometryType::HEIGHTMAP:
default:
std::cerr << "Geometry type is either invalid or not supported.\n";
}

return typeParsed;
}
41 changes: 41 additions & 0 deletions src/usd/sdf_parser/geometry.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_PARSER_GEOMETRY_HH_
#define SDF_PARSER_GEOMETRY_HH_

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Geometry.hh"

namespace usd
{
/// \brief Parse an SDF geometry into a USD stage.
/// \param[in] _geometry The SDF geometry to parse.
/// \param[in] _stage The stage that should contain the USD representation
/// of _geometry.
/// \param[in] _path The USD path of the parsed geometry in _stage, which must be
/// a valid USD path.
/// \return True if _geometry was succesfully parsed into _stage with a path of
/// _path. False otherwise.
bool ParseSdfGeometry(const sdf::Geometry &_geometry, pxr::UsdStageRefPtr &_stage,
const std::string &_path);
}

#endif
50 changes: 50 additions & 0 deletions src/usd/sdf_parser/link.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "link.hh"

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Link.hh"
#include "usd/sdf_parser/visual.hh"

using namespace usd;

bool ParseSdfLink(const sdf::Link &_link, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish parsing link. It will look something like this
// (this does not cover all elements of a link that need to be parsed):
// * ParseSdfVisual
// * ParseSdfCollision
// * ParseSdfSensor

// parse all of the link's visuals and convert them to USD
for (uint64_t i = 0; i < _link.VisualCount(); ++i)
{
const auto visual = *(_link.VisualByIndex(i));
const auto visualPath = std::string(_path + "/" + visual.Name());
if (!ParseSdfVisual(visual, _stage, visualPath))
{
std::cerr << "Error parsing visual [" << visual.Name() << "]\n.";
return false;
}
}
return true;
}
41 changes: 41 additions & 0 deletions src/usd/sdf_parser/link.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_PARSER_LINK_HH_
#define SDF_PARSER_LINK_HH_

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Link.hh"

namespace usd
{
/// \brief Parse an SDF link into a USD stage.
/// \param[in] _link The SDF link to parse.
/// \param[in] _stage The stage that should contain the USD representation
/// of _link.
/// \param[in] _path The USD path of the parsed link in _stage, which must be
/// a valid USD path.
/// \return True if _link was succesfully parsed into _stage with a path of
/// _path. False otherwise.
bool ParseSdfLink(const sdf::Link &_link, pxr::UsdStageRefPtr &_stage,
const std::string &_path);
}

#endif
51 changes: 51 additions & 0 deletions src/usd/sdf_parser/model.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "model.hh"

#include <iostream>
#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Model.hh"
#include "usd/sdf_parser/link.hh"

using namespace usd;

bool ParseSdfModel(const sdf::Model &_model, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// TODO(adlarkin) finish parsing model. It will look something like this
// (this does not cover parsing all elements of a model):
// * ParseSdfLink
// * ParseSdfJoint

// parse all of the model's links and convert them to USD
for (uint64_t i = 0; i < _model.LinkCount(); ++i)
{
const auto link = *(_model.LinkByIndex(i));
const auto linkPath = std::string(_path + "/" + link.Name());
if (!ParseSdfLink(link, _stage, linkPath))
{
std::cerr << "Error parsing link [" << link.Name() << "]\n.";
return false;
}
}

return true;
}
41 changes: 41 additions & 0 deletions src/usd/sdf_parser/model.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_PARSER_MODEL_HH_
#define SDF_PARSER_MODEL_HH_

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Model.hh"

namespace usd
{
/// \brief Parse an SDF model into a USD stage.
/// \param[in] _model The SDF model to parse.
/// \param[in] _stage The stage that should contain the USD representation
/// of _model.
/// \param[in] _path The USD path of the parsed model in _stage, which must be
/// a valid USD path.
/// \return True if _model was succesfully parsed into _stage with a path of
/// _path. False otherwise.
bool ParseSdfModel(const sdf::Model &_model, pxr::UsdStageRefPtr &_stage,
const std::string &_path);
}

#endif
43 changes: 43 additions & 0 deletions src/usd/sdf_parser/visual.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "visual.hh"

#include <iostream>
#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Visual.hh"
#include "usd/sdf_parser/geometry.hh"

using namespace usd;

bool ParseSdfVisual(const sdf::Visual &_visual, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
const auto geometry = *(_visual.Geom());
const auto geometryPath = std::string(_path + "/geometry");
if (!ParseSdfGeometry(geometry, _stage, geometryPath))
{
std::cerr << "Error parsing geometry attached to visual ["
<< _visual.Name() << "]\n";
return false;
}

return true;
}
41 changes: 41 additions & 0 deletions src/usd/sdf_parser/visual.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_PARSER_VISUAL_HH_
#define SDF_PARSER_VISUAL_HH_

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/Visual.hh"

namespace usd
{
/// \brief Parse an SDF visual into a USD stage.
/// \param[in] _visual The SDF visual to parse.
/// \param[in] _stage The stage that should contain the USD representation
/// of _visual.
/// \param[in] _path The USD path of the parsed visual in _stage, which must be
/// a valid USD path.
/// \return True if _visual was succesfully parsed into _stage with a path of
/// _path. False otherwise.
bool ParseSdfVisual(const sdf::Visual &_visual, pxr::UsdStageRefPtr &_stage,
const std::string &_path);
}

#endif
48 changes: 48 additions & 0 deletions src/usd/sdf_parser/world.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include "world.hh"

#include <iostream>
#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/World.hh"
#include "usd/sdf_parser/model.hh"

using namespace usd;

bool ParseSdfWorld(const sdf::World &_world, pxr::UsdStageRefPtr &_stage,
const std::string &_path)
{
// parse all of the world's models and convert them to USD
for (uint64_t i = 0; i < _world.ModelCount(); ++i)
{
const auto model = *(_world.ModelByIndex(i));
const auto modelPath = std::string(_path + "/" + model.Name());
if (!ParseSdfModel(model, _stage, modelPath))
{
std::cerr << "Error parsing model [" << model.Name() << "]\n.";
return false;
}
}

// TODO(adlarkin) finish parsing other elements in _world

return true;
}
41 changes: 41 additions & 0 deletions src/usd/sdf_parser/world.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#ifndef SDF_PARSER_WORLD_HH_
#define SDF_PARSER_WORLD_HH_

#include <string>

#include <pxr/usd/usd/stage.h>

#include "sdf/World.hh"

namespace usd
{
/// \brief Parse an SDF world into a USD stage.
/// \param[in] _world The SDF world to parse.
/// \param[in] _stage The stage that should contain the USD representation
/// of _world.
/// \param[in] _path The USD path of the parsed world in _stage, which must be
/// a valid USD path.
/// \return True if _world was succesfully parsed into _stage with a path of
/// _path. False otherwise.
bool ParseSdfWorld(const sdf::World &_world, pxr::UsdStageRefPtr &_stage,
const std::string &_path);
}

#endif