Commit 520fb368 authored by Robert Maynard's avatar Robert Maynard
Browse files

Properly generate unique mesh names when deserializing from json.

Previously when deserializing we didn't generate unique names, as we didnt
handle the use case of meshes already existing with names like "Mesh_1"
which would causing conflicts.
parent a77edb04
......@@ -992,10 +992,6 @@ int ExportJSON::forSingleCollection(cJSON* mdesc,
cJSON_AddItemToObject(jsonCollection,"formatVersion", cJSON_CreateNumber(1));
//ask the manager to generate a unique name for the collection, if it
//doesn't already have a unique name
collection->assignUniqueNameIfNotAlready();
cJSON_AddStringToObject(jsonCollection,"name", collection->name().c_str());
//assoicated model uuid of the collection
if(!collection->associatedModel().isNull())
......
......@@ -1146,7 +1146,13 @@ int ImportJSON::ofMeshesOfModel(cJSON* node,
//remove the old collection, as its interface is now owned by the new
//collection
meshMgr->removeCollection(importedCollection);
importedCollection.reset();
//We need to set the read location on the orginal collection if
//the interface is moab
if(isValidMoab)
{
collection->readLocation( importedCollection->readLocation() );
}
//set the name back to the collection
cJSON* collecNameNode = cJSON_GetObjectItem(child, "name");
......@@ -1154,6 +1160,11 @@ int ImportJSON::ofMeshesOfModel(cJSON* node,
cJSON_GetStringValue(collecNameNode, collectionName);
collection->name(collectionName);
//ask the manager to generate a unique name for the collection, if it
//doesn't already have a unique name. This occurs when meshes have
//no name, or a name that has already been used
collection->assignUniqueNameIfNotAlready();
//set the collections model manager so that we can do model based
//queries properly
collection->setModelManager( modelMgr );
......
......@@ -281,6 +281,7 @@ private:
friend class smtk::mesh::Manager;
friend class smtk::io::ImportMesh;
friend class smtk::io::ImportJSON;
//called by the manager that manages this collection, means that somebody
//has requested us to be removed from a collection
......
......@@ -16,6 +16,7 @@
#include <boost/lexical_cast.hpp>
#include <map>
#include <set>
namespace smtk {
namespace mesh {
......@@ -111,10 +112,16 @@ public:
{
}
std::string next()
std::string next( const std::set< std::string >& usedNames )
{
std::string result(this->m_basename);
result += boost::lexical_cast< std::string >(this->m_value++);
while( usedNames.find(result) != usedNames.end() )
{
result = (std::string(this->m_basename) += boost::lexical_cast< std::string >(this->m_value++));
}
std::cout << "generating name: " << result << std::endl;
return result;
}
......@@ -331,32 +338,24 @@ Manager::assignUniqueName( smtk::mesh::CollectionPtr collection )
return false;
}
bool needsName = false;
if(collection->name().empty())
{
//fast code path, the collection name is empty, so we don't need to check
//if the existing name is unique
needsName = true;
}
else
std::set< std::string > usedNames;
for(const_iterator i = this->m_collector->begin(); i != this->m_collector->end(); ++i)
{
std::string currentName = collection->name();
//slow path, we have to determine if the current name is unique or not
for(const_iterator i = this->m_collector->begin();
i != this->m_collector->end() && needsName == false;
++i)
if(i->second != collection)
{
if(i->second != collection)
{
needsName = ( i->second->name() == currentName );
}
usedNames.insert( i->second->name() );
}
}
if(needsName)
const bool nameAlreadyUsed = ( usedNames.find(collection->name()) != usedNames.end() );
const bool nameEmpty = ( collection->name().empty() );
if(nameAlreadyUsed || nameEmpty )
{
//time to generate a new name
collection->name( this->m_nameGenerator->next() );
//time to generate a new name, we pass the number of existing meshes
//to
collection->name( this->m_nameGenerator->next(usedNames) );
}
return true;
......
......@@ -179,7 +179,7 @@ void verify_name_generation()
test( c->name() == std::string("a"), "assignUniqueName overwrote existing unique name" );
}
//verify that assignUniqueName override an existing name that isn't unique
//verify that assignUniqueName overrides an existing name that isn't unique
{
smtk::mesh::ManagerPtr mgr = smtk::mesh::Manager::create();
smtk::mesh::CollectionPtr c1 = mgr->makeCollection();
......@@ -195,6 +195,23 @@ void verify_name_generation()
"assignUniqueName overwrote existing unique name" );
}
//verify that assignUniqueName handles not generating a clashing unique
//name, when the existing name matches the pattern of the auto generator
{
smtk::mesh::ManagerPtr mgr = smtk::mesh::Manager::create();
smtk::mesh::CollectionPtr c1 = mgr->makeCollection();
smtk::mesh::CollectionPtr c2 = mgr->makeCollection();
c1->name( std::string("Mesh_1") );
mgr->assignUniqueName(c1);
mgr->assignUniqueName(c2); //shoud be Mesh_2 not Mesh_1
test( c1->name() == std::string("Mesh_1"),
"assignUniqueName overwrote existing unique name" );
test( c2->name() == std::string("Mesh_2"),
"assignUniqueName generated a non-unique name" );
}
//verify that the only the owning manager can assign unique names
{
smtk::mesh::ManagerPtr mgr = smtk::mesh::Manager::create();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment