Skip to content
This repository has been archived by the owner on Feb 3, 2025. It is now read-only.

Support resource files with spaces #2877

Merged
merged 9 commits into from
Nov 21, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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: 5 additions & 2 deletions gazebo/Server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,10 @@ bool Server::GetInitialized() const
bool Server::LoadFile(const std::string &_filename,
const std::string &_physics)
{
auto foundFile = common::find_file(_filename);

// Quick test for a valid file
FILE *test = fopen(common::find_file(_filename).c_str(), "r");
FILE *test = fopen(foundFile.c_str(), "r");
if (!test)
{
gzerr << "Could not open file[" << _filename << "]\n";
Expand All @@ -402,12 +404,13 @@ bool Server::LoadFile(const std::string &_filename,
return false;
}

if (!sdf::readFile(common::find_file(_filename), sdf))
if (!sdf::readFile(foundFile, sdf))
{
gzerr << "Unable to read sdf file[" << _filename << "]\n";
return false;
}

gzmsg << "Loading world file [" << foundFile << "]" << std::endl;
return this->LoadImpl(sdf->Root(), _physics);
}

Expand Down
13 changes: 13 additions & 0 deletions gazebo/common/ColladaLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/

#include <curl/curl.h>
#include <tinyxml.h>
#include <math.h>
#include <sstream>
Expand Down Expand Up @@ -1484,6 +1485,18 @@ void ColladaLoader::LoadColorOrTexture(TiXmlElement *_elem,
{
std::string imgFile =
imageXml->FirstChildElement("init_from")->GetText();

auto curl = curl_easy_init();
if (curl)
{
imgFile = std::string(curl_easy_unescape(curl, imgFile.c_str(), 0,
nullptr));
}
else
{
gzerr << "Can't unescape file, failed to initialize curl" << std::endl;
}

_mat->SetTextureImage(imgFile, this->dataPtr->path);
}
}
Expand Down
127 changes: 127 additions & 0 deletions gazebo/gui/ModelMaker_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include "gazebo/common/MouseEvent.hh"
#include "gazebo/common/SystemPaths.hh"

#include "gazebo/msgs/msgs.hh"

Expand Down Expand Up @@ -549,5 +550,131 @@ void ModelMaker_TEST::FromNestedModel()
delete mainWindow;
}

/////////////////////////////////////////////////
void ModelMaker_TEST::FromModelWithSpaces()
{
this->resMaxPercentChange = 5.0;
this->shareMaxPercentChange = 2.0;

// Test database
gazebo::common::SystemPaths::Instance()->AddModelPaths(
PROJECT_SOURCE_PATH "/test/models/testdb");

this->Load("worlds/empty.world", false, false, false);

// Create the main window.
auto mainWindow = new gazebo::gui::MainWindow();
QVERIFY(mainWindow != nullptr);
mainWindow->Load();
mainWindow->Init();
mainWindow->show();

this->ProcessEventsAndDraw(mainWindow);

// Check there's no model in the left panel yet
bool hasModel = mainWindow->HasEntityName("model with spaces");
QVERIFY(!hasModel);

// Get scene
auto scene = gazebo::rendering::get_scene();
QVERIFY(scene != nullptr);

// Check there's no model in the scene yet
auto vis = scene->GetVisual("model with spaces");
QVERIFY(vis == nullptr);

// Create a model maker
auto modelMaker = new gazebo::gui::ModelMaker();
QVERIFY(modelMaker != nullptr);

// Model data
boost::filesystem::path path;
path = path / TEST_PATH / "models" / "testdb" / "model with spaces" /
"model.sdf";

// Start the maker to make a model
modelMaker->InitFromFile(path.string());
modelMaker->Start();

// Check there's still no model in the left panel
hasModel = mainWindow->HasEntityName("model with spaces");
QVERIFY(!hasModel);

// Check there's a model in the scene -- this is the preview
vis = scene->GetVisual("model with spaces");
QVERIFY(vis != nullptr);

// check all preview visuals are loaded
vis = scene->GetVisual("model with spaces::nested model with spaces");
QVERIFY(vis != nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces::"
"deeper nested model with spaces");
QVERIFY(vis != nullptr);
vis = scene->GetVisual(
"model with spaces::nested model with spaces::"
"deeper nested model with spaces::even deeper nested model with spaces");
QVERIFY(vis != nullptr);

// Check that the model appeared in the center of the screen
ignition::math::Vector3d startPos = modelMaker->EntityPosition();
QVERIFY(startPos == ignition::math::Vector3d(0, 0, 0.5));
vis = scene->GetVisual("model with spaces");
QVERIFY(vis->WorldPose().Pos() == startPos);

// Mouse move
gazebo::common::MouseEvent mouseEvent;
mouseEvent.SetType(gazebo::common::MouseEvent::MOVE);
modelMaker->OnMouseMove(mouseEvent);

// Check that entity moved
ignition::math::Vector3d pos = modelMaker->EntityPosition();
QVERIFY(pos != startPos);
QVERIFY(vis->WorldPose().Pos() == pos);

// Mouse release
mouseEvent.SetType(gazebo::common::MouseEvent::RELEASE);
mouseEvent.SetButton(gazebo::common::MouseEvent::LEFT);
mouseEvent.SetDragging(false);
mouseEvent.SetPressPos(0, 0);
mouseEvent.SetPos(0, 0);
modelMaker->OnMouseRelease(mouseEvent);

// Check there's no model in the scene -- the preview is gone
vis = scene->GetVisual("model with spaces");
QVERIFY(vis == nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces");
QVERIFY(vis == nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces::"
"deeper nested model with spaces");
QVERIFY(vis == nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces::"
"deeper nested model with spaces::even deeper nested model with spaces");
QVERIFY(vis == nullptr);

this->ProcessEventsAndDraw(mainWindow);

// Check there's a model in the scene -- this is the final model
vis = scene->GetVisual("model with spaces");
QVERIFY(vis != nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces");
QVERIFY(vis != nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces::"
"deeper nested model with spaces");
QVERIFY(vis != nullptr);
vis = scene->GetVisual("model with spaces::nested model with spaces::"
"deeper nested model with spaces::even deeper nested model with spaces");
QVERIFY(vis != nullptr);

// Check the model is in the left panel
hasModel = mainWindow->HasEntityName("model with spaces");
QVERIFY(hasModel);

delete modelMaker;

// Terminate
mainWindow->close();
delete mainWindow;
}

// Generate a main function for the test
QTEST_MAIN(ModelMaker_TEST)
4 changes: 4 additions & 0 deletions gazebo/gui/ModelMaker_TEST.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class ModelMaker_TEST : public QTestFixture

/// \brief Test creating a nested model by copying another nested model.
private slots: void FromNestedModel();

/// \brief Test creating a model with spaces in the file name and entity
/// names.
private slots: void FromModelWithSpaces();
};

#endif
10 changes: 9 additions & 1 deletion gazebo/test/ServerFixture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*
*/
#include <boost/algorithm/string.hpp>
#include <regex>
#include <stdio.h>
#include <string>
#include <cmath>
Expand Down Expand Up @@ -163,7 +164,10 @@ void ServerFixture::Load(const std::string &_worldFilename,
bool _paused, const std::string &_physics,
const std::vector<std::string> &_systemPlugins)
{
std::string params = _worldFilename;
// Substitute spaces in file name with a placeholder to prevent the name
// from being split later
auto params = std::regex_replace(_worldFilename, std::regex("\\s"), "%20");

if (!_physics.empty())
params += " -e " + _physics;
if (_paused)
Expand All @@ -186,6 +190,10 @@ void ServerFixture::LoadArgs(const std::string &_args)
boost::trim_if(args, boost::is_any_of("\t "));
boost::split(params, args, boost::is_any_of("\t "), boost::token_compress_on);

// Add spaces back
for (auto &param : params)
param = std::regex_replace(param, std::regex("%20"), " ");

bool paused = false;
if (std::find(params.begin(), params.end(), "-u") != params.end())
paused = true;
Expand Down
Loading