void DataGraph::FillCell(UIHierarchyCell *cell, void *node) { //Temporary fix for loading of UI Interface to avoid reloading of texrures to different formates. // 1. Reset default format before loading of UI // 2. Restore default format after loading of UI from stored settings. Texture::SetDefaultGPU(GPU_UNKNOWN); DataNode *n = (DataNode *)node; UIStaticText *text = (UIStaticText *)cell->FindByName("_Text_"); text->SetText(StringToWString(n->GetName())); UIControl *icon = cell->FindByName("_Icon_"); icon->SetSprite("~res:/Gfx/UI/SceneNode/datanode", 0); UIControl *marker = cell->FindByName("_Marker_"); marker->SetVisible(false); if(n == workingNode) { cell->SetSelected(true, false); } else { cell->SetSelected(false, false); } Texture::SetDefaultGPU(EditorSettings::Instance()->GetTextureViewGPU()); }
void ShowSegmentationAsSmoothedSurface::ThreadedUpdateSuccessful() { DataNode::Pointer node = DataNode::New(); bool wireframe = false; GetParameter("Wireframe", wireframe); if (wireframe) { VtkRepresentationProperty *representation = dynamic_cast<VtkRepresentationProperty *>( node->GetProperty("material.representation")); if (representation != nullptr) representation->SetRepresentationToWireframe(); } node->SetProperty("opacity", FloatProperty::New(1.0)); node->SetProperty("line width", IntProperty::New(1)); node->SetProperty("scalar visibility", BoolProperty::New(false)); std::string groupNodeName = "surface"; DataNode *groupNode = GetGroupNode(); if (groupNode != nullptr) groupNode->GetName(groupNodeName); node->SetProperty("name", StringProperty::New(groupNodeName)); node->SetData(m_Surface); BaseProperty *colorProperty = groupNode->GetProperty("color"); if (colorProperty != nullptr) node->ReplaceProperty("color", colorProperty->Clone()); else node->SetProperty("color", ColorProperty::New(1.0f, 0.0f, 0.0f)); bool showResult = true; GetParameter("Show result", showResult); bool syncVisibility = false; GetParameter("Sync visibility", syncVisibility); Image::Pointer image; GetPointerParameter("Input", image); BaseProperty *organTypeProperty = image->GetProperty("organ type"); if (organTypeProperty != nullptr) m_Surface->SetProperty("organ type", organTypeProperty); BaseProperty *visibleProperty = groupNode->GetProperty("visible"); if (visibleProperty != nullptr && syncVisibility) node->ReplaceProperty("visible", visibleProperty->Clone()); else node->SetProperty("visible", BoolProperty::New(showResult)); InsertBelowGroupNode(node); Superclass::ThreadedUpdateSuccessful(); }
void ShowSegmentationAsSurface::ThreadedUpdateSuccessful() { m_Node = DataNode::New(); bool wireframe(false); GetParameter("Wireframe", wireframe); if (wireframe) { VtkRepresentationProperty *np = dynamic_cast<VtkRepresentationProperty *>(m_Node->GetProperty("material.representation")); if (np) np->SetRepresentationToWireframe(); } m_Node->SetProperty("opacity", FloatProperty::New(0.3)); m_Node->SetProperty("line width", IntProperty::New(1)); m_Node->SetProperty("scalar visibility", BoolProperty::New(false)); std::string groupNodesName("surface"); DataNode *groupNode = GetGroupNode(); if (groupNode) { groupNode->GetName(groupNodesName); // if parameter smooth is set add extension to node name bool smooth(true); GetParameter("Smooth", smooth); if (smooth) groupNodesName.append("_smoothed"); } m_Node->SetProperty("name", StringProperty::New(groupNodesName)); // synchronize this object's color with the parent's color // surfaceNode->SetProperty( "color", parentNode->GetProperty( "color" ) ); // surfaceNode->SetProperty( "visible", parentNode->GetProperty( "visible" ) ); m_Node->SetData(m_Surface); BaseProperty *colorProp = groupNode->GetProperty("color"); if (colorProp) m_Node->ReplaceProperty("color", colorProp->Clone()); else m_Node->SetProperty("color", ColorProperty::New(1.0, 1.0, 0.0)); bool showResult(true); GetParameter("Show result", showResult); bool syncVisibility(false); GetParameter("Sync visibility", syncVisibility); Image::Pointer image; GetPointerParameter("Input", image); BaseProperty *organTypeProp = image->GetProperty("organ type"); if (organTypeProp) m_Surface->SetProperty("organ type", organTypeProp); BaseProperty *visibleProp = groupNode->GetProperty("visible"); if (visibleProp && syncVisibility) m_Node->ReplaceProperty("visible", visibleProp->Clone()); else m_Node->SetProperty("visible", BoolProperty::New(showResult)); InsertBelowGroupNode(m_Node); Superclass::ThreadedUpdateSuccessful(); }
void ShowSegmentationAsSmoothedSurface::ThreadedUpdateSuccessful() { DataNode::Pointer node = LookForPointerTargetBelowGroupNode("Surface representation"); bool addToTree = node.IsNull(); if (addToTree) { node = DataNode::New(); bool wireframe = false; GetParameter("Wireframe", wireframe); if (wireframe) { VtkRepresentationProperty *representation = dynamic_cast<VtkRepresentationProperty *>( node->GetProperty("material.representation")); if (representation != NULL) representation->SetRepresentationToWireframe(); } node->SetProperty("opacity", FloatProperty::New(1.0)); node->SetProperty("line width", IntProperty::New(1)); node->SetProperty("scalar visibility", BoolProperty::New(false)); UIDGenerator uidGenerator("Surface_"); node->SetProperty("FILENAME", StringProperty::New(uidGenerator.GetUID() + ".vtk")); std::string groupNodeName = "surface"; DataNode *groupNode = GetGroupNode(); if (groupNode != NULL) groupNode->GetName(groupNodeName); node->SetProperty("name", StringProperty::New(groupNodeName)); } node->SetData(m_Surface); if (addToTree) { DataNode* groupNode = GetGroupNode(); if (groupNode != NULL) { groupNode->SetProperty("Surface representation", SmartPointerProperty::New(node)); BaseProperty *colorProperty = groupNode->GetProperty("color"); if (colorProperty != NULL) node->ReplaceProperty("color", colorProperty); else node->SetProperty("color", ColorProperty::New(1.0f, 0.0f, 0.0f)); bool showResult = true; GetParameter("Show result", showResult); bool syncVisibility = false; GetParameter("Sync visibility", syncVisibility); Image::Pointer image; GetPointerParameter("Input", image); BaseProperty *organTypeProperty = image->GetProperty("organ type"); if (organTypeProperty != NULL) m_Surface->SetProperty("organ type", organTypeProperty); BaseProperty *visibleProperty = groupNode->GetProperty("visible"); if (visibleProperty != NULL && syncVisibility) node->ReplaceProperty("visible", visibleProperty); else node->SetProperty("visible", BoolProperty::New(showResult)); } InsertBelowGroupNode(node); } Superclass::ThreadedUpdateSuccessful(); }
void SerializedMaterial::WriteData(DataWriter* writer) const { DataNode::SetCurrentMaterial(this); writer->WriteDataStructure(RenderIOAttributes_Writable(VertexInputs), "Vertex inputs"); //Get all the "root" nodes (i.e. all the outputs into the material). std::vector<DataNode*> rootNodes; if (!MaterialOuts.VertexPosOutput.IsConstant()) { rootNodes.insert(rootNodes.end(), MaterialOuts.VertexPosOutput.GetNode()); } for (unsigned int i = 0; i < MaterialOuts.VertexOutputs.size(); ++i) { if (!MaterialOuts.VertexOutputs[i].Value.IsConstant()) { rootNodes.insert(rootNodes.end(), MaterialOuts.VertexOutputs[i].Value.GetNode()); } } for (unsigned int i = 0; i < MaterialOuts.FragmentOutputs.size(); ++i) { if (!MaterialOuts.FragmentOutputs[i].Value.IsConstant()) { rootNodes.insert(rootNodes.end(), MaterialOuts.FragmentOutputs[i].Value.GetNode()); } } //Define each node's "max depth" as the length of the longest chain from the root node // to that node. //Sort all nodes by their max depth. std::unordered_map<DataNode*, unsigned int> nodesAndDepth; unsigned int maxDepth = 0; for (unsigned int rootNodeI = 0; rootNodeI < rootNodes.size(); ++rootNodeI) { //Graph search starting at the root. struct NodeAndDepth { DataNode* Node; unsigned int Depth; NodeAndDepth(DataNode* n = 0, unsigned int d = 0) : Node(n), Depth(d) { } }; std::stack<NodeAndDepth> searchSpace; searchSpace.push(NodeAndDepth(rootNodes[rootNodeI], 0)); //Prevent infinite loops by tracking which edges have already been traversed. //Note that two nodes can be connected along more than one line, // so we have to count how many connections there should be between each pair of nodes. struct Traversal { DataNode *Start, *End; Traversal(DataNode* start = 0, DataNode* end = 0) : Start(start), End(end) { } bool operator==(const Traversal& other) const { return Start == other.Start && End == other.End; } #pragma warning(disable: 4100) unsigned int operator()(const Traversal& v) const { return Vector2i((int)Start, (int)End).GetHashCode(); } #pragma warning(default: 4100) }; std::unordered_map<Traversal, unsigned int, Traversal> connectionsPerTraversal, connectionsSoFar; //Iterate through the search space until all nodes have been traversed. while (!searchSpace.empty()) { //Get the current node. NodeAndDepth toSearch = searchSpace.top(); searchSpace.pop(); //If the node is a special singleton, it shouldn't be written out. if (DataNode::IsSingletonType(toSearch.Node)) { continue; } //If the node already exists, and doesn't have a greater depth here, // then there is no need to traverse its children again. auto found = nodesAndDepth.find(toSearch.Node); if (found != nodesAndDepth.end() && found->second >= toSearch.Depth) { continue; } //Set/update the node's entry in the graph. nodesAndDepth[toSearch.Node] = toSearch.Depth; maxDepth = Mathf::Max(maxDepth, toSearch.Depth); //Add the node's DataNode children (not its constant VectorF children) // to the search space. for (unsigned int childI = 0; childI < toSearch.Node->GetInputs().size(); ++childI) { if (!toSearch.Node->GetInputs()[childI].IsConstant()) { DataNode* child = toSearch.Node->GetInputs()[childI].GetNode(); //Make sure the input actually exists. if (child == 0) { writer->ErrorMessage = "Input node '" + toSearch.Node->GetInputs()[childI].GetNonConstantValue() + "' of node '" + toSearch.Node->GetName() + "' doens't exist!"; throw DataWriter::EXCEPTION_FAILURE; } //Make sure this path hasn't been traversed already. Traversal trvs(toSearch.Node, child); if (connectionsSoFar.find(trvs) != connectionsSoFar.end()) { //If there are more connections between these nodes than there should be, // then this traversal has happened more than once -- i.e., // there is an infinite loop. if (connectionsSoFar[trvs] >= connectionsPerTraversal[trvs]) { writer->ErrorMessage = "Infinite loop detected: The link between '" + toSearch.Node->GetName() + "' and its input '" + child->GetName() + "' has been traversed more than once."; throw DataWriter::EXCEPTION_FAILURE; } else { connectionsSoFar[trvs] += 1; } } else { connectionsSoFar[trvs] = 1; //Count how many connections there should be for this traversal. unsigned int connPerTrav = 0; for (unsigned int j = 0; j < toSearch.Node->GetInputs().size(); ++j) { DataLine& inp = toSearch.Node->GetInputs()[j]; if (!inp.IsConstant() && inp.GetNode() == trvs.End) { connPerTrav += 1; } } connectionsPerTraversal[trvs] = connPerTrav; } //Put the child node into the search space. searchSpace.push(NodeAndDepth(child, toSearch.Depth + 1)); } } } } //Before writing any nodes, write out the number of nodes that will be written. writer->WriteUInt(nodesAndDepth.size(), "Number of nodes"); //Now that we have all nodes sorted by their depth, start with the lowest nodes // (i.e. the fewest dependencies) and work up. for (int depth = (int)maxDepth; depth >= 0; --depth) { unsigned int depthU = (unsigned int)depth; //Get all nodes of this depth and write them. for (auto element = nodesAndDepth.begin(); element != nodesAndDepth.end(); ++element) { if (element->second == depthU) { //Generate a description of the outputs. std::string outputDescription = std::to_string(element->first->GetNumbOutputs()) + " Outputs: "; for (unsigned int i = 0; i < element->first->GetNumbOutputs(); ++i) { if (i > 0) outputDescription += ", "; outputDescription += std::to_string(element->first->GetOutputSize(i)); } //Write the node. writer->WriteDataStructure(SerializedNode(element->first), outputDescription); } } } //Now write out the output declarations. writer->WriteDataStructure(MaterialOuts, "Material outputs"); //Finally, write out the geometry shader. writer->WriteDataStructure(GeoShader, "Geometry shader"); }
bool mitk::SceneIO::SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, const DataStorage* storage, const std::string& filename) { if (!sceneNodes) { MITK_ERROR << "No set of nodes given. Not possible to save scene."; return false; } if (!storage) { MITK_ERROR << "No data storage given. Not possible to save scene."; // \TODO: Technically, it would be possible to save the nodes without their relation return false; } if ( filename.empty() ) { MITK_ERROR << "No filename given. Not possible to save scene."; return false; } try { m_FailedNodes = DataStorage::SetOfObjects::New(); m_FailedProperties = PropertyList::New(); // start XML DOM TiXmlDocument document; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" ); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere... document.LinkEndChild( decl ); TiXmlElement* version = new TiXmlElement("Version"); version->SetAttribute("Writer", __FILE__ ); version->SetAttribute("Revision", "$Revision: 17055 $" ); version->SetAttribute("FileVersion", 1 ); document.LinkEndChild(version); //DataStorage::SetOfObjects::ConstPointer sceneNodes = storage->GetSubset( predicate ); if ( sceneNodes.IsNull() ) { MITK_WARN << "Saving empty scene to " << filename; } else { if ( sceneNodes->size() == 0 ) { MITK_WARN << "Saving empty scene to " << filename; } MITK_INFO << "Storing scene with " << sceneNodes->size() << " objects to " << filename; m_WorkingDirectory = CreateEmptyTempDirectory(); if (m_WorkingDirectory.empty()) { MITK_ERROR << "Could not create temporary directory. Cannot create scene files."; return false; } ProgressBar::GetInstance()->AddStepsToDo( sceneNodes->size() ); // find out about dependencies typedef std::map< DataNode*, std::string > UIDMapType; typedef std::map< DataNode*, std::list<std::string> > SourcesMapType; UIDMapType nodeUIDs; // for dependencies: ID of each node SourcesMapType sourceUIDs; // for dependencies: IDs of a node's parent nodes UIDGenerator nodeUIDGen("OBJECT_"); for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin(); iter != sceneNodes->end(); ++iter) { DataNode* node = iter->GetPointer(); if (!node) continue; // unlikely event that we get a NULL pointer as an object for saving. just ignore // generate UIDs for all source objects DataStorage::SetOfObjects::ConstPointer sourceObjects = storage->GetSources( node ); for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = sourceObjects->begin(); sourceIter != sourceObjects->end(); ++sourceIter ) { if ( std::find( sceneNodes->begin(), sceneNodes->end(), *sourceIter ) == sceneNodes->end() ) continue; // source is not saved, so don't generate a UID for this source // create a uid for the parent object if ( nodeUIDs[ *sourceIter ].empty() ) { nodeUIDs[ *sourceIter ] = nodeUIDGen.GetUID(); } // store this dependency for writing sourceUIDs[ node ].push_back( nodeUIDs[*sourceIter] ); } if ( nodeUIDs[ node ].empty() ) { nodeUIDs[ node ] = nodeUIDGen.GetUID(); } } // write out objects, dependencies and properties for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin(); iter != sceneNodes->end(); ++iter) { DataNode* node = iter->GetPointer(); if (node) { TiXmlElement* nodeElement = new TiXmlElement("node"); std::string filenameHint( node->GetName() ); filenameHint = itksys::SystemTools::MakeCindentifier(filenameHint.c_str()); // escape filename <-- only allow [A-Za-z0-9_], replace everything else with _ // store dependencies UIDMapType::iterator searchUIDIter = nodeUIDs.find(node); if ( searchUIDIter != nodeUIDs.end() ) { // store this node's ID nodeElement->SetAttribute("UID", searchUIDIter->second.c_str() ); } SourcesMapType::iterator searchSourcesIter = sourceUIDs.find(node); if ( searchSourcesIter != sourceUIDs.end() ) { // store all source IDs for ( std::list<std::string>::iterator sourceUIDIter = searchSourcesIter->second.begin(); sourceUIDIter != searchSourcesIter->second.end(); ++sourceUIDIter ) { TiXmlElement* uidElement = new TiXmlElement("source"); uidElement->SetAttribute("UID", sourceUIDIter->c_str() ); nodeElement->LinkEndChild( uidElement ); } } // store basedata if ( BaseData* data = node->GetData() ) { //std::string filenameHint( node->GetName() ); bool error(false); TiXmlElement* dataElement( SaveBaseData( data, filenameHint, error ) ); // returns a reference to a file if (error) { m_FailedNodes->push_back( node ); } // store basedata properties PropertyList* propertyList = data->GetPropertyList(); if (propertyList && !propertyList->IsEmpty() ) { TiXmlElement* baseDataPropertiesElement( SavePropertyList( propertyList, filenameHint + "-data") ); // returns a reference to a file dataElement->LinkEndChild( baseDataPropertiesElement ); } nodeElement->LinkEndChild( dataElement ); } // store all renderwindow specific propertylists const RenderingManager::RenderWindowVector& allRenderWindows( RenderingManager::GetInstance()->GetAllRegisteredRenderWindows() ); for ( RenderingManager::RenderWindowVector::const_iterator rw = allRenderWindows.begin(); rw != allRenderWindows.end(); ++rw) { if (vtkRenderWindow* renderWindow = *rw) { std::string renderWindowName( mitk::BaseRenderer::GetInstance(renderWindow)->GetName() ); BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(renderWindow); PropertyList* propertyList = node->GetPropertyList(renderer); if ( propertyList && !propertyList->IsEmpty() ) { TiXmlElement* renderWindowPropertiesElement( SavePropertyList( propertyList, filenameHint + "-" + renderWindowName) ); // returns a reference to a file renderWindowPropertiesElement->SetAttribute("renderwindow", renderWindowName); nodeElement->LinkEndChild( renderWindowPropertiesElement ); } } } // don't forget the renderwindow independent list PropertyList* propertyList = node->GetPropertyList(); if ( propertyList && !propertyList->IsEmpty() ) { TiXmlElement* propertiesElement( SavePropertyList( propertyList, filenameHint + "-node") ); // returns a reference to a file nodeElement->LinkEndChild( propertiesElement ); } document.LinkEndChild( nodeElement ); } else { MITK_WARN << "Ignoring NULL node during scene serialization."; } ProgressBar::GetInstance()->Progress(); } // end for all nodes } // end if sceneNodes if ( !document.SaveFile( m_WorkingDirectory + Poco::Path::separator() + "index.xml" ) ) { MITK_ERROR << "Could not write scene to " << m_WorkingDirectory << Poco::Path::separator() << "index.xml" << "\nTinyXML reports '" << document.ErrorDesc() << "'"; return false; } else { try { Poco::File deleteFile( filename.c_str() ); if (deleteFile.exists()) { deleteFile.remove(); } // create zip at filename std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out); if (!file.good()) { MITK_ERROR << "Could not open a zip file for writing: '" << filename << "'"; } else { Poco::Zip::Compress zipper( file, true ); Poco::Path tmpdir( m_WorkingDirectory ); zipper.addRecursive( tmpdir ); zipper.close(); } try { Poco::File deleteDir( m_WorkingDirectory ); deleteDir.remove(true); // recursive } catch(...) { MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory; return false; // ok? } } catch(std::exception& e) { MITK_ERROR << "Could not create ZIP file from " << m_WorkingDirectory << "\nReason: " << e.what(); return false; } return true; } } catch(std::exception& e) { MITK_ERROR << "Caught exception during saving temporary files to disk. Error description: '" << e.what() << "'"; return false; } }