Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkSceneReaderV1.h"
00019 #include "mitkSerializerMacros.h"
00020 #include "mitkDataNodeFactory.h"
00021 #include "mitkBaseRenderer.h"
00022 #include "mitkPropertyListDeserializer.h"
00023 #include "Poco/Path.h"
00024
00025 MITK_REGISTER_SERIALIZER(SceneReaderV1)
00026
00027 bool mitk::SceneReaderV1::LoadScene( TiXmlDocument& document, const std::string& workingDirectory, DataStorage* storage )
00028 {
00029 assert(storage);
00030 bool error(false);
00031
00032
00033
00034
00035
00036 for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node") )
00037 {
00038
00039
00040
00041
00042
00043 DataNode::Pointer node = LoadBaseDataFromDataTag( element->FirstChildElement("data"), workingDirectory, error );
00044
00045
00046 const char* uida = element->Attribute("UID");
00047 std::string uid("");
00048
00049 if (uida)
00050 {
00051 uid = uida;
00052 m_NodeForID[uid] = node.GetPointer();
00053 m_IDForNode[ node.GetPointer() ] = uid;
00054 }
00055 else
00056 {
00057 MITK_ERROR << "No UID found for current node. Node will have no parents.";
00058 error = true;
00059 }
00060
00061
00062 m_Nodes.insert( std::make_pair( node, std::list<std::string>() ) );
00063
00064
00065 for( TiXmlElement* source = element->FirstChildElement("source"); source != NULL; source = source->NextSiblingElement("source") )
00066 {
00067 const char* sourceUID = source->Attribute("UID");
00068 if (sourceUID)
00069 {
00070 m_Nodes[node].push_back( std::string(sourceUID) );
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 bool success = DecorateNodeWithProperties(node, element, workingDirectory);
00080 if (!success)
00081 {
00082 MITK_ERROR << "Could not load properties for node.";
00083 error = true;
00084 }
00085 }
00086
00087
00088 for (NodesAndParentsMapType::iterator nodesIter = m_Nodes.begin();
00089 nodesIter != m_Nodes.end();
00090 ++nodesIter)
00091 {
00092 for (std::list<std::string>::iterator parentsIter = nodesIter->second.begin();
00093 parentsIter != nodesIter->second.end();)
00094 {
00095 if (m_NodeForID.find( *parentsIter ) == m_NodeForID.end())
00096 {
00097 parentsIter = nodesIter->second.erase( parentsIter );
00098 MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects.";
00099 error = true;
00100 }
00101 else
00102 {
00103 ++parentsIter;
00104 }
00105 }
00106 }
00107
00108
00109
00110 unsigned int lastMapSize(0);
00111 while ( lastMapSize != m_Nodes.size())
00112 {
00113 lastMapSize = m_Nodes.size();
00114
00115 for (NodesAndParentsMapType::iterator nodesIter = m_Nodes.begin();
00116 nodesIter != m_Nodes.end();
00117 ++nodesIter)
00118 {
00119 bool addNow(true);
00120
00121 for (std::list<std::string>::iterator parentsIter = nodesIter->second.begin();
00122 parentsIter != nodesIter->second.end();
00123 ++parentsIter)
00124 {
00125 if ( !storage->Exists( m_NodeForID[ *parentsIter ] ) )
00126 {
00127 addNow = false;
00128 break;
00129 }
00130 }
00131
00132 if (addNow)
00133 {
00134 DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New();
00135 for (std::list<std::string>::iterator parentsIter = nodesIter->second.begin();
00136 parentsIter != nodesIter->second.end();
00137 ++parentsIter)
00138 {
00139 parents->push_back( m_NodeForID[ *parentsIter ] );
00140 }
00141
00142
00143 storage->Add( nodesIter->first, parents );
00144
00145
00146 m_Nodes.erase( nodesIter );
00147
00148
00149 break;
00150 }
00151 }
00152 }
00153
00154
00155 for (NodesAndParentsMapType::iterator nodesIter = m_Nodes.begin();
00156 nodesIter != m_Nodes.end();
00157 ++nodesIter)
00158 {
00159 storage->Add( nodesIter->first );
00160 MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage without parents.";
00161 error = true;
00162 }
00163
00164 return !error;
00165 }
00166
00167 mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag( TiXmlElement* dataElement, const std::string& workingDirectory, bool& error )
00168 {
00169 DataNode::Pointer node;
00170
00171 if (dataElement)
00172 {
00173 const char* filename( dataElement->Attribute("file") );
00174 if ( filename )
00175 {
00176 DataNodeFactory::Pointer factory = DataNodeFactory::New();
00177 factory->SetFileName( workingDirectory + Poco::Path::separator() + filename );
00178
00179 try
00180 {
00181 factory->Update();
00182 node = factory->GetOutput();
00183 }
00184 catch (std::exception& e)
00185 {
00186 MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what();
00187 error = true;
00188 }
00189
00190 if (node.IsNull())
00191 {
00192 MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned NULL object.";
00193 error = true;
00194 }
00195 }
00196 }
00197
00198
00199 if (node.IsNull())
00200 {
00201 node = DataNode::New();
00202 }
00203
00204 return node;
00205 }
00206
00207 bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode* node, TiXmlElement* nodeElement, const std::string& workingDirectory)
00208 {
00209 assert(node);
00210 assert(nodeElement);
00211 bool error(false);
00212
00213 for( TiXmlElement* properties = nodeElement->FirstChildElement("properties"); properties != NULL; properties = properties->NextSiblingElement("properties") )
00214 {
00215 const char* propertiesfilea( properties->Attribute("file") );
00216 std::string propertiesfile( propertiesfilea ? propertiesfilea : "" );
00217
00218 const char* renderwindowa( properties->Attribute("renderwindow") );
00219 std::string renderwindow( renderwindowa ? renderwindowa : "" );
00220
00221 BaseRenderer* renderer = BaseRenderer::GetByName( renderwindow );
00222 if (renderer || renderwindow.empty())
00223 {
00224 PropertyList::Pointer propertyList = node->GetPropertyList(renderer);
00225
00226 propertyList->Clear();
00227
00228
00229 PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New();
00230
00231 deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile);
00232 bool success = deserializer->Deserialize();
00233 error |= !success;
00234 PropertyList::Pointer readProperties = deserializer->GetOutput();
00235
00236 if (readProperties.IsNotNull())
00237 {
00238 propertyList->ConcatenatePropertyList( readProperties, true );
00239 }
00240 else
00241 {
00242 MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell your developer.";
00243 error = true;
00244 }
00245 }
00246 else
00247 {
00248 MITK_ERROR << "Found properties for renderer " << renderwindow << " but there is no such renderer in current application. Ignoring those properties";
00249 error = true;
00250 }
00251 }
00252
00253 return !error;
00254 }
00255