diff --git a/Core/Code/DataManagement/mitkDataNode.cpp b/Core/Code/DataManagement/mitkDataNode.cpp index f126dba1f7..068be6c4fa 100644 --- a/Core/Code/DataManagement/mitkDataNode.cpp +++ b/Core/Code/DataManagement/mitkDataNode.cpp @@ -1,574 +1,574 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDataNode.h" #include "mitkCoreObjectFactory.h" #include #include #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkGroupTagProperty.h" #include "mitkSmartPointerProperty.h" //#include "mitkMaterialProperty.h" #include "mitkColorProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkGeometry3D.h" #include "mitkRenderingManager.h" #include "mitkGlobalInteraction.h" #include "mitkEventMapper.h" #include "mitkGenericProperty.h" #include "mitkCoreObjectFactory.h" mitk::Mapper* mitk::DataNode::GetMapper(MapperSlotId id) const { if( (id >= m_Mappers.size()) || (m_Mappers[id].IsNull()) ) { if(id >= m_Mappers.capacity()) { // int i, size=id-m_Mappers.capacity()+10; m_Mappers.resize(id+10); } m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast(this),id); } return m_Mappers[id]; } mitk::BaseData* mitk::DataNode::GetData() const { return m_Data; } mitk::Interactor* mitk::DataNode::GetInteractor() const { return m_Interactor; } void mitk::DataNode::SetData(mitk::BaseData* baseData) { if(m_Data!=baseData) { m_Data=baseData; m_Mappers.clear(); m_Mappers.resize(10); mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); m_DataReferenceChangedTime.Modified(); Modified(); //inform the interactor about the change if (m_Interactor.IsNotNull()) m_Interactor->DataChanged(); } } void mitk::DataNode::SetInteractor(mitk::Interactor* interactor) { m_Interactor = interactor; if(m_Interactor.IsNotNull()) m_Interactor->SetDataNode(this); } mitk::DataNode::DataNode() : m_Data(NULL), m_PropertyListModifiedObserverTag(0) { m_Mappers.resize(10); m_PropertyList = PropertyList::New(); // subscribe for modified event itk::MemberCommand::Pointer _PropertyListModifiedCommand = itk::MemberCommand::New(); _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified); m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); } mitk::DataNode::~DataNode() { if(m_PropertyList.IsNotNull()) // remove modified event listener m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag); Interactor* interactor = this->GetInteractor(); if ( interactor ) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor( interactor ); } m_Mappers.clear(); m_Data = NULL; } mitk::DataNode& mitk::DataNode::operator=(const DataNode& right) { mitk::DataNode* node=mitk::DataNode::New(); node->SetData(right.GetData()); return *node; } mitk::DataNode& mitk::DataNode::operator=(mitk::BaseData* right) { mitk::DataNode* node=mitk::DataNode::New(); node->SetData(right); return *node; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) MBI_STD::istream& mitk::operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn ) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) MBI_STD::istream& operator>>( MBI_STD::istream& i, mitk::DataNode::Pointer& dtn ) #endif { dtn = mitk::DataNode::New(); //i >> av.get(); return i; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) MBI_STD::ostream& mitk::operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) MBI_STD::ostream& operator<<( MBI_STD::ostream& o, mitk::DataNode::Pointer& dtn) #endif { if(dtn->GetData()!=NULL) o<GetData()->GetNameOfClass(); else o<<"empty data"; return o; } void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper* mapper) { m_Mappers[id] = mapper; if (mapper!=NULL) mapper->SetDataNode(this); } void mitk::DataNode::UpdateOutputInformation() { if (this->GetSource()) { this->GetSource()->UpdateOutputInformation(); } } void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::DataNode::VerifyRequestedRegion() { return true; } void mitk::DataNode::SetRequestedRegion(itk::DataObject * /*data*/) { } void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/) { } mitk::PropertyList* mitk::DataNode::GetPropertyList(const mitk::BaseRenderer* renderer) const { if(renderer==NULL) return m_PropertyList; mitk::PropertyList::Pointer & propertyList = m_MapOfPropertyLists[renderer]; if(propertyList.IsNull()) propertyList = mitk::PropertyList::New(); assert(m_MapOfPropertyLists[renderer].IsNotNull()); return propertyList; } void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty* mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer* renderer) const { if(propertyKey==NULL) return NULL; //renderer specified? if (renderer) { std::map::const_iterator it; //check for the renderer specific property it=m_MapOfPropertyLists.find(renderer); if(it!=m_MapOfPropertyLists.end()) //found { mitk::BaseProperty::Pointer property; property=it->second->GetProperty(propertyKey); if(property.IsNotNull())//found an enabled property in the render specific list return property; else //found a renderer specific list, but not the desired property return m_PropertyList->GetProperty(propertyKey); //return renderer unspecific property } else //didn't find the property list of the given renderer { //return the renderer unspecific property if there is one return m_PropertyList->GetProperty(propertyKey); } } else //no specific renderer given; use the renderer independent one { mitk::BaseProperty::Pointer property; property=m_PropertyList->GetProperty(propertyKey); if(property.IsNotNull()) return property; } //only to satisfy compiler! return NULL; } mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const { GroupTagList groups; const PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap(); for ( PropertyList::PropertyMap::const_iterator groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here groupIter != propertyMap->end(); ++groupIter ) { - const BaseProperty* bp = groupIter->second.first; - if ( dynamic_cast(bp) && groupIter->second.second ) + const BaseProperty* bp = groupIter->second; + if ( dynamic_cast(bp) ) { groups.insert( groupIter->first ); } } return groups; } bool mitk::DataNode::GetBoolProperty(const char* propertyKey, bool& boolValue, mitk::BaseRenderer* renderer) const { mitk::BoolProperty::Pointer boolprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool mitk::DataNode::GetIntProperty(const char* propertyKey, int &intValue, mitk::BaseRenderer* renderer) const { mitk::IntProperty::Pointer intprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(intprop.IsNull()) return false; intValue = intprop->GetValue(); return true; } bool mitk::DataNode::GetFloatProperty(const char* propertyKey, float &floatValue, mitk::BaseRenderer* renderer) const { mitk::FloatProperty::Pointer floatprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(floatprop.IsNull()) return false; floatValue = floatprop->GetValue(); return true; } bool mitk::DataNode::GetStringProperty(const char* propertyKey, std::string& string, mitk::BaseRenderer* renderer) const { mitk::StringProperty::Pointer stringProp = dynamic_cast(GetProperty(propertyKey, renderer)); if(stringProp.IsNull()) { return false; } else { //memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous string = stringProp->GetValue(); return true; } } bool mitk::DataNode::GetColor(float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(colorprop.IsNull()) return false; memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); return true; } bool mitk::DataNode::GetOpacity(float &opacity, mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey, renderer)); if(opacityprop.IsNull()) return false; opacity=opacityprop->GetValue(); return true; } bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) const { mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast(GetProperty(propertyKey, renderer)); if(levWinProp.IsNull()) return false; levelWindow=levWinProp->GetLevelWindow(); return true; } void mitk::DataNode::SetColor(const mitk::Color &color, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetColor(float red, float green, float blue, mitk::BaseRenderer* renderer, const char* propertyKey) { float color[3]; color[0]=red; color[1]=green; color[2]=blue; SetColor(color, renderer, propertyKey); } void mitk::DataNode::SetColor(const float rgb[3], mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetVisibility(bool visible, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetOpacity(float opacity, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, mitk::BaseRenderer* renderer, const char* propertyKey) { mitk::LevelWindowProperty::Pointer prop; prop = mitk::LevelWindowProperty::New(levelWindow); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetIntProperty(const char* propertyKey, int intValue, mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::DataNode::SetBoolProperty( const char* propertyKey, bool boolValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::DataNode::SetFloatProperty( const char* propertyKey, float floatValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::DataNode::SetStringProperty( const char* propertyKey, const char* stringValue, mitk::BaseRenderer* renderer/*=NULL*/ ) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void mitk::DataNode::SetProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue); } void mitk::DataNode::ReplaceProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer) { GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue); } void mitk::DataNode::AddProperty(const char *propertyKey, BaseProperty* propertyValue, const mitk::BaseRenderer* renderer, bool overwrite) { if((overwrite) || (GetProperty(propertyKey, renderer) == NULL)) { SetProperty(propertyKey, propertyValue, renderer); } } vtkLinearTransform* mitk::DataNode::GetVtkTransform(int t) const { assert(m_Data.IsNotNull()); mitk::Geometry3D* geometry = m_Data->GetGeometry(t); if(geometry == NULL) return NULL; return geometry->GetVtkTransform(); } unsigned long mitk::DataNode::GetMTime() const { unsigned long time = Superclass::GetMTime(); if(m_Data.IsNotNull()) { if((time < m_Data->GetMTime()) || ((m_Data->GetSource() != NULL) && (time < m_Data->GetSource()->GetMTime())) ) { Modified(); return Superclass::GetMTime(); } } return time; } void mitk::DataNode::SetSelected(bool selected, mitk::BaseRenderer* renderer) { mitk::BoolProperty::Pointer selectedProperty = dynamic_cast(GetProperty("selected")); if ( selectedProperty.IsNull() ) { selectedProperty = mitk::BoolProperty::New(); selectedProperty->SetValue(false); SetProperty("selected", selectedProperty, renderer); } if( selectedProperty->GetValue() != selected ) { selectedProperty->SetValue(selected); itk::ModifiedEvent event; InvokeEvent( event ); } } /* class SelectedEvent : public itk::ModifiedEvent { public: typedef SelectedEvent Self; typedef itk::ModifiedEvent Superclass; SelectedEvent(DataNode* dataNode) { m_DataNode = dataNode; }; DataNode* GetDataNode() { return m_DataNode; }; virtual const char * GetEventName() const { return "SelectedEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_DataNode); } private: DataNode* m_DataNode; SelectedEvent(const Self& event) { m_DataNode = event.m_DataNode; }; void operator=(const Self& event) { m_DataNode = event.m_DataNode; } }; */ bool mitk::DataNode::IsSelected(mitk::BaseRenderer* renderer) { bool selected; if ( !GetBoolProperty("selected", selected, renderer) ) return false; return selected; } void mitk::DataNode::SetInteractorEnabled( const bool& enabled ) { if ( m_Interactor.IsNull() ) { itkWarningMacro("Interactor is NULL. Couldn't enable or disable interaction."); return; } if ( enabled ) mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor.GetPointer() ); else mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor.GetPointer() ); } void mitk::DataNode::EnableInteractor() { SetInteractorEnabled( true ); } void mitk::DataNode::DisableInteractor() { SetInteractorEnabled( false ); } bool mitk::DataNode::IsInteractorEnabled() const { return mitk::GlobalInteraction::GetInstance()->InteractorRegistered( m_Interactor.GetPointer() ); } void mitk::DataNode::PropertyListModified( const itk::Object* /*caller*/, const itk::EventObject& ) { Modified(); } #ifndef _MSC_VER template bool mitk::DataNode::GetPropertyValue(const char* propertyKey, T & value, mitk::BaseRenderer* renderer) const { GenericProperty* gp= dynamic_cast*>(GetProperty(propertyKey, renderer) ); if ( gp != NULL ) { value = gp->GetValue(); return true; } return false; } template bool mitk::DataNode::GetPropertyValue(char const*, double&, mitk::BaseRenderer*) const; template bool mitk::DataNode::GetPropertyValue(char const*, float&, mitk::BaseRenderer*) const; template bool mitk::DataNode::GetPropertyValue(char const*, int&, mitk::BaseRenderer*) const; template bool mitk::DataNode::GetPropertyValue(char const*, bool&, mitk::BaseRenderer*) const; #endif diff --git a/Core/Code/DataManagement/mitkDataStorage.cpp b/Core/Code/DataManagement/mitkDataStorage.cpp index 4e1edd044b..9ee1adb74d 100644 --- a/Core/Code/DataManagement/mitkDataStorage.cpp +++ b/Core/Code/DataManagement/mitkDataStorage.cpp @@ -1,513 +1,513 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDataStorage.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkNodePredicateBase.h" #include "mitkNodePredicateProperty.h" #include "mitkGroupTagProperty.h" #include "itkMutexLockHolder.h" #include "itkCommand.h" mitk::DataStorage::DataStorage() : itk::Object() , m_BlockNodeModifiedEvents(false) { } mitk::DataStorage::~DataStorage() { ///// we can not call GetAll() in destructor, because it is implemented in a subclass //SetOfObjects::ConstPointer all = this->GetAll(); //for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) // this->RemoveListeners(it->Value()); //m_NodeModifiedObserverTags.clear(); //m_NodeDeleteObserverTags.clear(); } void mitk::DataStorage::Add(mitk::DataNode* node, mitk::DataNode* parent) { mitk::DataStorage::SetOfObjects::Pointer parents = mitk::DataStorage::SetOfObjects::New(); parents->InsertElement(0, parent); this->Add(node, parents); } void mitk::DataStorage::Remove(const mitk::DataStorage::SetOfObjects* nodes) { if (nodes == NULL) return; for (mitk::DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); it++) this->Remove(it.Value()); } mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::GetSubset(const NodePredicateBase* condition) const { mitk::DataStorage::SetOfObjects::ConstPointer result = this->FilterSetOfObjects(this->GetAll(), condition); return result; } mitk::DataNode* mitk::DataStorage::GetNamedNode(const char* name) const { if (name == NULL) return NULL; mitk::StringProperty::Pointer s(mitk::StringProperty::New(name)); mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s); mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(p); if (rs->Size() >= 1) return rs->GetElement(0); else return NULL; } mitk::DataNode* mitk::DataStorage::GetNode(const NodePredicateBase* condition) const { if (condition == NULL) return NULL; mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetSubset(condition); if (rs->Size() >= 1) return rs->GetElement(0); else return NULL; } mitk::DataNode* mitk::DataStorage::GetNamedDerivedNode(const char* name, const mitk::DataNode* sourceNode, bool onlyDirectDerivations) const { if (name == NULL) return NULL; mitk::StringProperty::Pointer s(mitk::StringProperty::New(name)); mitk::NodePredicateProperty::Pointer p = mitk::NodePredicateProperty::New("name", s); mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDerivations(sourceNode, p, onlyDirectDerivations); if (rs->Size() >= 1) return rs->GetElement(0); else return NULL; } void mitk::DataStorage::PrintSelf(std::ostream& os, itk::Indent indent) const { //Superclass::PrintSelf(os, indent); mitk::DataStorage::SetOfObjects::ConstPointer all = this->GetAll(); os << indent << "DataStorage " << this << " is managing " << all->Size() << " objects. List of objects:" << std::endl; for (mitk::DataStorage::SetOfObjects::ConstIterator allIt = all->Begin(); allIt != all->End(); allIt++) { std::string name; allIt.Value()->GetName(name); std::string datatype; if (allIt.Value()->GetData() != NULL) datatype = allIt.Value()->GetData()->GetNameOfClass(); os << indent << " " << allIt.Value().GetPointer() << "<" << datatype << ">: " << name << std::endl; mitk::DataStorage::SetOfObjects::ConstPointer parents = this->GetSources(allIt.Value()); if (parents->Size() > 0) { os << indent << " Direct sources: "; for (mitk::DataStorage::SetOfObjects::ConstIterator parentIt = parents->Begin(); parentIt != parents->End(); parentIt++) os << parentIt.Value().GetPointer() << ", "; os << std::endl; } mitk::DataStorage::SetOfObjects::ConstPointer derivations = this->GetDerivations(allIt.Value()); if (derivations->Size() > 0) { os << indent << " Direct derivations: "; for (mitk::DataStorage::SetOfObjects::ConstIterator derivationIt = derivations->Begin(); derivationIt != derivations->End(); derivationIt++) os << derivationIt.Value().GetPointer() << ", "; os << std::endl; } } os << std::endl; } mitk::DataStorage::SetOfObjects::ConstPointer mitk::DataStorage::FilterSetOfObjects(const SetOfObjects* set, const NodePredicateBase* condition) const { if (set == NULL) return NULL; mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = set->Begin(); it != set->End(); it++) if (condition == NULL || condition->CheckNode(it.Value()) == true) //alway copy the set, otherwise the iterator in mitk::DataStorage::Remove() will crash result->InsertElement(result->Size(), it.Value()); return mitk::DataStorage::SetOfObjects::ConstPointer(result); } const mitk::DataNode::GroupTagList mitk::DataStorage::GetGroupTags() const { DataNode::GroupTagList result; SetOfObjects::ConstPointer all = this->GetAll(); if (all.IsNull()) return result; for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = all->Begin(); nodeIt != all->End(); nodeIt++) // for each node { mitk::PropertyList* pl = nodeIt.Value()->GetPropertyList(); for (mitk::PropertyList::PropertyMap::const_iterator propIt = pl->GetMap()->begin(); propIt != pl->GetMap()->end(); propIt++) - if (dynamic_cast(propIt->second.first.GetPointer()) != NULL) + if (dynamic_cast(propIt->second.GetPointer()) != NULL) result.insert(propIt->first); } return result; } void mitk::DataStorage::EmitAddNodeEvent(const mitk::DataNode* node) { AddNodeEvent.Send(node); } void mitk::DataStorage::EmitRemoveNodeEvent(const mitk::DataNode* node) { RemoveNodeEvent.Send(node); } void mitk::DataStorage::OnNodeModifiedOrDeleted( const itk::Object *caller, const itk::EventObject &event ) { if(m_BlockNodeModifiedEvents) return; const mitk::DataNode* _Node = dynamic_cast(caller); if(_Node) { const itk::ModifiedEvent* modEvent = dynamic_cast(&event); if(modEvent) ChangedNodeEvent.Send(_Node); else DeleteNodeEvent.Send(_Node); } } void mitk::DataStorage::AddListeners( const mitk::DataNode* _Node ) { itk::MutexLockHolder locked(m_MutexOne); // node must not be 0 and must not be yet registered mitk::DataNode* NonConstNode = const_cast(_Node); if(_Node && m_NodeModifiedObserverTags .find(NonConstNode) == m_NodeModifiedObserverTags.end()) { itk::MemberCommand::Pointer nodeModifiedCommand = itk::MemberCommand::New(); nodeModifiedCommand->SetCallbackFunction(this , &mitk::DataStorage::OnNodeModifiedOrDeleted); m_NodeModifiedObserverTags[NonConstNode] = NonConstNode->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand); // add itk delete listener on datastorage itk::MemberCommand::Pointer deleteCommand = itk::MemberCommand::New(); deleteCommand->SetCallbackFunction(this, &mitk::DataStorage::OnNodeModifiedOrDeleted); // add observer m_NodeDeleteObserverTags[NonConstNode] = NonConstNode->AddObserver(itk::DeleteEvent(), deleteCommand); } } void mitk::DataStorage::RemoveListeners( const mitk::DataNode* _Node ) { itk::MutexLockHolder locked(m_MutexOne) ; // node must not be 0 and must be registered mitk::DataNode* NonConstNode = const_cast(_Node); if(_Node && m_NodeModifiedObserverTags .find(NonConstNode) != m_NodeModifiedObserverTags.end()) { // const cast is bad! but sometimes it is necessary. removing an observer does not really // touch the internal state NonConstNode->RemoveObserver(m_NodeModifiedObserverTags .find(NonConstNode)->second); NonConstNode->RemoveObserver(m_NodeDeleteObserverTags .find(NonConstNode)->second); m_NodeModifiedObserverTags.erase(NonConstNode); m_NodeDeleteObserverTags.erase(NonConstNode); } } mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const SetOfObjects* input, const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) { if (input == NULL) throw std::invalid_argument("DataStorage: input is invalid"); BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New(); BoundingBox::PointIdentifier pointid=0; Point3D point; Vector3D minSpacing; minSpacing.Fill(ScalarTypeNumericTraits::max()); ScalarType stmin, stmax; stmin= ScalarTypeNumericTraits::NonpositiveMin(); stmax= ScalarTypeNumericTraits::max(); ScalarType minimalIntervallSize = stmax; ScalarType minimalTime = stmax; ScalarType maximalTime = 0; // Needed for check of zero bounding boxes mitk::ScalarType nullpoint[]={0,0,0,0,0,0}; BoundingBox::BoundsArrayType itkBoundsZero(nullpoint); for (SetOfObjects::ConstIterator it = input->Begin(); it != input->End(); ++it) { DataNode::Pointer node = it->Value(); if((node.IsNotNull()) && (node->GetData() != NULL) && (node->GetData()->IsEmpty()==false) && node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer) ) { const TimeSlicedGeometry* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry(); if (geometry != NULL ) { // bounding box (only if non-zero) BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBox()->GetBounds(); if (itkBounds == itkBoundsZero) { continue; } unsigned char i; for(i=0; i<8; ++i) { point = geometry->GetCornerPoint(i); if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large) pointscontainer->InsertElement( pointid++, point); else { itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node ); } } // spacing try { AffineTransform3D::Pointer inverseTransform = AffineTransform3D::New(); geometry->GetIndexToWorldTransform()->GetInverse(inverseTransform); vnl_vector< AffineTransform3D::MatrixType::ValueType > unitVector(3); int axis; for(axis = 0; axis < 3; ++axis) { unitVector.fill(0); unitVector[axis] = 1.0; ScalarType mmPerPixel = 1.0/(inverseTransform->GetMatrix()*unitVector).magnitude(); if(minSpacing[axis] > mmPerPixel) { minSpacing[axis] = mmPerPixel; } } // time bounds // iterate over all time steps // Attention: Objects with zero bounding box are not respected in time bound calculation TimeBounds minTB = geometry->GetTimeBounds(); for (unsigned int i=0; iGetTimeSteps(); i++) { const TimeBounds & curTimeBounds = node->GetData()->GetGeometry(i)->GetTimeBounds(); // get the minimal time of all objects in the DataStorage if ((curTimeBounds[0]stmin)) { minimalTime=curTimeBounds[0]; } // get the maximal time of all objects in the DataStorage if ((curTimeBounds[1]>maximalTime)&&(curTimeBounds[1]SetPoints(pointscontainer); result->ComputeBoundingBox(); // minimal time bounds of a single time step for all geometries TimeBounds minTimeBounds; minTimeBounds[0] = 0; minTimeBounds[1] = 1; // compute the number of time steps unsigned int numberOfTimeSteps = 1; if (maximalTime!=0) // make sure that there is at least one time sliced geometry in the data storage { minTimeBounds[0] = minimalTime; minTimeBounds[1] = minimalTime + minimalIntervallSize; numberOfTimeSteps = (maximalTime-minimalTime)/minimalIntervallSize; } TimeSlicedGeometry::Pointer timeSlicedGeometry = NULL; if ( result->GetPoints()->Size()>0 ) { // Initialize a geometry of a single time step Geometry3D::Pointer geometry = Geometry3D::New(); geometry->Initialize(); // correct bounding-box (is now in mm, should be in index-coordinates) // according to spacing BoundingBox::BoundsArrayType bounds = result->GetBounds(); int i; for(i = 0; i < 6; ++i) { bounds[i] /= minSpacing[i/2]; } geometry->SetBounds(bounds); geometry->SetSpacing(minSpacing); geometry->SetTimeBounds(minTimeBounds); // Initialize the time sliced geometry timeSlicedGeometry = TimeSlicedGeometry::New(); timeSlicedGeometry->InitializeEvenlyTimed(geometry,numberOfTimeSteps); } return timeSlicedGeometry; } mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeBoundingGeometry3D( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) { return this->ComputeBoundingGeometry3D(this->GetAll(), boolPropertyKey, renderer, boolPropertyKey2); } mitk::TimeSlicedGeometry::Pointer mitk::DataStorage::ComputeVisibleBoundingGeometry3D( mitk::BaseRenderer* renderer, const char* boolPropertyKey ) { return ComputeBoundingGeometry3D( "visible", renderer, boolPropertyKey ); } mitk::BoundingBox::Pointer mitk::DataStorage::ComputeBoundingBox( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) { BoundingBox::PointsContainer::Pointer pointscontainer=BoundingBox::PointsContainer::New(); BoundingBox::PointIdentifier pointid=0; Point3D point; // Needed for check of zero bounding boxes mitk::ScalarType nullpoint[]={0,0,0,0,0,0}; BoundingBox::BoundsArrayType itkBoundsZero(nullpoint); SetOfObjects::ConstPointer all = this->GetAll(); for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { DataNode::Pointer node = it->Value(); if((node.IsNotNull()) && (node->GetData() != NULL) && (node->GetData()->IsEmpty()==false) && node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer) ) { const Geometry3D* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry(); if (geometry != NULL ) { // bounding box (only if non-zero) BoundingBox::BoundsArrayType itkBounds = geometry->GetBoundingBox()->GetBounds(); if (itkBounds == itkBoundsZero) { continue; } unsigned char i; for(i=0; i<8; ++i) { point = geometry->GetCornerPoint(i); if(point[0]*point[0]+point[1]*point[1]+point[2]*point[2] < large) pointscontainer->InsertElement( pointid++, point); else { itkGenericOutputMacro( << "Unrealistically distant corner point encountered. Ignored. Node: " << node ); } } } } } BoundingBox::Pointer result = BoundingBox::New(); result->SetPoints(pointscontainer); result->ComputeBoundingBox(); return result; } mitk::TimeBounds mitk::DataStorage::ComputeTimeBounds( const char* boolPropertyKey, mitk::BaseRenderer* renderer, const char* boolPropertyKey2) { TimeBounds timeBounds; ScalarType stmin, stmax, cur; stmin= ScalarTypeNumericTraits::NonpositiveMin(); stmax= ScalarTypeNumericTraits::max(); timeBounds[0]=stmax; timeBounds[1]=stmin; SetOfObjects::ConstPointer all = this->GetAll(); for (SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { DataNode::Pointer node = it->Value(); if((node.IsNotNull()) && (node->GetData() != NULL) && (node->GetData()->IsEmpty()==false) && node->IsOn(boolPropertyKey, renderer) && node->IsOn(boolPropertyKey2, renderer) ) { const Geometry3D* geometry = node->GetData()->GetUpdatedTimeSlicedGeometry(); if (geometry != NULL ) { const TimeBounds & curTimeBounds = geometry->GetTimeBounds(); cur=curTimeBounds[0]; //is it after -infinity, but before everything else that we found until now? if((cur > stmin) && (cur < timeBounds[0])) timeBounds[0] = cur; cur=curTimeBounds[1]; //is it before infinity, but after everything else that we found until now? if((cur < stmax) && (cur > timeBounds[1])) timeBounds[1] = cur; } } } if(!(timeBounds[0] < stmax)) { timeBounds[0] = stmin; timeBounds[1] = stmax; } return timeBounds; } diff --git a/Core/Code/DataManagement/mitkPropertyList.cpp b/Core/Code/DataManagement/mitkPropertyList.cpp index 03879b3ced..c464d702cf 100644 --- a/Core/Code/DataManagement/mitkPropertyList.cpp +++ b/Core/Code/DataManagement/mitkPropertyList.cpp @@ -1,317 +1,293 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkPropertyList.h" #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkVector.h" mitk::BaseProperty* mitk::PropertyList::GetProperty(const std::string& propertyKey) const { PropertyMap::const_iterator it; it=m_Properties.find( propertyKey ); - if(it!=m_Properties.end() && it->second.second ) - return it->second.first; + if(it!=m_Properties.end()) + return it->second; else return NULL; } void mitk::PropertyList::SetProperty(const std::string& propertyKey, BaseProperty* property) { if (!property) return; //make sure that BaseProperty*, which may have just been created and never been //assigned to a SmartPointer, is registered/unregistered properly. If we do not //do that, it will a) not deleted in case it is identical to the old one or //b) possibly deleted when temporarily added to a smartpointer somewhere below. BaseProperty::Pointer tmpSmartPointerToProperty = property; PropertyMap::iterator it( m_Properties.find( propertyKey ) ); // Is a property with key @a propertyKey contained in the list? if( it != m_Properties.end() ) { // yes //is the property contained in the list identical to the new one? - if( it->second.first == property) + if( it->second == property) { // yes? do nothing and return. return; } // compatible? then use operator= to assign value - if (it->second.first->Assignable( *property )) + if (it->second->Assignable( *property )) { - bool changed = (it->second.first->GetValueAsString() != property->GetValueAsString()); - *(static_cast(it->second.first.GetPointer())) = *property; + bool changed = (it->second->GetValueAsString() != property->GetValueAsString()); + *(static_cast(it->second.GetPointer())) = *property; // muellerm,20.10: added modified event if(changed) this->Modified(); return; } - if ( typeid( *(it->second.first.GetPointer()) ) != typeid( *property ) ) + if ( typeid( *(it->second.GetPointer()) ) != typeid( *property ) ) { // Accept only if the two types are matching. For replacing, use // ReplaceProperty. MITK_ERROR << "In " __FILE__ ", l." << __LINE__ << ": Trying to set existing property to a property with different type." << " Use ReplaceProperty() instead." << std::endl; return; } // If types are identical, but the property has no operator= (s.a.), // overwrite the pointer. - it->second.first = property; + it->second = property; return; } //no? add/replace it. PropertyMapElementType newProp; newProp.first = propertyKey; - newProp.second = std::pair(property,true); + newProp.second = property; m_Properties.insert ( newProp ); this->Modified(); } void mitk::PropertyList::ReplaceProperty(const std::string& propertyKey, BaseProperty* property) { if (!property) return; PropertyMap::iterator it( m_Properties.find( propertyKey ) ); // Is a property with key @a propertyKey contained in the list? if( it != m_Properties.end() ) { - it->second.first=NULL; + it->second=NULL; m_Properties.erase(it); } //no? add/replace it. PropertyMapElementType newProp; newProp.first = propertyKey; - newProp.second = std::pair(property,true); + newProp.second = property; m_Properties.insert ( newProp ); Modified(); } mitk::PropertyList::PropertyList() { } mitk::PropertyList::~PropertyList() { Clear(); } /** * Consider the list as changed when any of the properties has changed recently. */ unsigned long mitk::PropertyList::GetMTime() const { for ( PropertyMap::const_iterator it = m_Properties.begin() ; it != m_Properties.end(); ++it ) { - if( it->second.first.IsNull() ) + if( it->second.IsNull() ) { itkWarningMacro(<< "Property '" << it->first <<"' contains nothing (NULL)."); continue; } - if( Superclass::GetMTime() < it->second.first->GetMTime() ) + if( Superclass::GetMTime() < it->second->GetMTime() ) { Modified(); break; } } return Superclass::GetMTime(); } bool mitk::PropertyList::DeleteProperty(const std::string& propertyKey) { PropertyMap::iterator it; it=m_Properties.find( propertyKey ); if(it!=m_Properties.end()) { - it->second.first=NULL; + it->second=NULL; m_Properties.erase(it); Modified(); return true; } return false; } mitk::PropertyList::Pointer mitk::PropertyList::Clone() { mitk::PropertyList::Pointer newPropertyList = PropertyList::New(); // copy the map newPropertyList->m_Properties = m_Properties; return newPropertyList.GetPointer(); } void mitk::PropertyList::Clear() { PropertyMap::iterator it = m_Properties.begin(), end = m_Properties.end(); while(it!=end) { - it->second.first = NULL; + it->second = NULL; ++it; } m_Properties.clear(); } -bool mitk::PropertyList::IsEnabled(const std::string& propertyKey) -{ - PropertyMap::iterator it = m_Properties.find( propertyKey ); - if (it != m_Properties.end() && it->second.second) - { - return true; - } - else - { - return false; - } -} - - -void mitk::PropertyList::SetEnabled(const std::string& propertyKey, bool enabled) -{ - PropertyMap::iterator it = m_Properties.find( propertyKey ); - if (it != m_Properties.end() && it->second.second != enabled) - { - it->second.second = enabled; - this->Modified(); - } -} - void mitk::PropertyList::ConcatenatePropertyList(PropertyList *pList, bool replace) { if (pList) { const PropertyMap* propertyMap = pList->GetMap(); for ( PropertyMap::const_iterator iter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here iter != propertyMap->end(); ++iter ) { const std::string key = iter->first; - BaseProperty* value = iter->second.first; + BaseProperty* value = iter->second; if (replace) { ReplaceProperty( key.c_str(), value ); } else { SetProperty( key.c_str(), value ); } } } } bool mitk::PropertyList::GetBoolProperty(const char* propertyKey, bool& boolValue) const { BoolProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { boolValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, boolValue); } bool mitk::PropertyList::GetIntProperty(const char* propertyKey, int &intValue) const { IntProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { intValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, intValue); } bool mitk::PropertyList::GetFloatProperty(const char* propertyKey, float &floatValue) const { FloatProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { floatValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, floatValue); } bool mitk::PropertyList::GetStringProperty(const char* propertyKey, std::string& stringValue) const { StringProperty* sp= dynamic_cast(GetProperty(propertyKey)); if ( sp != NULL ) { stringValue = sp->GetValue(); return true; } return false; } void mitk::PropertyList::SetIntProperty(const char* propertyKey, int intValue) { SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::PropertyList::SetBoolProperty( const char* propertyKey, bool boolValue) { SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::PropertyList::SetFloatProperty( const char* propertyKey, float floatValue) { SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::PropertyList::SetStringProperty( const char* propertyKey, const char* stringValue) { SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } diff --git a/Core/Code/DataManagement/mitkPropertyList.h b/Core/Code/DataManagement/mitkPropertyList.h index e2b9fbdeca..e8d4409c3c 100644 --- a/Core/Code/DataManagement/mitkPropertyList.h +++ b/Core/Code/DataManagement/mitkPropertyList.h @@ -1,215 +1,208 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D #define PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D #include "mitkCommon.h" #include "mitkBaseProperty.h" #include "mitkGenericProperty.h" #include "mitkUIDGenerator.h" #include #include #include namespace mitk { class XMLWriter; /** * @brief Key-value list holding instances of BaseProperty * * This list is meant to hold an arbitrary list of "properties", * which should describe the object associated with this list. * * Usually you will use PropertyList as part of a DataNode * object - in this context the properties describe the data object * held by the DataNode (e.g. whether the object is rendered at * all, which color is used for rendering, what name should be * displayed for the object, etc.) * * The values in the list are not fixed, you may introduce any kind * of property that seems useful - all you have to do is inherit * from BaseProperty. * * The list is organized as a key-value pairs, i.e. * * \li "name" : pointer to a StringProperty * \li "visible" : pointer to a BoolProperty * \li "color" : pointer to a ColorProperty * \li "volume" : pointer to a FloatProperty * * Please see the documentation of SetProperty and ReplaceProperty for two * quite different semantics. Normally SetProperty is what you want - this * method will try to change the value of an existing property and will * not allow you to replace e.g. a ColorProperty with an IntProperty. * * @ingroup DataManagement */ class MITK_CORE_EXPORT PropertyList : public itk::Object { public: mitkClassMacro(PropertyList, itk::Object); /** * Method for creation through the object factory. */ itkNewMacro(Self); /** * Map structure to hold the properties: the map key is a string, - * the value consists of the actual property object (BaseProperty) and - * a bool flag (indicating whether a property is "enabled"). - * - * The "enabled" flag is there to "keep a property without showing it", i.e. - * GetProperty will not tell that there such a thing. Is there any real world use for this? (bug #1052) + * the value consists of the actual property object (BaseProperty). */ - typedef std::map< std::string,std::pair > PropertyMap; - typedef std::pair< std::string,std::pair > PropertyMapElementType; + typedef std::map< std::string, BaseProperty::Pointer> PropertyMap; + typedef std::pair< std::string, BaseProperty::Pointer> PropertyMapElementType; /** * @brief Get a property by its name. */ mitk::BaseProperty* GetProperty(const std::string& propertyKey) const; /** * @brief Set a property in the list/map by value. * * The actual OBJECT holding the value of the property is not replaced, but its value * is modified to match that of @a property. To really replace the object holding the * property - which would make sense if you want to change the type (bool, string) of the property * - call ReplaceProperty. */ void SetProperty(const std::string& propertyKey, BaseProperty* property); /** * @brief Set a property object in the list/map by reference. * * The actual OBJECT holding the value of the property is replaced by this function. * This is useful if you want to change the type of the property, like from BoolProperty to StringProperty. * Another use is to share one and the same property object among several ProperyList/DataNode objects, which * makes them appear synchronized. */ void ReplaceProperty(const std::string& propertyKey, BaseProperty* property); /** * @brief Set a property object in the list/map by reference. */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); //##Documentation //## @brief Convenience access method for GenericProperty properties //## (T being the type of the second parameter) //## @return @a true property was found template bool GetPropertyValue(const char* propertyKey, T & value) const { GenericProperty* gp= dynamic_cast*>(GetProperty(propertyKey)); if ( gp != NULL ) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience method to access the value of a BoolProperty */ bool GetBoolProperty(const char* propertyKey, bool& boolValue) const; /** * @brief Convenience method to set the value of a BoolProperty */ void SetBoolProperty( const char* propertyKey, bool boolValue); /** * @brief Convenience method to access the value of an IntProperty */ bool GetIntProperty(const char* propertyKey, int &intValue) const; /** * @brief Convenience method to set the value of an IntProperty */ void SetIntProperty(const char* propertyKey, int intValue); /** * @brief Convenience method to access the value of a FloatProperty */ bool GetFloatProperty(const char* propertyKey, float &floatValue) const; /** * @brief Convenience method to set the value of a FloatProperty */ void SetFloatProperty( const char* propertyKey, float floatValue); /** * @brief Convenience method to access the value of a StringProperty */ bool GetStringProperty(const char* propertyKey, std::string& stringValue) const; /** * @brief Convenience method to set the value of a StringProperty */ void SetStringProperty( const char* propertyKey, const char* stringValue); /** * @brief Get the timestamp of the last change of the map or the last change of one of * the properties store in the list (whichever is later). */ virtual unsigned long GetMTime() const; /** * @brief Remove a property from the list/map. */ bool DeleteProperty(const std::string& propertyKey); const PropertyMap* GetMap() const { return &m_Properties; } bool IsEmpty() const { return m_Properties.empty(); } virtual Pointer Clone(); virtual void Clear(); - virtual bool IsEnabled(const std::string& propertyKey); - virtual void SetEnabled(const std::string& propertyKey,bool enabled); - protected: PropertyList(); virtual ~PropertyList(); /** * @brief Map of properties. */ PropertyMap m_Properties; }; } // namespace mitk #endif /* PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D */ diff --git a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp index 5bea4a7510..5486b9344d 100644 --- a/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp +++ b/Core/Code/Rendering/mitkSurfaceVtkMapper3D.cpp @@ -1,456 +1,456 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkSurfaceVtkMapper3D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkLookupTableProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkClippingProperty.h" #include "mitkShaderProperty.h" #include "mitkShaderRepository.h" #include #include #include #include #include #include #include const mitk::Surface* mitk::SurfaceVtkMapper3D::GetInput() { return static_cast ( GetData() ); } mitk::SurfaceVtkMapper3D::SurfaceVtkMapper3D() { // m_Prop3D = vtkActor::New(); m_GenerateNormals = false; } mitk::SurfaceVtkMapper3D::~SurfaceVtkMapper3D() { // m_Prop3D->Delete(); } void mitk::SurfaceVtkMapper3D::GenerateData(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool visible = IsVisible(renderer); if(visible==false) { ls->m_Actor->VisibilityOff(); return; } // // set the input-object at time t for the mapper // mitk::Surface::Pointer input = const_cast< mitk::Surface* >( this->GetInput() ); vtkPolyData * polydata = input->GetVtkPolyData( this->GetTimestep() ); if(polydata == NULL) { ls->m_Actor->VisibilityOff(); return; } if ( m_GenerateNormals ) { ls->m_VtkPolyDataNormals->SetInput( polydata ); ls->m_VtkPolyDataMapper->SetInput( ls->m_VtkPolyDataNormals->GetOutput() ); } else { ls->m_VtkPolyDataMapper->SetInput( polydata ); } // // apply properties read from the PropertyList // ApplyProperties(ls->m_Actor, renderer); if(visible) ls->m_Actor->VisibilityOn(); } void mitk::SurfaceVtkMapper3D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_Actor->VisibilityOff(); } void mitk::SurfaceVtkMapper3D::ApplyMitkPropertiesToVtkProperty(mitk::DataNode *node, vtkProperty* property, mitk::BaseRenderer* renderer) { // Colors { double ambient [3] = { 0.5,0.5,0.0 }; double diffuse [3] = { 0.5,0.5,0.0 }; double specular[3] = { 1.0,1.0,1.0 }; float coeff_ambient = 0.5f; float coeff_diffuse = 0.5f; float coeff_specular= 0.5f; float power_specular=10.0f; // Color { mitk::ColorProperty::Pointer p; node->GetProperty(p, "color", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); // Setting specular color to the same, make physically no real sense, however vtk rendering slows down, if these colors are different. specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.ambientColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); ambient[0]=c.GetRed(); ambient[1]=c.GetGreen(); ambient[2]=c.GetBlue(); } } // Diffuse { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.diffuseColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); diffuse[0]=c.GetRed(); diffuse[1]=c.GetGreen(); diffuse[2]=c.GetBlue(); } } // Specular { mitk::ColorProperty::Pointer p; node->GetProperty(p, "material.specularColor", renderer); if(p.IsNotNull()) { mitk::Color c = p->GetColor(); specular[0]=c.GetRed(); specular[1]=c.GetGreen(); specular[2]=c.GetBlue(); } } // Ambient coeff { node->GetFloatProperty("material.ambientCoefficient", coeff_ambient, renderer); } // Diffuse coeff { node->GetFloatProperty("material.diffuseCoefficient", coeff_diffuse, renderer); } // Specular coeff { node->GetFloatProperty("material.specularCoefficient", coeff_specular, renderer); } // Specular power { node->GetFloatProperty("material.specularPower", power_specular, renderer); } property->SetAmbient( coeff_ambient ); property->SetDiffuse( coeff_diffuse ); property->SetSpecular( coeff_specular ); property->SetSpecularPower( power_specular ); property->SetAmbientColor( ambient ); property->SetDiffuseColor( diffuse ); property->SetSpecularColor( specular ); } // Render mode { // Opacity { float opacity = 1.0f; if( node->GetOpacity(opacity,renderer) ) property->SetOpacity( opacity ); } // Wireframe line width { float lineWidth = 1; node->GetFloatProperty("material.wireframeLineWidth", lineWidth, renderer); property->SetLineWidth( lineWidth ); } // Representation { mitk::VtkRepresentationProperty::Pointer p; node->GetProperty(p, "material.representation", renderer); if(p.IsNotNull()) property->SetRepresentation( p->GetVtkRepresentation() ); } // Interpolation { mitk::VtkInterpolationProperty::Pointer p; node->GetProperty(p, "material.interpolation", renderer); if(p.IsNotNull()) property->SetInterpolation( p->GetVtkInterpolation() ); } } } void mitk::SurfaceVtkMapper3D::ApplyProperties(vtkActor* /*actor*/, mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // Applying shading properties { Superclass::ApplyProperties( ls->m_Actor, renderer ) ; // VTK Properties ApplyMitkPropertiesToVtkProperty( this->GetDataNode(), ls->m_Actor->GetProperty(), renderer ); // Shaders mitk::ShaderRepository::GetGlobalShaderRepository()->ApplyProperties(this->GetDataNode(),ls->m_Actor,renderer,ls->m_ShaderTimestampUpdate); } mitk::LookupTableProperty::Pointer lookupTableProp; this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer); if (lookupTableProp.IsNotNull() ) { ls->m_VtkPolyDataMapper->SetLookupTable(lookupTableProp->GetLookupTable()->GetVtkLookupTable()); } mitk::LevelWindow levelWindow; if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer, "levelWindow")) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } else if(this->GetDataNode()->GetLevelWindow(levelWindow, renderer)) { ls->m_VtkPolyDataMapper->SetScalarRange(levelWindow.GetLowerWindowBound(),levelWindow.GetUpperWindowBound()); } bool scalarVisibility = false; this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility); ls->m_VtkPolyDataMapper->SetScalarVisibility( (scalarVisibility ? 1 : 0) ); if(scalarVisibility) { mitk::VtkScalarModeProperty* scalarMode; if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(scalarMode->GetVtkScalarMode()); } else ls->m_VtkPolyDataMapper->SetScalarModeToDefault(); bool colorMode = false; this->GetDataNode()->GetBoolProperty("color mode", colorMode); ls->m_VtkPolyDataMapper->SetColorMode( (colorMode ? 1 : 0) ); float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 1.0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); } // deprecated settings bool deprecatedUseCellData = false; this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", deprecatedUseCellData); bool deprecatedUsePointData = false; this->GetDataNode()->GetBoolProperty("deprecated usePointDataForColouring", deprecatedUsePointData); if (deprecatedUseCellData) { ls->m_VtkPolyDataMapper->SetColorModeToDefault(); ls->m_VtkPolyDataMapper->SetScalarRange(0,255); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_VtkPolyDataMapper->SetScalarModeToUseCellData(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } else if (deprecatedUsePointData) { float scalarsMin = 0; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum")) != NULL) scalarsMin = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMinimum"))->GetValue(); float scalarsMax = 0.1; if (dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum")) != NULL) scalarsMax = dynamic_cast(this->GetDataNode()->GetProperty("ScalarsRangeMaximum"))->GetValue(); ls->m_VtkPolyDataMapper->SetScalarRange(scalarsMin,scalarsMax); ls->m_VtkPolyDataMapper->SetColorModeToMapScalars(); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); ls->m_Actor->GetProperty()->SetInterpolationToPhong(); } int deprecatedScalarMode = VTK_COLOR_MODE_DEFAULT; if(this->GetDataNode()->GetIntProperty("deprecated scalar mode", deprecatedScalarMode, renderer)) { ls->m_VtkPolyDataMapper->SetScalarMode(deprecatedScalarMode); ls->m_VtkPolyDataMapper->ScalarVisibilityOn(); ls->m_Actor->GetProperty()->SetSpecular (1); ls->m_Actor->GetProperty()->SetSpecularPower (50); //m_Actor->GetProperty()->SetInterpolationToPhong(); } // Check whether one or more ClippingProperty objects have been defined for // this node. Check both renderer specific and global property lists, since // properties in both should be considered. const PropertyList::PropertyMap *rendererProperties = this->GetDataNode()->GetPropertyList( renderer )->GetMap(); const PropertyList::PropertyMap *globalProperties = this->GetDataNode()->GetPropertyList( NULL )->GetMap(); // Add clipping planes (if any) ls->m_ClippingPlaneCollection->RemoveAllItems(); PropertyList::PropertyMap::const_iterator it; for ( it = rendererProperties->begin(); it != rendererProperties->end(); ++it ) { - this->CheckForClippingProperty( renderer,(*it).second.first.GetPointer() ); + this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } for ( it = globalProperties->begin(); it != globalProperties->end(); ++it ) { - this->CheckForClippingProperty( renderer,(*it).second.first.GetPointer() ); + this->CheckForClippingProperty( renderer,(*it).second.GetPointer() ); } if ( ls->m_ClippingPlaneCollection->GetNumberOfItems() > 0 ) { ls->m_VtkPolyDataMapper->SetClippingPlanes( ls->m_ClippingPlaneCollection ); } else { ls->m_VtkPolyDataMapper->RemoveAllClippingPlanes(); } } vtkProp *mitk::SurfaceVtkMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_Actor; } void mitk::SurfaceVtkMapper3D::CheckForClippingProperty( mitk::BaseRenderer* renderer, mitk::BaseProperty *property ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); // m_Prop3D = ls->m_Actor; ClippingProperty *clippingProperty = dynamic_cast< ClippingProperty * >( property ); if ( (clippingProperty != NULL) && (clippingProperty->GetClippingEnabled()) ) { const Point3D &origin = clippingProperty->GetOrigin(); const Vector3D &normal = clippingProperty->GetNormal(); vtkPlane *clippingPlane = vtkPlane::New(); clippingPlane->SetOrigin( origin[0], origin[1], origin[2] ); clippingPlane->SetNormal( normal[0], normal[1], normal[2] ); ls->m_ClippingPlaneCollection->AddItem( clippingPlane ); clippingPlane->UnRegister( NULL ); } } void mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { // Shading { node->AddProperty( "material.wireframeLineWidth", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.ambientCoefficient" , mitk::FloatProperty::New(0.05f) , renderer, overwrite ); node->AddProperty( "material.diffuseCoefficient" , mitk::FloatProperty::New(0.9f) , renderer, overwrite ); node->AddProperty( "material.specularCoefficient", mitk::FloatProperty::New(1.0f) , renderer, overwrite ); node->AddProperty( "material.specularPower" , mitk::FloatProperty::New(16.0f) , renderer, overwrite ); //node->AddProperty( "material.ambientColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.diffuseColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); //node->AddProperty( "material.specularColor" , mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "material.representation" , mitk::VtkRepresentationProperty::New() , renderer, overwrite ); node->AddProperty( "material.interpolation" , mitk::VtkInterpolationProperty::New() , renderer, overwrite ); } // Shaders { mitk::ShaderRepository::GetGlobalShaderRepository()->AddDefaultProperties(node,renderer,overwrite); } } void mitk::SurfaceVtkMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", mitk::ColorProperty::New(1.0f,1.0f,1.0f), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New(1.0), renderer, overwrite ); mitk::SurfaceVtkMapper3D::SetDefaultPropertiesForVtkProperty(node,renderer,overwrite); // Shading node->AddProperty( "scalar visibility", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "scalar mode", mitk::VtkScalarModeProperty::New(), renderer, overwrite ); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { if((surface->GetVtkPolyData() != 0) && (surface->GetVtkPolyData()->GetPointData() != NULL) && (surface->GetVtkPolyData()->GetPointData()->GetScalars() != 0)) { node->AddProperty( "scalar visibility", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "color mode", mitk::BoolProperty::New(true), renderer, overwrite ); } } Superclass::SetDefaultProperties(node, renderer, overwrite); } void mitk::SurfaceVtkMapper3D::SetImmediateModeRenderingOn(int /*on*/) { /* if (m_VtkPolyDataMapper != NULL) m_VtkPolyDataMapper->SetImmediateModeRendering(on); */ } diff --git a/CoreUI/Qmitk/QmitkPropertiesTableModel.cpp b/CoreUI/Qmitk/QmitkPropertiesTableModel.cpp index a33c149dcf..0dd3a84a0a 100644 --- a/CoreUI/Qmitk/QmitkPropertiesTableModel.cpp +++ b/CoreUI/Qmitk/QmitkPropertiesTableModel.cpp @@ -1,582 +1,544 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkPropertiesTableModel.h" //# Own includes #include "mitkStringProperty.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkEnumerationProperty.h" #include "mitkRenderingManager.h" #include "QmitkCustomVariants.h" //# Toolkit includes #include #include #include #include //# PUBLIC CTORS,DTOR QmitkPropertiesTableModel::QmitkPropertiesTableModel(QObject* parent, mitk::PropertyList::Pointer _PropertyList) : QAbstractTableModel(parent) , m_PropertyList(0) , m_BlockEvents(false) , m_SortDescending(false) , m_FilterKeyWord("") { this->SetPropertyList(_PropertyList); } QmitkPropertiesTableModel::~QmitkPropertiesTableModel() { // remove all event listeners by setting the property list to 0 this->SetPropertyList(0); } //# PUBLIC GETTER mitk::PropertyList::Pointer QmitkPropertiesTableModel::GetPropertyList() const { return m_PropertyList.GetPointer(); } Qt::ItemFlags QmitkPropertiesTableModel::flags(const QModelIndex& index) const { // no editing so far, return default (enabled, selectable) Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.column() == PROPERTY_VALUE_COLUMN) { // there are also read only property items -> do not allow editing them if(index.data(Qt::EditRole).isValid()) flags |= Qt::ItemIsEditable; if(index.data(Qt::CheckStateRole).isValid()) flags |= Qt::ItemIsUserCheckable; } - if (index.column() == PROPERTY_ACTIVE_COLUMN) - { - flags |= Qt::ItemIsUserCheckable; - } - return flags; } QVariant QmitkPropertiesTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { switch (section) { case PROPERTY_NAME_COLUMN: return tr("Name"); case PROPERTY_VALUE_COLUMN: return tr("Value"); - case PROPERTY_ACTIVE_COLUMN: - return tr("Active"); - default: return QVariant(); } } return QVariant(); } QVariant QmitkPropertiesTableModel::data(const QModelIndex& index, int role) const { // empty data by default QVariant data; if(!index.isValid() || m_SelectedProperties.empty() || index.row() > (int)(m_SelectedProperties.size()-1)) return data; // the properties name if(index.column() == PROPERTY_NAME_COLUMN) { if(role == Qt::DisplayRole) data = QString::fromStdString(m_SelectedProperties[index.row()].first); } // the real properties value else if(index.column() == PROPERTY_VALUE_COLUMN) { - mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second.first; + mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second; if (const mitk::ColorProperty* colorProp = dynamic_cast(baseProp)) { mitk::Color col = colorProp->GetColor(); QColor qcol((int)(col.GetRed() * 255), (int)(col.GetGreen() * 255),(int)( col.GetBlue() * 255)); if(role == Qt::DisplayRole) data.setValue(qcol); else if(role == Qt::EditRole) data.setValue(qcol); } else if(mitk::BoolProperty* boolProp = dynamic_cast(baseProp)) { if(role == Qt::CheckStateRole) data = boolProp->GetValue() ? Qt::Checked : Qt::Unchecked; } else if (mitk::StringProperty* stringProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(QString::fromStdString(stringProp->GetValue())); else if(role == Qt::EditRole) data.setValue(QString::fromStdString(stringProp->GetValue())); } else if (mitk::IntProperty* intProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(intProp->GetValue()); else if(role == Qt::EditRole) data.setValue(intProp->GetValue()); } else if (mitk::FloatProperty* floatProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(floatProp->GetValue()); else if(role == Qt::EditRole) data.setValue(floatProp->GetValue()); } else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(QString::fromStdString(baseProp->GetValueAsString())); else if(role == Qt::EditRole) { QStringList values; for(mitk::EnumerationProperty::EnumConstIterator it=enumerationProp->Begin(); it!=enumerationProp->End() ; it++) { values << QString::fromStdString(it->second); } data.setValue(values); } } else { if(role == Qt::DisplayRole) - data.setValue(QString::fromStdString(m_SelectedProperties[index.row()].second.first->GetValueAsString())); + data.setValue(QString::fromStdString(m_SelectedProperties[index.row()].second->GetValueAsString())); } } - // enabled/disabled value - else if(index.column() == PROPERTY_ACTIVE_COLUMN) - { - if (role == Qt::CheckStateRole) - data = (m_SelectedProperties[index.row()].second.second) ? Qt::Checked : Qt::Unchecked; - } - return data; } int QmitkPropertiesTableModel::rowCount(const QModelIndex& /*parent*/) const { // return the number of properties in the properties list. return m_SelectedProperties.size(); } int QmitkPropertiesTableModel::columnCount(const QModelIndex & /*parent*/)const { - return 3; + return 2; } //# PUBLIC SETTER void QmitkPropertiesTableModel::SetPropertyList( mitk::PropertyList* _PropertyList ) { // if propertylist really changed if(m_PropertyList.GetPointer() != _PropertyList) { // Remove delete listener if there was a propertylist before if(m_PropertyList.IsNotNull()) { m_PropertyList.ObjectDelete.RemoveListener (mitk::MessageDelegate1( this, &QmitkPropertiesTableModel::PropertyListDelete )); } // set new list m_PropertyList = _PropertyList; if(m_PropertyList.IsNotNull()) { m_PropertyList.ObjectDelete.AddListener (mitk::MessageDelegate1( this, &QmitkPropertiesTableModel::PropertyListDelete )); } this->Reset(); } } void QmitkPropertiesTableModel::PropertyListDelete( const itk::Object * /*_PropertyList*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; this->Reset(); m_BlockEvents = false; } } void QmitkPropertiesTableModel::PropertyModified( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; int row = this->FindProperty(dynamic_cast(caller)); QModelIndex indexOfChangedProperty = index(row, 1); emit dataChanged(indexOfChangedProperty, indexOfChangedProperty); m_BlockEvents = false; } } void QmitkPropertiesTableModel::PropertyDelete( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; int row = this->FindProperty(dynamic_cast(caller)); if(row >= 0) this->Reset(); m_BlockEvents = false; } } bool QmitkPropertiesTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && !m_SelectedProperties.empty() && index.row() < (int)(m_SelectedProperties.size()) && (role == Qt::EditRole || Qt::CheckStateRole)) { // block all events now! m_BlockEvents = true; // the properties name if(index.column() == PROPERTY_VALUE_COLUMN) { - mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second.first; + mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second; if (mitk::ColorProperty* colorProp = dynamic_cast(baseProp)) { QColor qcolor = value.value(); if(!qcolor.isValid()) return false; mitk::Color col = colorProp->GetColor(); col.SetRed(qcolor.red() / 255.0); col.SetGreen(qcolor.green() / 255.0); col.SetBlue(qcolor.blue() / 255.0); colorProp->SetColor(col); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(mitk::BoolProperty* boolProp = dynamic_cast(baseProp)) { boolProp->SetValue(value.toInt() == Qt::Checked ? true : false); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if (mitk::StringProperty* stringProp = dynamic_cast(baseProp)) { stringProp->SetValue((value.value()).toStdString()); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if (mitk::IntProperty* intProp = dynamic_cast(baseProp)) { int intValue = value.value(); if (intValue != intProp->GetValue()) { intProp->SetValue(intValue); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else if (mitk::FloatProperty* floatProp = dynamic_cast(baseProp)) { float floatValue = value.value(); if (floatValue != floatProp->GetValue()) { floatProp->SetValue(floatValue); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast(baseProp)) { std::string activatedItem = value.value().toStdString(); if ( activatedItem != enumerationProp->GetValueAsString() ) { if ( enumerationProp->IsValidEnumerationValue( activatedItem ) ) { enumerationProp->SetValue( activatedItem ); m_PropertyList->InvokeEvent( itk::ModifiedEvent() ); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } } - // enabled/disabled value - else if(index.column() == PROPERTY_ACTIVE_COLUMN) - { - bool active = value.toInt() == Qt::Checked; - std::string propertyName = m_SelectedProperties[index.row()].first; - - m_PropertyList->SetEnabled(propertyName, active); - m_SelectedProperties[index.row()].second.second = active; - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - // property was changed by us, now we can accept property changes triggered by someone else m_BlockEvents = false; emit dataChanged(index, index); return true; } return false; } void QmitkPropertiesTableModel::sort( int column, Qt::SortOrder order /*= Qt::AscendingOrder */ ) { bool sortDescending = (order == Qt::DescendingOrder) ? true: false; // do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!) if(sortDescending != m_SortDescending) { m_SortDescending = sortDescending; PropertyDataSetCompareFunction::CompareCriteria _CompareCriteria = PropertyDataSetCompareFunction::CompareByName; PropertyDataSetCompareFunction::CompareOperator _CompareOperator = m_SortDescending ? PropertyDataSetCompareFunction::Greater: PropertyDataSetCompareFunction::Less; if(column == PROPERTY_VALUE_COLUMN) _CompareCriteria = PropertyDataSetCompareFunction::CompareByValue; - else if(column == PROPERTY_ACTIVE_COLUMN) - _CompareCriteria = PropertyDataSetCompareFunction::CompareByActivity; - - PropertyDataSetCompareFunction compareFunc(_CompareCriteria, _CompareOperator); std::sort(m_SelectedProperties.begin(), m_SelectedProperties.end(), compareFunc); QAbstractTableModel::reset(); } } //# PROTECTED GETTER int QmitkPropertiesTableModel::FindProperty( const mitk::BaseProperty* _Property ) const { int row = -1; if(_Property) { // search for property that changed and emit datachanged on the corresponding ModelIndex std::vector::const_iterator propertyIterator; for( propertyIterator=m_SelectedProperties.begin(); propertyIterator!=m_SelectedProperties.end() ; propertyIterator++) { - if(propertyIterator->second.first == _Property) + if(propertyIterator->second == _Property) break; } if(propertyIterator != m_SelectedProperties.end()) row = std::distance(m_SelectedProperties.begin(), propertyIterator); } return row; } //# PROTECTED SETTER void QmitkPropertiesTableModel::AddSelectedProperty( PropertyDataSet& _PropertyDataSet ) { // subscribe for modified event itk::MemberCommand::Pointer _PropertyDataSetModifiedCommand = itk::MemberCommand::New(); _PropertyDataSetModifiedCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyModified); - m_PropertyModifiedObserverTags.push_back(_PropertyDataSet.second.first->AddObserver(itk::ModifiedEvent(), _PropertyDataSetModifiedCommand)); + m_PropertyModifiedObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::ModifiedEvent(), _PropertyDataSetModifiedCommand)); // subscribe for delete event itk::MemberCommand::Pointer _PropertyDataSetDeleteCommand = itk::MemberCommand::New(); _PropertyDataSetDeleteCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyDelete); - m_PropertyDeleteObserverTags.push_back(_PropertyDataSet.second.first->AddObserver(itk::DeleteEvent(), _PropertyDataSetDeleteCommand)); + m_PropertyDeleteObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::DeleteEvent(), _PropertyDataSetDeleteCommand)); // add to the selection m_SelectedProperties.push_back(_PropertyDataSet); } void QmitkPropertiesTableModel::RemoveSelectedProperty( unsigned int _Index ) { PropertyDataSet& _PropertyDataSet = m_SelectedProperties.at(_Index); // remove modified event listener - _PropertyDataSet.second.first->RemoveObserver(m_PropertyModifiedObserverTags[_Index]); + _PropertyDataSet.second->RemoveObserver(m_PropertyModifiedObserverTags[_Index]); m_PropertyModifiedObserverTags.erase(m_PropertyModifiedObserverTags.begin()+_Index); // remove delete event listener - _PropertyDataSet.second.first->RemoveObserver(m_PropertyDeleteObserverTags[_Index]); + _PropertyDataSet.second->RemoveObserver(m_PropertyDeleteObserverTags[_Index]); m_PropertyDeleteObserverTags.erase(m_PropertyDeleteObserverTags.begin()+_Index); // remove from selection m_SelectedProperties.erase(m_SelectedProperties.begin()+_Index); } void QmitkPropertiesTableModel::Reset() { // remove all selected properties while(!m_SelectedProperties.empty()) { this->RemoveSelectedProperty(m_SelectedProperties.size()-1); } std::vector allPredicates; if(m_PropertyList.IsNotNull()) { // first of all: collect all properties from the list for(mitk::PropertyList::PropertyMap::const_iterator it=m_PropertyList->GetMap()->begin() ; it!=m_PropertyList->GetMap()->end() ; it++) { - allPredicates.push_back(*it); + allPredicates.push_back(*it); //% TODO } } // make a subselection if a keyword is specified if(!m_FilterKeyWord.empty()) { std::vector subSelection; for(std::vector::iterator it=allPredicates.begin() ; it!=allPredicates.end() ; it++) { // add this to the selection if it is matched by the keyword if((*it).first.find(m_FilterKeyWord) != std::string::npos) subSelection.push_back((*it)); } allPredicates.clear(); allPredicates = subSelection; } PropertyDataSet tmpPropertyDataSet; // add all selected now to the Model for(std::vector::iterator it=allPredicates.begin() ; it!=allPredicates.end() ; it++) { tmpPropertyDataSet = *it; this->AddSelectedProperty(tmpPropertyDataSet); } // sort the list as indicated by m_SortDescending this->sort(m_SortDescending); // model was resetted QAbstractTableModel::reset(); } void QmitkPropertiesTableModel::SetFilterPropertiesKeyWord( std::string _FilterKeyWord ) { m_FilterKeyWord = _FilterKeyWord; this->Reset(); } QmitkPropertiesTableModel::PropertyDataSetCompareFunction::PropertyDataSetCompareFunction( CompareCriteria _CompareCriteria , CompareOperator _CompareOperator ) : m_CompareCriteria(_CompareCriteria) , m_CompareOperator(_CompareOperator) { } bool QmitkPropertiesTableModel::PropertyDataSetCompareFunction::operator() ( const PropertyDataSet& _Left , const PropertyDataSet& _Right ) const { switch(m_CompareCriteria) { case CompareByValue: if(m_CompareOperator == Less) - return (_Left.second.first->GetValueAsString() < _Right.second.first->GetValueAsString()); - else - return (_Left.second.first->GetValueAsString() > _Right.second.first->GetValueAsString()); - break; - - case CompareByActivity: - if(m_CompareOperator == Less) - return (_Left.second.second < _Right.second.second); + return (_Left.second->GetValueAsString() < _Right.second->GetValueAsString()); else - return (_Left.second.second > _Right.second.second); + return (_Left.second->GetValueAsString() > _Right.second->GetValueAsString()); break; // CompareByName: default: if(m_CompareOperator == Less) return (_Left.first < _Right.first); else return (_Left.first > _Right.first); break; } } QmitkPropertiesTableModel::PropertyListElementFilterFunction::PropertyListElementFilterFunction( const std::string& _FilterKeyWord ) : m_FilterKeyWord(_FilterKeyWord) { } bool QmitkPropertiesTableModel::PropertyListElementFilterFunction::operator()( const PropertyDataSet& _Elem ) const { if(m_FilterKeyWord.empty()) return true; return (_Elem.first.find(m_FilterKeyWord) == 0); } diff --git a/CoreUI/Qmitk/QmitkPropertiesTableModel.h b/CoreUI/Qmitk/QmitkPropertiesTableModel.h index f8d5e67ecc..8a21c120b8 100644 --- a/CoreUI/Qmitk/QmitkPropertiesTableModel.h +++ b/CoreUI/Qmitk/QmitkPropertiesTableModel.h @@ -1,253 +1,251 @@ /*========================================================================= Program: MITK Language: C++ Date: $Date$ Version: $Revision: 14921 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /// Header guard. #ifndef QmitkPropertiesTableModel_h #define QmitkPropertiesTableModel_h //# Own includes #include "mitkDataNode.h" #include "mitkWeakPointer.h" //# Toolkit includes #include #include #include //# Forward declarations /// /// \class QmitkPropertiesTableModel /// \brief A table model for showing and editing mitk::Properties. /// /// \see QmitkPropertyDelegate /// class QMITK_EXPORT QmitkPropertiesTableModel : public QAbstractTableModel { //# PUBLIC CTORS,DTOR,TYPEDEFS,CONSTANTS public: static const int PROPERTY_NAME_COLUMN = 0; static const int PROPERTY_VALUE_COLUMN = 1; - static const int PROPERTY_ACTIVE_COLUMN = 2; /// /// Typedef for the complete Property Datastructure, which may be written as follows: - /// Name->(mitk::BaseProperty::Pointer->ActiveFlag) + /// Name->(mitk::BaseProperty::Pointer) /// - typedef std::pair > PropertyDataSet; + typedef std::pair PropertyDataSet; /// /// Constructs a new QmitkDataStorageTableModel /// and sets the DataNode for this TableModel. QmitkPropertiesTableModel(QObject* parent = 0, mitk::PropertyList::Pointer _PropertyList=0); /// /// Standard dtor. Nothing to do here. virtual ~QmitkPropertiesTableModel(); //# PUBLIC GETTER public: /// /// Returns the property list of this table model. /// mitk::PropertyList::Pointer GetPropertyList() const; /// /// Overwritten from QAbstractTableModel. Returns the flags what can be done with the items (view, edit, ...) Qt::ItemFlags flags(const QModelIndex& index) const; /// /// Overwritten from QAbstractTableModel. Returns the flags what can be done with the items (view, edit, ...) QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; /// /// Overwritten from QAbstractTableModel. Returns the flags what can be done with the items (view, edit, ...) QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; /// /// Overwritten from QAbstractTableModel. Returns the flags what can be done with the items (view, edit, ...) int rowCount(const QModelIndex& parent = QModelIndex()) const; /// /// Overwritten from QAbstractTableModel. Returns the number of columns. That is usually two in this model: /// the properties name and its value. int columnCount(const QModelIndex &parent) const; //# PUBLIC SETTER public: /// /// Sets the Property List to show. Resets the whole model. If _PropertyList is NULL the model is empty. /// void SetPropertyList(mitk::PropertyList* _PropertyList); /// /// \brief Gets called when the list is about to be deleted. /// virtual void PropertyListDelete(const itk::Object *_PropertyList); /// /// \brief Called when a single property was changed. Send a model changed event to the Qt-outer world. /// virtual void PropertyModified(const itk::Object *caller, const itk::EventObject &event); /// /// \brief Called when a single property was changed. Send a model changed event to the Qt-outer world. /// virtual void PropertyDelete(const itk::Object *caller, const itk::EventObject &event); /// /// \brief Set a keyword for filtering of properties. Only properties beginning with this string will be shown /// virtual void SetFilterPropertiesKeyWord(std::string _FilterKeyWord); /// /// Overridden from QAbstractTableModel. Sets data at index for given role. /// bool setData(const QModelIndex &index, const QVariant &value, int role); /// /// \brief Reimplemented sort function from QAbstractTableModel to enable sorting on the table. /// void sort ( int column, Qt::SortOrder order = Qt::AscendingOrder ); //#PROTECTED INNER CLASSES protected: /// /// \struct PropertyDataSetCompareFunction /// \brief A struct that inherits from std::binary_function. You can use it in std::sort algorithm for sorting the property list elements. /// struct PropertyDataSetCompareFunction : public std::binary_function { /// /// \brief Specifies field of the property with which it will be sorted. /// enum CompareCriteria { CompareByName = 0, - CompareByValue, - CompareByActivity + CompareByValue }; /// /// \brief Specifies Ascending/descending ordering. /// enum CompareOperator { Less = 0, Greater }; /// /// \brief Creates a PropertyDataSetCompareFunction. A CompareCriteria and a CompareOperator must be given. /// PropertyDataSetCompareFunction(CompareCriteria _CompareCriteria = CompareByName, CompareOperator _CompareOperator = Less); /// /// \brief The reimplemented compare function. /// bool operator()(const PropertyDataSet& _Left , const PropertyDataSet& _Right) const; protected: CompareCriteria m_CompareCriteria; CompareOperator m_CompareOperator; }; /// /// An unary function for selecting Properties in a vector by a key word. /// struct PropertyListElementFilterFunction : public std::unary_function { PropertyListElementFilterFunction(const std::string& m_FilterKeyWord); /// /// \brief The reimplemented compare function. /// bool operator()(const PropertyDataSet& _Elem) const; protected: std::string m_FilterKeyWord; }; //# PROTECTED GETTER protected: /// /// \brief Searches for the specified property and returns the row of the element in this QTableModel. /// If any errors occur, the function returns -1. /// int FindProperty(const mitk::BaseProperty* _Property) const; //# PROTECTED SETTER protected: /// /// Adds a property dataset to the current selection. /// When a property is added a modified and delete listener /// is appended. /// void AddSelectedProperty(PropertyDataSet& _PropertyDataSet); /// /// Removes a property dataset from the current selection. /// When a property is removed the modified and delete listener /// are also removed. /// void RemoveSelectedProperty(unsigned int _Index); /// /// Reset is called when a new filter keyword is set or a new /// PropertyList is set. First of all, all priorly selected /// properties are removed. Then all properties to be /// selected (specified by the keyword) are added to the selection. /// void Reset(); //# PROTECTED MEMBERS protected: /// /// Holds the pointer to the properties list. Dont use smart pointers here. Instead: Listen /// to the delete event. mitk::WeakPointer m_PropertyList; /// /// Store the properties in a vector so that they may be sorted std::vector m_SelectedProperties; /// /// \brief Holds all tags of Modified Event Listeners. We need it to remove them again. /// std::vector m_PropertyModifiedObserverTags; /// /// \brief Holds all tags of Modified Event Listeners. We need it to remove them again. /// std::vector m_PropertyDeleteObserverTags; /// /// \brief Indicates if this class should neglect all incoming events because /// the class itself triggered the event (e.g. when a property was edited). /// bool m_BlockEvents; /// /// \brief The property is true when the property list is sorted in descending order. /// bool m_SortDescending; /// /// \brief If set to any value, only properties containing the specified keyword in their name will be shown. /// std::string m_FilterKeyWord; }; #endif /* QMITKPROPERTIESTABLEMODEL_H_ */ diff --git a/Modules/Bundles/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp b/Modules/Bundles/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp index 9316799343..cd50e2db87 100644 --- a/Modules/Bundles/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp @@ -1,139 +1,139 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-10-07 16:14:59 +0200 (Mi, 07 Okt 2009) $ Version: $Revision: 19343 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkExtFileSaveProjectAction.h" #include #include #include "mitkSceneIO.h" #include "mitkProgressBar.h" #include #include #include #include #include #include #include #include "QmitkStdMultiWidgetEditor.h" QmitkExtFileSaveProjectAction::QmitkExtFileSaveProjectAction(berry::IWorkbenchWindow::Pointer window) : QAction(0) { m_Window = window; this->setParent(static_cast(m_Window->GetShell()->GetControl())); this->setText("&Save Project..."); this->setToolTip("Save content of Data Manager as a .mitk project file"); m_Window = window; this->connect(this, SIGNAL(triggered(bool)), this, SLOT(Run())); } void QmitkExtFileSaveProjectAction::Run() { try { QString fileName = QFileDialog::getSaveFileName(NULL, "Save MITK scene", QString::null, "MITK scene files (*.mitk)", NULL ); if (fileName.isEmpty() ) return; if ( fileName.right(5) != ".mitk" ) fileName += ".mitk"; mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); mitk::DataStorageEditorInput::Pointer editorInput; mitk::DataStorage::Pointer storage; QmitkStdMultiWidgetEditor::Pointer multiWidgetEditor; berry::IEditorPart::Pointer editor = m_Window->GetActivePage()->GetActiveEditor(); if (editor.Cast().IsNull()) { editorInput = new mitk::DataStorageEditorInput(); storage = editorInput->GetDataStorageReference()->GetDataStorage(); } else { multiWidgetEditor = editor.Cast(); storage = multiWidgetEditor->GetEditorInput().Cast()->GetDataStorageReference()->GetDataStorage(); } mitk::ProgressBar::GetInstance()->AddStepsToDo(2); /* Build list of nodes that should be saved */ mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); mitk::DataStorage::SetOfObjects::ConstPointer nodesToBeSaved = storage->GetSubset(isNotHelperObject); if ( !sceneIO->SaveScene( nodesToBeSaved, storage, fileName.toLocal8Bit().constData() ) ) { QMessageBox::information(NULL, "Scene saving", "Scene could not be written completely. Please check the log.", QMessageBox::Ok); } mitk::ProgressBar::GetInstance()->Progress(2); mitk::SceneIO::FailedBaseDataListType::ConstPointer failedNodes = sceneIO->GetFailedNodes(); if (!failedNodes->empty()) { std::stringstream ss; ss << "The following nodes could not be serialized:" << std::endl; for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { ss << " - "; if ( mitk::BaseData* data =(*iter)->GetData() ) { ss << data->GetNameOfClass(); } else { ss << "(NULL)"; } ss << " contained in node '" << (*iter)->GetName() << "'" << std::endl; } MITK_WARN << ss.str(); } mitk::PropertyList::ConstPointer failedProperties = sceneIO->GetFailedProperties(); if (!failedProperties->GetMap()->empty()) { std::stringstream ss; ss << "The following properties could not be serialized:" << std::endl; const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { - ss << " - " << iter->second.first->GetNameOfClass() << " associated to key '" << iter->first << "'" << std::endl; + ss << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'" << std::endl; } MITK_WARN << ss.str(); } } catch (std::exception& e) { MITK_ERROR << "Exception caught during scene saving: " << e.what(); } } diff --git a/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/QmitkMITKSurfaceMaterialEditorView.cpp b/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/QmitkMITKSurfaceMaterialEditorView.cpp index 88c69e4d5c..46162ce248 100644 --- a/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/QmitkMITKSurfaceMaterialEditorView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.materialeditor/src/internal/QmitkMITKSurfaceMaterialEditorView.cpp @@ -1,320 +1,320 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-03-21 19:27:37 +0100 (Sa, 21 Mrz 2009) $ Version: $Revision: 16719 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkMITKSurfaceMaterialEditorView.h" #include "mitkBaseRenderer.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkIDataStorageService.h" #include "mitkDataNodeObject.h" #include "berryIEditorPart.h" #include "berryIWorkbenchPage.h" #include "mitkShaderProperty.h" #include "mitkShaderRepository.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkStandaloneDataStorage.h" const std::string QmitkMITKSurfaceMaterialEditorView::VIEW_ID = "org.mitk.views.mitksurfacematerialeditor"; QmitkMITKSurfaceMaterialEditorView::QmitkMITKSurfaceMaterialEditorView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { fixedProperties.push_back( "shader" ); fixedProperties.push_back( "material.representation" ); fixedProperties.push_back( "color" ); fixedProperties.push_back( "opacity" ); fixedProperties.push_back( "material.wireframeLineWidth" ); fixedProperties.push_back( "material.ambientCoefficient" ); fixedProperties.push_back( "material.diffuseCoefficient" ); fixedProperties.push_back( "material.ambientColor" ); fixedProperties.push_back( "material.diffuseColor" ); fixedProperties.push_back( "material.specularColor" ); fixedProperties.push_back( "material.specularCoefficient" ); fixedProperties.push_back( "material.specularPower" ); fixedProperties.push_back( "material.interpolation" ); shaderProperties.push_back( "shader" ); shaderProperties.push_back( "material.representation" ); shaderProperties.push_back( "color" ); shaderProperties.push_back( "opacity" ); shaderProperties.push_back( "material.wireframeLineWidth" ); observerAllocated = false; mitk::ShaderRepository::GetGlobalShaderRepository(); } QmitkMITKSurfaceMaterialEditorView::~QmitkMITKSurfaceMaterialEditorView() { } void QmitkMITKSurfaceMaterialEditorView::InitPreviewWindow() { usedTimer=0; vtkSphereSource* sphereSource = vtkSphereSource::New(); sphereSource->SetThetaResolution(25); sphereSource->SetPhiResolution(25); sphereSource->Update(); vtkPolyData* sphere = sphereSource->GetOutput(); m_Surface = mitk::Surface::New(); m_Surface->SetVtkPolyData( sphere ); m_DataNode = mitk::DataNode::New(); m_DataNode->SetData( m_Surface ); m_DataTree = mitk::StandaloneDataStorage::New(); m_DataTree->Add( m_DataNode , (mitk::DataNode *)0 ); m_Controls->m_PreviewRenderWindow->GetRenderer()->SetDataStorage( m_DataTree ); m_Controls->m_PreviewRenderWindow->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); sphereSource->Delete(); } void QmitkMITKSurfaceMaterialEditorView::RefreshPropertiesList() { mitk::DataNode* SrcND = m_SelectedDataNode; mitk::DataNode* DstND = m_DataNode; mitk::PropertyList* DstPL = DstND->GetPropertyList(); m_Controls->m_ShaderPropertyList->SetPropertyList( 0 ); DstPL->Clear(); if(observerAllocated) { observedProperty->RemoveObserver( observerIndex ); observerAllocated=false; } if(SrcND) { mitk::PropertyList* SrcPL = SrcND->GetPropertyList(); mitk::ShaderProperty::Pointer shaderEnum = dynamic_cast(SrcPL->GetProperty("shader")); std::string shaderState = "fixed"; if(shaderEnum.IsNotNull()) { shaderState = shaderEnum->GetValueAsString(); itk::MemberCommand::Pointer propertyModifiedCommand = itk::MemberCommand::New(); propertyModifiedCommand->SetCallbackFunction(this, &QmitkMITKSurfaceMaterialEditorView::shaderEnumChange); observerIndex = shaderEnum->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); observedProperty = shaderEnum; observerAllocated=true; } MITK_INFO << "PROPERTIES SCAN BEGIN"; for(mitk::PropertyList::PropertyMap::const_iterator it=SrcPL->GetMap()->begin(); it!=SrcPL->GetMap()->end(); it++) { std::string name=it->first; - mitk::BaseProperty *p=it->second.first; + mitk::BaseProperty *p=it->second; // MITK_INFO << "property '" << name << "' found"; if(shaderState.compare("fixed")==0) { if(std::find(fixedProperties.begin(), fixedProperties.end(), name) != fixedProperties.end()) { DstPL->SetProperty(name,p); } } else { //if(std::find(shaderProperties.begin(), shaderProperties.end(), name) != shaderProperties.end()) { DstPL->SetProperty(name,p); } } } MITK_INFO << "PROPERTIES SCAN END"; } m_Controls->m_ShaderPropertyList->SetPropertyList( DstPL ); //m_Controls->m_PreviewRenderWindow->GetRenderer()->GetVtkRenderer()->ResetCameraClippingRange(); } /* // subscribe for property change events itk::MemberCommand::Pointer propertyModifiedCommand = itk::MemberCommand::New(); propertyModifiedCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyModified); m_PropertyModifiedObserverTags[it->first] = it->second.first->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); itk::MemberCommand::Pointer propertyModifiedCommand = itk::MemberCommand::New(); propertyModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageTableModel::PropertyModified); mitk::BaseProperty* visibilityProperty = (*it)->GetProperty("visible"); if(visibilityProperty) m_PropertyModifiedObserverTags[visibilityProperty] = visibilityProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); mitk::BaseProperty* nameProperty = (*it)->GetProperty("name"); if(nameProperty) m_PropertyModifiedObserverTags[nameProperty] = nameProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); for(mitk::PropertyList::PropertyMap::const_iterator it=m_PropertyList->GetMap()->begin() ; it!=m_PropertyList->GetMap()->end() ; it++) { // add relevant property column values m_PropertyListElements.push_back((*it)); // subscribe for property change events itk::MemberCommand::Pointer propertyModifiedCommand = itk::MemberCommand::New(); propertyModifiedCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyModified); m_PropertyModifiedObserverTags[it->first] = it->second.first->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand);*/ void QmitkMITKSurfaceMaterialEditorView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkMITKSurfaceMaterialEditorViewControls; m_Controls->setupUi(parent); this->CreateConnections(); InitPreviewWindow(); RefreshPropertiesList(); } } void QmitkMITKSurfaceMaterialEditorView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkMITKSurfaceMaterialEditorView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkMITKSurfaceMaterialEditorView::CreateConnections() { } void QmitkMITKSurfaceMaterialEditorView::Activated() { QmitkFunctionality::Activated(); } void QmitkMITKSurfaceMaterialEditorView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkMITKSurfaceMaterialEditorView::OnSelectionChanged(std::vector nodes) { if(!nodes.empty()) { m_SelectedDataNode = nodes.at(0); MITK_INFO << "Node '" << m_SelectedDataNode->GetName() << "' selected"; SurfaceSelected(); } } void QmitkMITKSurfaceMaterialEditorView::SurfaceSelected() { postRefresh(); } void QmitkMITKSurfaceMaterialEditorView::shaderEnumChange(const itk::Object * /*caller*/, const itk::EventObject & /*event*/) { postRefresh(); } void QmitkMITKSurfaceMaterialEditorView::postRefresh() { if(usedTimer) return; usedTimer=startTimer(0); } void QmitkMITKSurfaceMaterialEditorView::timerEvent( QTimerEvent *e ) { if(usedTimer!=e->timerId()) { MITK_ERROR << "INTERNAL ERROR: usedTimer[" << usedTimer << "] != timerId[" << e->timerId() << "]"; } if(usedTimer) { killTimer(usedTimer); usedTimer=0; } RefreshPropertiesList(); } \ No newline at end of file diff --git a/Modules/MitkExt/DataManagement/mitkDataStorageSelection.cpp b/Modules/MitkExt/DataManagement/mitkDataStorageSelection.cpp index 4a0b31da5c..3fbe12b139 100644 --- a/Modules/MitkExt/DataManagement/mitkDataStorageSelection.cpp +++ b/Modules/MitkExt/DataManagement/mitkDataStorageSelection.cpp @@ -1,369 +1,369 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDataStorageSelection.h" #include #include #include namespace mitk { DataStorageSelection::DataStorageSelection(mitk::DataStorage* _DataStorage, bool _AutoAddNodes) : m_DataStorage(0), m_Predicate(0), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes) { this->SetDataStorage(_DataStorage); } DataStorageSelection::DataStorageSelection(mitk::DataStorage* _DataStorage , mitk::NodePredicateBase* _Predicate , bool _AutoAddNodes) : m_DataStorage(0), m_Predicate(_Predicate), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes) { this->SetDataStorage(_DataStorage); } DataStorageSelection::~DataStorageSelection() { // kick datastorage and all nodes and all listeners this->SetDataStorage(0); } mitk::DataStorage::Pointer DataStorageSelection::GetDataStorage() const { return m_DataStorage; } mitk::NodePredicateBase::Pointer DataStorageSelection::GetPredicate() const { return m_Predicate; } unsigned int DataStorageSelection::GetSize() const { return m_Nodes.size(); } mitk::DataNode::Pointer DataStorageSelection::GetNode() const { return this->GetNode(0); } mitk::DataNode::Pointer DataStorageSelection::GetNode(unsigned int index) const { return (index < m_Nodes.size())? m_Nodes.at(index): 0; } std::vector DataStorageSelection::GetNodes() const { return m_Nodes; } bool DataStorageSelection::DoesAutoAddNodes() const { return m_AutoAddNodes; } DataStorageSelection& DataStorageSelection::operator=(mitk::DataNode* node) { this->RemoveAllNodes(); this->AddNode(node); return *this; } DataStorageSelection& DataStorageSelection::operator=(mitk::DataNode::Pointer node) { *this = node.GetPointer(); return *this; } void DataStorageSelection::SetDataStorage(mitk::DataStorage* _DataStorage) { // only proceed if we have a new datastorage if(m_DataStorage != _DataStorage) { // if a data storage was set before remove old event listeners if(m_DataStorage != 0) { if(m_AutoAddNodes) this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &DataStorageSelection::AddNode ) ); this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &DataStorageSelection::RemoveNode ) ); m_DataStorage->RemoveObserver(m_DataStorageDeletedTag); m_DataStorageDeletedTag = 0; } // set new data storage m_DataStorage = _DataStorage; // if new storage is not 0 subscribe for events if(m_DataStorage != 0) { // subscribe for node added/removed events if(m_AutoAddNodes) this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1( this, &DataStorageSelection::AddNode ) ); this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &DataStorageSelection::RemoveNode ) ); itk::MemberCommand::Pointer ObjectChangedCommand = itk::MemberCommand::New(); ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged); m_DataStorageDeletedTag = m_DataStorage->AddObserver(itk::DeleteEvent(), ObjectChangedCommand); } // Reset model (even if datastorage is 0->will be checked in Reset()) this->Reset(); } } void DataStorageSelection::SetPredicate(mitk::NodePredicateBase* _Predicate) { // ensure that a new predicate is set in order to avoid unnecessary changed events if(m_Predicate != _Predicate) { m_Predicate = _Predicate; this->Reset(); } } void DataStorageSelection::AddNode(const mitk::DataNode* node) { // garantuee no recursions when a new node event is thrown if(m_SelfCall) return; // if we have a predicate, check node against predicate first if(m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node)) return; // no duplicates if(std::find(m_Nodes.begin(), m_Nodes.end(), node) != m_Nodes.end()) return; mitk::DataNode* nonConstNode = const_cast(node); // add listener this->AddListener(nonConstNode); // add node m_Nodes.push_back(nonConstNode); NodeAdded.Send(node); } void DataStorageSelection::RemoveNode(const mitk::DataNode* node) { if(m_SelfCall) return; // find corresponding node std::vector::iterator nodeIt = std::find(m_Nodes.begin(), m_Nodes.end(), node); if(nodeIt == m_Nodes.end()) return; mitk::DataNode* nonConstNode = const_cast(node); // add listener this->RemoveListener(nonConstNode); // remove node m_Nodes.erase(nodeIt); NodeRemoved.Send(node); } void DataStorageSelection::RemoveAllNodes() { // remove all nodes now (dont use iterators because removing elements // would invalidate the iterator) // start at the last element: first in, last out unsigned int i = m_Nodes.size(); while(!m_Nodes.empty()) { --i; this->RemoveNode(m_Nodes.at(i)); } } void DataStorageSelection::ObjectChanged(const itk::Object *caller, const itk::EventObject &event) { if(m_SelfCall) return; const itk::DeleteEvent* delEvent = 0; const itk::ModifiedEvent* modifiedEvent = dynamic_cast(&event); if(!modifiedEvent) delEvent = dynamic_cast(&event); const mitk::BaseProperty* prop = 0; const mitk::PropertyList* propList = 0; const mitk::DataNode* node = dynamic_cast(caller); if(!node) { if((prop = dynamic_cast(caller))) { node = this->FindNode(prop); } else if((propList = dynamic_cast(caller))) { node = this->FindNode(propList); } else if(dynamic_cast(caller)) { this->SetDataStorage(0); } } if(prop && node) { PropertyChanged.Send(node, prop); } else if(node) { NodeChanged.Send(node); } } //# protected mitk::DataNode::Pointer DataStorageSelection::FindNode(const mitk::BaseProperty* prop) const { mitk::DataNode* node = 0; for(Nodes::const_iterator it=m_Nodes.begin(); it!=m_Nodes.end(); ++it) { for(mitk::PropertyList::PropertyMap::const_iterator it2 = (*it)->GetPropertyList()->GetMap()->begin() ; it2 != (*it)->GetPropertyList()->GetMap()->end(); ++it2) { - if(it2->second.first == prop) + if(it2->second == prop) { node = *it; break; } } } return node; } mitk::DataNode::Pointer DataStorageSelection::FindNode(const mitk::PropertyList* propList) const { mitk::DataNode* node = 0; for(Nodes::const_iterator it=m_Nodes.begin(); it!=m_Nodes.end(); ++it) { if((*it)->GetPropertyList() == propList) { node = *it; break; } } return node; } void DataStorageSelection::Reset() { this->RemoveAllNodes(); // the whole reset depends on the fact if a data storage is set or not if(m_DataStorage) { mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = 0; if(m_AutoAddNodes && m_Predicate.IsNotNull()) // get subset _NodeSet = m_DataStorage->GetSubset(m_Predicate); // if predicate is NULL, select all nodes else if(m_AutoAddNodes) { _NodeSet = m_DataStorage->GetAll(); } else return; // finally add all nodes to the model for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end() ; it++) { // save node this->AddNode(*it); } } } void DataStorageSelection::RemoveListener(mitk::DataNode* node) { // remove node listener node->RemoveObserver(m_NodeModifiedObserverTags[node]); m_NodeModifiedObserverTags.erase(node); // remove propertylist listener mitk::PropertyList* propList = node->GetPropertyList(); propList->RemoveObserver(m_PropertyListModifiedObserverTags[propList]); m_PropertyListModifiedObserverTags.erase(propList); propList->RemoveObserver(m_PropertyListDeletedObserverTags[propList]); m_PropertyListDeletedObserverTags.erase(propList); mitk::BaseProperty* prop = 0; // do the same for each property for(mitk::PropertyList::PropertyMap::const_iterator it=propList->GetMap()->begin() ; it!=propList->GetMap()->end() ; ++it) { - prop = it->second.first; + prop = it->second; prop->RemoveObserver(m_PropertyModifiedObserverTags[prop]); m_PropertyModifiedObserverTags.erase(prop); prop->RemoveObserver(m_PropertyDeletedObserverTags[prop]); m_PropertyDeletedObserverTags.erase(prop); } } void DataStorageSelection::AddListener(mitk::DataNode* node) { // node listener itk::MemberCommand::Pointer ObjectChangedCommand = itk::MemberCommand::New(); ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged); m_NodeModifiedObserverTags[node] = node->AddObserver(itk::ModifiedEvent() , ObjectChangedCommand); // create propertylist listener mitk::PropertyList* propList = node->GetPropertyList(); m_PropertyListModifiedObserverTags[propList] = propList ->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand); m_PropertyListDeletedObserverTags[propList] = propList ->AddObserver(itk::DeleteEvent(), ObjectChangedCommand); mitk::BaseProperty* prop = 0; // do the same for each property for(mitk::PropertyList::PropertyMap::const_iterator it=propList->GetMap()->begin() ; it!=propList->GetMap()->end() ; ++it) { - prop = it->second.first; + prop = it->second; m_PropertyModifiedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent() , ObjectChangedCommand); m_PropertyDeletedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent() , ObjectChangedCommand); } } } diff --git a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp index 524eb47bcb..ac27b26fc3 100644 --- a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp +++ b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp @@ -1,304 +1,304 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12. Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkPlanarFigureWriter.h" #include "mitkBasePropertySerializer.h" #include mitk::PlanarFigureWriter::PlanarFigureWriter() : m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Extension(".pf"), m_MimeType("application/MITK.PlanarFigure"), m_Success(false) { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfOutputs( 0 ); //this->SetNthOutput( 0, mitk::PlanarFigure::New().GetPointer() ); m_CanWriteToMemory = true; } mitk::PlanarFigureWriter::~PlanarFigureWriter() {} void mitk::PlanarFigureWriter::GenerateData() { m_Success = false; if (!m_WriteToMemory && m_FileName.empty()) { MITK_ERROR << "Could not write planar figures. File name is invalid"; throw std::invalid_argument("file name is empty"); } TiXmlDocument document; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); // TODO what to write here? encoding? etc.... document.LinkEndChild( decl ); TiXmlElement* version = new TiXmlElement("Version"); version->SetAttribute("Writer", __FILE__ ); version->SetAttribute("CVSRevision", "$Revision: 17055 $" ); version->SetAttribute("FileVersion", 1 ); document.LinkEndChild(version); /* create xml element for each input */ for ( unsigned int i = 0 ; i < this->GetNumberOfInputs(); ++i ) { // Create root element for this PlanarFigure InputType::Pointer pf = this->GetInput( i ); if (pf.IsNull()) continue; TiXmlElement* pfElement = new TiXmlElement("PlanarFigure"); pfElement->SetAttribute("type", pf->GetNameOfClass()); document.LinkEndChild(pfElement); if ( pf->GetNumberOfControlPoints() == 0 ) continue; //PlanarFigure::VertexContainerType* vertices = pf->GetControlPoints(); //if (vertices == NULL) // continue; // Serialize property list of PlanarFigure mitk::PropertyList::Pointer propertyList = pf->GetPropertyList(); mitk::PropertyList::PropertyMap::const_iterator it; for ( it = propertyList->GetMap()->begin(); it != propertyList->GetMap()->end(); ++it ) { // Create seralizer for this property - const mitk::BaseProperty* prop = it->second.first; + const mitk::BaseProperty* prop = it->second; std::string serializerName = std::string( prop->GetNameOfClass() ) + "Serializer"; std::list< itk::LightObject::Pointer > allSerializers = itk::ObjectFactoryBase::CreateAllInstance( serializerName.c_str() ); if ( allSerializers.size() != 1 ) { // No or too many serializer(s) found, skip this property continue; } mitk::BasePropertySerializer* serializer = dynamic_cast< mitk::BasePropertySerializer* >( allSerializers.begin()->GetPointer() ); if ( serializer == NULL ) { // Serializer not valid; skip this property } TiXmlElement* keyElement = new TiXmlElement( "property" ); keyElement->SetAttribute( "key", it->first ); keyElement->SetAttribute( "type", prop->GetNameOfClass() ); serializer->SetProperty( prop ); TiXmlElement* valueElement = NULL; try { valueElement = serializer->Serialize(); } catch (...) { } if ( valueElement == NULL ) { // Serialization failed; skip this property continue; } // Add value to property element keyElement->LinkEndChild( valueElement ); // Append serialized property to property list pfElement->LinkEndChild( keyElement ); } // Serialize control points of PlanarFigure TiXmlElement* controlPointsElement = new TiXmlElement("ControlPoints"); pfElement->LinkEndChild(controlPointsElement); for (unsigned int i = 0; i < pf->GetNumberOfControlPoints(); i++) { TiXmlElement* vElement = new TiXmlElement("Vertex"); vElement->SetAttribute("id", i); vElement->SetDoubleAttribute("x", pf->GetControlPoint(i)[0]); vElement->SetDoubleAttribute("y", pf->GetControlPoint(i)[1]); controlPointsElement->LinkEndChild(vElement); } TiXmlElement* geoElement = new TiXmlElement("Geometry"); const PlaneGeometry* planeGeo = dynamic_cast(pf->GetGeometry2D()); if (planeGeo != NULL) { // Write parameters of IndexToWorldTransform of the PlaneGeometry typedef mitk::AffineGeometryFrame3D::TransformType TransformType; const TransformType* affineGeometry = planeGeo->GetIndexToWorldTransform(); const TransformType::ParametersType& parameters = affineGeometry->GetParameters(); TiXmlElement* vElement = new TiXmlElement( "transformParam" ); for ( unsigned int i = 0; i < affineGeometry->GetNumberOfParameters(); ++i ) { std::stringstream paramName; paramName << "param" << i; vElement->SetDoubleAttribute( paramName.str().c_str(), parameters.GetElement( i ) ); } geoElement->LinkEndChild( vElement ); // Write bounds of the PlaneGeometry typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; const BoundsArrayType& bounds = planeGeo->GetBounds(); vElement = new TiXmlElement( "boundsParam" ); for ( unsigned int i = 0; i < 6; ++i ) { std::stringstream boundName; boundName << "bound" << i; vElement->SetDoubleAttribute( boundName.str().c_str(), bounds.GetElement( i ) ); } geoElement->LinkEndChild( vElement ); // Write spacing and origin of the PlaneGeometry Vector3D spacing = planeGeo->GetSpacing(); Point3D origin = planeGeo->GetOrigin(); geoElement->LinkEndChild(this->CreateXMLVectorElement("Spacing", spacing)); geoElement->LinkEndChild(this->CreateXMLVectorElement("Origin", origin)); pfElement->LinkEndChild(geoElement); } } if(m_WriteToMemory) { // Declare a printer TiXmlPrinter printer; // attach it to the document you want to convert in to a std::string document.Accept(&printer); // Create memory buffer and print tinyxmldocument there... m_MemoryBufferSize = printer.Size(); m_MemoryBuffer = new char[m_MemoryBufferSize]; memcpy(m_MemoryBuffer,printer.CStr(),m_MemoryBufferSize); } else { if (document.SaveFile( m_FileName) == false) { MITK_ERROR << "Could not write planar figures to " << m_FileName << "\nTinyXML reports '" << document.ErrorDesc() << "'"; throw std::ios_base::failure("Error during writing of planar figure xml file."); } } m_Success = true; } void mitk::PlanarFigureWriter::ReleaseMemory() { if(m_MemoryBuffer != NULL) { delete [] m_MemoryBuffer; } } TiXmlElement* mitk::PlanarFigureWriter::CreateXMLVectorElement(const char* name, itk::FixedArray v) { TiXmlElement* vElement = new TiXmlElement(name); vElement->SetDoubleAttribute("x", v.GetElement(0)); vElement->SetDoubleAttribute("y", v.GetElement(1)); vElement->SetDoubleAttribute("z", v.GetElement(2)); return vElement; } void mitk::PlanarFigureWriter::ResizeInputs( const unsigned int& num ) { //unsigned int prevNum = this->GetNumberOfInputs(); this->SetNumberOfInputs( num ); //for ( unsigned int i = prevNum; i < num; ++i ) //{ // this->SetNthInput( i, mitk::PlanarFigure::New().GetPointer() ); //} } void mitk::PlanarFigureWriter::SetInput( InputType* PlanarFigure ) { this->ProcessObject::SetNthInput( 0, PlanarFigure ); } void mitk::PlanarFigureWriter::SetInput( const unsigned int& id, InputType* PlanarFigure ) { if ( id >= this->GetNumberOfInputs() ) this->ResizeInputs( id + 1 ); this->ProcessObject::SetNthInput( id, PlanarFigure ); } mitk::PlanarFigure* mitk::PlanarFigureWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) return NULL; else return dynamic_cast ( this->GetInput( 0 ) ); } mitk::PlanarFigure* mitk::PlanarFigureWriter::GetInput( const unsigned int& num ) { return dynamic_cast ( this->ProcessObject::GetInput( num ) ); } bool mitk::PlanarFigureWriter::CanWriteDataType( DataNode* input ) { if ( input == NULL ) return false; mitk::BaseData* data = input->GetData(); if ( data == NULL) return false; mitk::PlanarFigure::Pointer PlanarFigure = dynamic_cast( data ); if( PlanarFigure.IsNull() ) return false; // add code for special subclasses here return true; } void mitk::PlanarFigureWriter::SetInput( DataNode* input ) { if (this->CanWriteDataType(input)) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } std::string mitk::PlanarFigureWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::PlanarFigureWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(m_Extension); return possibleFileExtensions; } std::string mitk::PlanarFigureWriter::GetFileExtension() { return m_Extension; } diff --git a/Modules/PlanarFigure/Testing/mitkPlanarFigureIOTest.cpp b/Modules/PlanarFigure/Testing/mitkPlanarFigureIOTest.cpp index f6c5630c91..8257e67148 100644 --- a/Modules/PlanarFigure/Testing/mitkPlanarFigureIOTest.cpp +++ b/Modules/PlanarFigure/Testing/mitkPlanarFigureIOTest.cpp @@ -1,566 +1,566 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTestingMacros.h" #include "mitkPlanarAngle.h" #include "mitkPlanarCircle.h" #include "mitkPlanarCross.h" #include "mitkPlanarFourPointAngle.h" #include "mitkPlanarLine.h" #include "mitkPlanarPolygon.h" #include "mitkPlanarRectangle.h" #include "mitkPlanarFigureWriter.h" #include "mitkPlanarFigureReader.h" #include "mitkPlaneGeometry.h" #include /** \brief Helper class for testing PlanarFigure reader and writer classes. */ class PlanarFigureIOTestClass { public: typedef std::list< mitk::PlanarFigure::Pointer > PlanarFigureList; typedef std::vector< mitk::PlanarFigureWriter::Pointer > PlanarFigureToMemoryWriterList; static PlanarFigureList CreatePlanarFigures() { PlanarFigureList planarFigures; // Create PlaneGeometry on which to place the PlanarFigures mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New(); planeGeometry->InitializeStandardPlane( 100.0, 100.0 ); // Create a few sample points for PlanarFigure placement mitk::Point2D p0; p0[0] = 20.0; p0[1] = 20.0; mitk::Point2D p1; p1[0] = 80.0; p1[1] = 80.0; mitk::Point2D p2; p2[0] = 90.0; p2[1] = 10.0; mitk::Point2D p3; p3[0] = 10.0; p3[1] = 90.0; // Create PlanarAngle mitk::PlanarAngle::Pointer planarAngle = mitk::PlanarAngle::New(); planarAngle->SetGeometry2D( planeGeometry ); planarAngle->PlaceFigure( p0 ); planarAngle->SetCurrentControlPoint( p1 ); planarAngle->AddControlPoint( p2 ); planarFigures.push_back( planarAngle.GetPointer() ); // Create PlanarCircle mitk::PlanarCircle::Pointer planarCircle = mitk::PlanarCircle::New(); planarCircle->SetGeometry2D( planeGeometry ); planarCircle->PlaceFigure( p0 ); planarCircle->SetCurrentControlPoint( p1 ); planarFigures.push_back( planarCircle.GetPointer() ); // Create PlanarCross mitk::PlanarCross::Pointer planarCross = mitk::PlanarCross::New(); planarCross->SetSingleLineMode( false ); planarCross->SetGeometry2D( planeGeometry ); planarCross->PlaceFigure( p0 ); planarCross->SetCurrentControlPoint( p1 ); planarCross->AddControlPoint( p2 ); planarCross->AddControlPoint( p3 ); planarFigures.push_back( planarCross.GetPointer() ); // Create PlanarFourPointAngle mitk::PlanarFourPointAngle::Pointer planarFourPointAngle = mitk::PlanarFourPointAngle::New(); planarFourPointAngle->SetGeometry2D( planeGeometry ); planarFourPointAngle->PlaceFigure( p0 ); planarFourPointAngle->SetCurrentControlPoint( p1 ); planarFourPointAngle->AddControlPoint( p2 ); planarFourPointAngle->AddControlPoint( p3 ); planarFigures.push_back( planarFourPointAngle.GetPointer() ); // Create PlanarLine mitk::PlanarLine::Pointer planarLine = mitk::PlanarLine::New(); planarLine->SetGeometry2D( planeGeometry ); planarLine->PlaceFigure( p0 ); planarLine->SetCurrentControlPoint( p1 ); planarFigures.push_back( planarLine.GetPointer() ); // Create PlanarPolygon mitk::PlanarPolygon::Pointer planarPolygon = mitk::PlanarPolygon::New(); planarPolygon->SetClosed( false ); planarPolygon->SetGeometry2D( planeGeometry ); planarPolygon->PlaceFigure( p0 ); planarPolygon->SetCurrentControlPoint( p1 ); planarPolygon->AddControlPoint( p2 ); planarPolygon->AddControlPoint( p3 ); planarFigures.push_back( planarPolygon.GetPointer() ); // Create PlanarRectangle mitk::PlanarRectangle::Pointer planarRectangle = mitk::PlanarRectangle::New(); planarRectangle->SetGeometry2D( planeGeometry ); planarRectangle->PlaceFigure( p0 ); planarRectangle->SetCurrentControlPoint( p1 ); planarFigures.push_back( planarRectangle.GetPointer() ); //create preciseGeometry which is using float coordinates mitk::PlaneGeometry::Pointer preciseGeometry = mitk::PlaneGeometry::New(); mitk::Vector3D right; right[0] = 0.0; right[1] = 1.23456; right[2] = 0.0; mitk::Vector3D down; down[0] = 1.23456; down[1] = 0.0; down[2] = 0.0; mitk::Vector3D spacing; spacing[0] = 0.0123456; spacing[1] = 0.0123456; spacing[2] = 1.123456; preciseGeometry->InitializeStandardPlane( right, down, &spacing ); //convert points into the precise coordinates mitk::Point2D p0precise; p0precise[0] = p0[0] * spacing[0]; p0precise[1] = p0[1] * spacing[1]; mitk::Point2D p1precise; p1precise[0] = p1[0] * spacing[0]; p1precise[1] = p1[1] * spacing[1]; mitk::Point2D p2precise; p2precise[0] = p2[0] * spacing[0]; p2precise[1] = p2[1] * spacing[1]; mitk::Point2D p3precise; p3precise[0] = p3[0] * spacing[0]; p3precise[1] = p3[1] * spacing[1]; //Now all PlanarFigures are create using the precise Geometry // Create PlanarCross mitk::PlanarCross::Pointer nochncross = mitk::PlanarCross::New(); nochncross->SetSingleLineMode( false ); nochncross->SetGeometry2D( preciseGeometry ); nochncross->PlaceFigure( p0precise ); nochncross->SetCurrentControlPoint( p1precise ); nochncross->AddControlPoint( p2precise ); nochncross->AddControlPoint( p3precise ); planarFigures.push_back( nochncross.GetPointer() ); // Create PlanarAngle mitk::PlanarAngle::Pointer planarAnglePrecise = mitk::PlanarAngle::New(); planarAnglePrecise->SetGeometry2D( preciseGeometry ); planarAnglePrecise->PlaceFigure( p0precise ); planarAnglePrecise->SetCurrentControlPoint( p1precise ); planarAnglePrecise->AddControlPoint( p2precise ); planarFigures.push_back( planarAnglePrecise.GetPointer() ); // Create PlanarCircle mitk::PlanarCircle::Pointer planarCirclePrecise = mitk::PlanarCircle::New(); planarCirclePrecise->SetGeometry2D( preciseGeometry ); planarCirclePrecise->PlaceFigure( p0precise ); planarCirclePrecise->SetCurrentControlPoint( p1precise ); planarFigures.push_back( planarCirclePrecise.GetPointer() ); // Create PlanarFourPointAngle mitk::PlanarFourPointAngle::Pointer planarFourPointAnglePrecise = mitk::PlanarFourPointAngle::New(); planarFourPointAnglePrecise->SetGeometry2D( preciseGeometry ); planarFourPointAnglePrecise->PlaceFigure( p0precise ); planarFourPointAnglePrecise->SetCurrentControlPoint( p1precise ); planarFourPointAnglePrecise->AddControlPoint( p2precise ); planarFourPointAnglePrecise->AddControlPoint( p3precise ); planarFigures.push_back( planarFourPointAnglePrecise.GetPointer() ); // Create PlanarLine mitk::PlanarLine::Pointer planarLinePrecise = mitk::PlanarLine::New(); planarLinePrecise->SetGeometry2D( preciseGeometry ); planarLinePrecise->PlaceFigure( p0precise ); planarLinePrecise->SetCurrentControlPoint( p1precise ); planarFigures.push_back( planarLinePrecise.GetPointer() ); // Create PlanarPolygon mitk::PlanarPolygon::Pointer planarPolygonPrecise = mitk::PlanarPolygon::New(); planarPolygonPrecise->SetClosed( false ); planarPolygonPrecise->SetGeometry2D( preciseGeometry ); planarPolygonPrecise->PlaceFigure( p0precise ); planarPolygonPrecise->SetCurrentControlPoint( p1precise ); planarPolygonPrecise->AddControlPoint( p2precise ); planarPolygonPrecise->AddControlPoint( p3precise ); planarFigures.push_back( planarPolygonPrecise.GetPointer() ); // Create PlanarRectangle mitk::PlanarRectangle::Pointer planarRectanglePrecise = mitk::PlanarRectangle::New(); planarRectanglePrecise->SetGeometry2D( preciseGeometry ); planarRectanglePrecise->PlaceFigure( p0precise ); planarRectanglePrecise->SetCurrentControlPoint( p1precise ); planarFigures.push_back( planarRectanglePrecise.GetPointer() ); return planarFigures; } static PlanarFigureList CreateDeepCopiedPlanarFigures(PlanarFigureList original) { PlanarFigureList copiedPlanarFigures; PlanarFigureList::iterator it1; for ( it1 = original.begin(); it1 != original.end(); ++it1 ) { mitk::PlanarFigure::Pointer copiedFigure; if(strcmp((*it1)->GetNameOfClass(), "PlanarAngle") == 0) { copiedFigure = mitk::PlanarAngle::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarCircle") == 0) { copiedFigure = mitk::PlanarCircle::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarLine") == 0) { copiedFigure = mitk::PlanarLine::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarPolygon") == 0) { copiedFigure = mitk::PlanarPolygon::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarCross") == 0) { copiedFigure = mitk::PlanarCross::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarRectangle") == 0) { copiedFigure = mitk::PlanarRectangle::New(); } if(strcmp((*it1)->GetNameOfClass(), "PlanarFourPointAngle") == 0) { copiedFigure = mitk::PlanarFourPointAngle::New(); } copiedFigure->DeepCopy((*it1)); copiedPlanarFigures.push_back(copiedFigure.GetPointer()); } return copiedPlanarFigures; } static void VerifyPlanarFigures( PlanarFigureList &planarFigures1, PlanarFigureList &planarFigures2 ) { PlanarFigureList::iterator it1, it2; for ( it1 = planarFigures1.begin(); it1 != planarFigures1.end(); ++it1 ) { bool planarFigureFound = false; for ( it2 = planarFigures2.begin(); it2 != planarFigures2.end(); ++it2 ) { // Compare PlanarFigures (returns false if different types) if ( ComparePlanarFigures( *it1, *it2 ) ) { planarFigureFound = true; } } // Test if (at least) on PlanarFigure of the first type was found in the second list MITK_TEST_CONDITION_REQUIRED( planarFigureFound, "Testing if " << (*it1)->GetNameOfClass() << " has a counterpart" ); } } static bool ComparePlanarFigures( mitk::PlanarFigure* figure1, mitk::PlanarFigure* figure2 ) { // Test if PlanarFigures are of same type; otherwise return if ( strcmp( figure1->GetNameOfClass(), figure2->GetNameOfClass() ) != 0 ) { return false; } const char* figureName = figure1->GetNameOfClass(); // Test for equal number of control points if(figure1->GetNumberOfControlPoints() != figure2->GetNumberOfControlPoints()) { return false; } // Test if all control points are equal for ( unsigned int i = 0; i < figure1->GetNumberOfControlPoints(); ++i ) { mitk::Point2D point1 = figure1->GetControlPoint( i ); mitk::Point2D point2 = figure2->GetControlPoint( i ); if(point1.EuclideanDistanceTo( point2 ) >= mitk::eps) { return false; } } // Test for equal number of properties typedef mitk::PropertyList::PropertyMap PropertyMap; const PropertyMap* properties1 = figure1->GetPropertyList()->GetMap(); const PropertyMap* properties2 = figure2->GetPropertyList()->GetMap(); if(properties1->size() != properties2->size()) { return false; } MITK_INFO << "List 1:"; for (PropertyMap::const_iterator i1 = properties1->begin(); i1 != properties1->end(); ++i1) { std::cout << i1->first << std::endl; } MITK_INFO << "List 2:"; for (PropertyMap::const_iterator i2 = properties2->begin(); i2 != properties2->end(); ++i2) { std::cout << i2->first << std::endl; } MITK_INFO << "-------"; // Test if all properties are equal if(!std::equal( properties1->begin(), properties1->end(), properties2->begin(), PropertyMapEntryCompare() )) { return false; } // Test if Geometry is equal const mitk::PlaneGeometry* planeGeometry1 = dynamic_cast(figure1->GetGeometry2D()); const mitk::PlaneGeometry* planeGeometry2 = dynamic_cast(figure2->GetGeometry2D()); // Test Geometry transform parameters typedef mitk::AffineGeometryFrame3D::TransformType TransformType; const TransformType* affineGeometry1 = planeGeometry1->GetIndexToWorldTransform(); const TransformType::ParametersType& parameters1 = affineGeometry1->GetParameters(); const TransformType::ParametersType& parameters2 = planeGeometry2->GetIndexToWorldTransform()->GetParameters(); for ( unsigned int i = 0; i < affineGeometry1->GetNumberOfParameters(); ++i ) { if ( fabs(parameters1.GetElement( i ) - parameters2.GetElement( i )) >= mitk::eps ) { return false; } } // Test Geometry bounds typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; const BoundsArrayType& bounds1 = planeGeometry1->GetBounds(); const BoundsArrayType& bounds2 = planeGeometry2->GetBounds(); for ( unsigned int i = 0; i < 6; ++i ) { if ( fabs(bounds1.GetElement( i ) - bounds2.GetElement( i )) >= mitk::eps ) { return false; }; } // Test Geometry spacing and origin mitk::Vector3D spacing1 = planeGeometry1->GetSpacing(); mitk::Vector3D spacing2 = planeGeometry2->GetSpacing(); if((spacing1 - spacing2).GetNorm() >= mitk::eps) { return false; } mitk::Point3D origin1 = planeGeometry1->GetOrigin(); mitk::Point3D origin2 = planeGeometry2->GetOrigin(); if(origin1.EuclideanDistanceTo( origin2 ) >= mitk::eps) { return false; } return true; } static void SerializePlanarFigures( PlanarFigureList &planarFigures, std::string& fileName ) { //std::string sceneFileName = Poco::Path::temp() + /*Poco::Path::separator() +*/ "scene.zip"; std::cout << "File name: " << fileName << std::endl; mitk::PlanarFigureWriter::Pointer writer = mitk::PlanarFigureWriter::New(); writer->SetFileName( fileName.c_str() ); unsigned int i; PlanarFigureList::iterator it; for ( it = planarFigures.begin(), i = 0; it != planarFigures.end(); ++it, ++i ) { writer->SetInput( i, *it ); } writer->Update(); MITK_TEST_CONDITION_REQUIRED( writer->GetSuccess(), "Testing if writing was successful"); } static PlanarFigureList DeserializePlanarFigures( std::string& fileName) { // Read in the planar figures mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); reader->SetFileName( fileName.c_str() ); reader->Update(); MITK_TEST_CONDITION_REQUIRED( reader->GetSuccess(), "Testing if reading was successful"); // Store them in the list and return it PlanarFigureList planarFigures; for ( unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i ) { mitk::PlanarFigure* figure = reader->GetOutput( i ); planarFigures.push_back( figure ); } return planarFigures; } static PlanarFigureToMemoryWriterList SerializePlanarFiguresToMemoryBuffers( PlanarFigureList &planarFigures ) { PlanarFigureToMemoryWriterList pfMemoryWriters; unsigned int i; PlanarFigureList::iterator it; bool success = true; for ( it = planarFigures.begin(), i = 0; it != planarFigures.end(); ++it, ++i ) { mitk::PlanarFigureWriter::Pointer writer = mitk::PlanarFigureWriter::New(); writer->SetWriteToMemory( true ); writer->SetInput( *it ); writer->Update(); pfMemoryWriters.push_back(writer); if(!writer->GetSuccess()) success = false; } MITK_TEST_CONDITION_REQUIRED(success, "Testing if writing to memory buffers was successful"); return pfMemoryWriters; } static PlanarFigureList DeserializePlanarFiguresFromMemoryBuffers( PlanarFigureToMemoryWriterList pfMemoryWriters) { // Store them in the list and return it PlanarFigureList planarFigures; bool success = true; for ( unsigned int i = 0; i < pfMemoryWriters.size(); ++i ) { // Read in the planar figures mitk::PlanarFigureReader::Pointer reader = mitk::PlanarFigureReader::New(); reader->SetReadFromMemory( true ); reader->SetMemoryBuffer(pfMemoryWriters[i]->GetMemoryPointer(), pfMemoryWriters[i]->GetMemorySize()); reader->Update(); mitk::PlanarFigure* figure = reader->GetOutput( 0 ); planarFigures.push_back( figure ); if(!reader->GetSuccess()) success = false; } MITK_TEST_CONDITION_REQUIRED(success, "Testing if reading was successful"); return planarFigures; } private: class PropertyMapEntryCompare { public: bool operator()( const mitk::PropertyList::PropertyMap::value_type &entry1, const mitk::PropertyList::PropertyMap::value_type &entry2 ) { - MITK_INFO << "Comparing " << entry1.first << "(" << entry1.second.first->GetValueAsString() << ") and " << entry2.first << "(" << entry2.second.first->GetValueAsString() << ")"; + MITK_INFO << "Comparing " << entry1.first << "(" << entry1.second->GetValueAsString() << ") and " << entry2.first << "(" << entry2.second->GetValueAsString() << ")"; // Compare property objects contained in the map entries (see mitk::PropertyList) - return *(entry1.second.first) == *(entry2.second.first); + return *(entry1.second) == *(entry2.second); } }; }; // end test helper class /** \brief Test for PlanarFigure reader and writer classes. * * The test works as follows: * * First, a number of PlanarFigure objects of different types are created and placed with * various control points. These objects are the serialized to file, read again from file, and * the retrieved objects are compared with their control points, properties, and geometry * information to the original PlanarFigure objects. */ int mitkPlanarFigureIOTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("PlanarFigureIO"); // Create a number of PlanarFigure objects PlanarFigureIOTestClass::PlanarFigureList originalPlanarFigures = PlanarFigureIOTestClass::CreatePlanarFigures(); // Create a number of "deep-copied" planar figures to test the DeepCopy function PlanarFigureIOTestClass::PlanarFigureList copiedPlanarFigures = PlanarFigureIOTestClass::CreateDeepCopiedPlanarFigures(originalPlanarFigures); PlanarFigureIOTestClass::VerifyPlanarFigures(originalPlanarFigures, copiedPlanarFigures ); // Write PlanarFigure objects into temp file // tmpname static unsigned long count = 0; unsigned long n = count++; std::ostringstream name; for (int i = 0; i < 6; ++i) { name << char('a' + (n % 26)); n /= 26; } std::string myname; myname.append(name.str()); std::string fileName = itksys::SystemTools::GetCurrentWorkingDirectory() + myname + ".pf"; PlanarFigureIOTestClass::SerializePlanarFigures( originalPlanarFigures, fileName ); // Write PlanarFigure objects to memory buffers PlanarFigureIOTestClass::PlanarFigureToMemoryWriterList writersWithMemoryBuffers = PlanarFigureIOTestClass::SerializePlanarFiguresToMemoryBuffers( originalPlanarFigures ); // Read PlanarFigure objects from temp file PlanarFigureIOTestClass::PlanarFigureList retrievedPlanarFigures = PlanarFigureIOTestClass::DeserializePlanarFigures( fileName ); // Read PlanarFigure objects from memory buffers PlanarFigureIOTestClass::PlanarFigureList retrievedPlanarFiguresFromMemory = PlanarFigureIOTestClass::DeserializePlanarFiguresFromMemoryBuffers( writersWithMemoryBuffers ); PlanarFigureIOTestClass::PlanarFigureToMemoryWriterList::iterator it = writersWithMemoryBuffers.begin(); while(it != writersWithMemoryBuffers.end()) { (*it)->ReleaseMemory(); ++it; } // Test if original and retrieved PlanarFigure objects are the same PlanarFigureIOTestClass::VerifyPlanarFigures( originalPlanarFigures, retrievedPlanarFigures ); // Test if original and memory retrieved PlanarFigure objects are the same PlanarFigureIOTestClass::VerifyPlanarFigures( originalPlanarFigures, retrievedPlanarFiguresFromMemory ); //empty the originalPlanarFigures originalPlanarFigures.empty(); // Test if deep-copied and retrieved PlanarFigure objects are the same PlanarFigureIOTestClass::VerifyPlanarFigures( copiedPlanarFigures, retrievedPlanarFigures ); MITK_TEST_END() } diff --git a/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp b/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp index d8acf244e3..00fe024829 100644 --- a/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp +++ b/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp @@ -1,339 +1,339 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTestingMacros.h" #include "mitkTestingConfig.h" #include "mitkSceneIO.h" #include "mitkStandaloneDataStorage.h" #include "mitkStandardFileLocations.h" #include "mitkDataNodeFactory.h" #include "mitkCoreObjectFactory.h" #include "mitkBaseData.h" #include "mitkImage.h" #include "mitkSurface.h" #include "mitkPointSet.h" #include "Poco/File.h" #include "Poco/TemporaryFile.h" #ifndef WIN32 #include #include #endif class SceneIOTestClass { public: static mitk::BaseData::Pointer LoadBaseData(const std::string& filename) { mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New(); try { factory->SetFileName( filename ); factory->Update(); if(factory->GetNumberOfOutputs()<1) { MITK_TEST_FAILED_MSG(<< "Could not find test data '" << filename << "'"); } mitk::DataNode::Pointer node = factory->GetOutput( 0 ); return node->GetData(); } catch ( itk::ExceptionObject & e ) { MITK_TEST_FAILED_MSG(<< "Failed loading test data '" << filename << "': " << e.what()); } } static mitk::Image::Pointer LoadImage(const std::string& filename) { mitk::BaseData::Pointer basedata = LoadBaseData( filename ); mitk::Image::Pointer image = dynamic_cast(basedata.GetPointer()); if(image.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test image '" << filename << "' was not loaded as an mitk::Image"); } return image; } static mitk::Surface::Pointer LoadSurface(const std::string& filename) { mitk::BaseData::Pointer basedata = LoadBaseData( filename ); mitk::Surface::Pointer surface = dynamic_cast(basedata.GetPointer()); if(surface.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test surface '" << filename << "' was not loaded as an mitk::Surface"); } return surface; } static mitk::PointSet::Pointer CreatePointSet() { mitk::PointSet::Pointer ps = mitk::PointSet::New(); mitk::PointSet::PointType p; mitk::FillVector3D(p, 1.0, -2.0, 33.0); ps->SetPoint(0, p); mitk::FillVector3D(p, 100.0, -200.0, 3300.0); ps->SetPoint(1, p); mitk::FillVector3D(p, 2.0, -3.0, 22.0); ps->SetPoint(2, p, mitk::PTCORNER); // add point spec //mitk::FillVector3D(p, -2.0, -2.0, -2.22); //ps->SetPoint(0, p, 1); // ID 0 in timestep 1 //mitk::FillVector3D(p, -1.0, -1.0, -11.22); //ps->SetPoint(1, p, 1); // ID 1 in timestep 1 //mitk::FillVector3D(p, 1000.0, 1000.0, 1122.22); //ps->SetPoint(11, p, mitk::PTCORNER, 2); // ID 11, point spec, timestep 2 return ps; } static void FillStorage(mitk::DataStorage* storage, std::string imageName, std::string surfaceName) { mitk::Image::Pointer image = LoadImage(imageName); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"Loading test image Pic3D.pic.gz"); image->SetProperty("image type", mitk::StringProperty::New("test image") ); image->SetProperty("greetings", mitk::StringProperty::New("to mom") ); mitk::DataNode::Pointer imagenode = mitk::DataNode::New(); imagenode->SetData( image ); imagenode->SetName( "Pic3D" ); storage->Add( imagenode ); mitk::DataNode::Pointer imagechildnode = mitk::DataNode::New(); imagechildnode->SetData( image ); imagechildnode->SetName( "Pic3D again" ); storage->Add( imagechildnode, imagenode ); mitk::Surface::Pointer surface = LoadSurface(surfaceName ); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(),"Loading test surface binary.stl"); surface->SetProperty("surface type", mitk::StringProperty::New("test surface") ); surface->SetProperty("greetings", mitk::StringProperty::New("to dad") ); mitk::DataNode::Pointer surfacenode = mitk::DataNode::New(); surfacenode->SetData( surface ); surfacenode->SetName( "binary" ); storage->Add( surfacenode ); mitk::PointSet::Pointer ps = CreatePointSet(); mitk::DataNode::Pointer psenode = mitk::DataNode::New(); psenode->SetData( ps ); psenode->SetName( "points" ); storage->Add( psenode ); } static void VerifyStorage(mitk::DataStorage* storage) { //TODO the Surface and PointSet are uncommented until the material property is saved properly mitk::DataNode::Pointer imagenode = storage->GetNamedNode("Pic3D"); MITK_TEST_CONDITION_REQUIRED(imagenode.IsNotNull(),"Get previously stored image node"); //Image std::string testString(""); imagenode->GetStringProperty("image type", testString); MITK_TEST_CONDITION_REQUIRED(!(testString == "test image") ,"Get StringProperty from previously stored image node"); imagenode->GetStringProperty("greetings", testString); MITK_TEST_CONDITION_REQUIRED(!(testString == "to mom") ,"Get another StringProperty from previously stored image node"); mitk::Image::Pointer image = dynamic_cast(imagenode->GetData()); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"Loading test image from Datastorage"); //Get Image child node mitk::DataNode::Pointer imagechildnode = storage->GetNamedNode("Pic3D again"); mitk::DataStorage::SetOfObjects::ConstPointer objects = storage->GetSources(imagechildnode); MITK_TEST_CONDITION_REQUIRED(objects->Size() == 1,"Check size of image child nodes source list"); MITK_TEST_CONDITION_REQUIRED(objects->ElementAt(0) == imagenode,"Check for right parent node"); mitk::Image::Pointer imagechild = dynamic_cast(imagechildnode->GetData()); MITK_TEST_CONDITION_REQUIRED(imagechild.IsNotNull(),"Loading child test image from Datastorage"); //Surface mitk::DataNode::Pointer surfacenode = storage->GetNamedNode("binary"); MITK_TEST_CONDITION_REQUIRED(surfacenode.IsNotNull(),"Get previously stored surface node"); surfacenode->GetStringProperty("surface type", testString); MITK_TEST_CONDITION_REQUIRED(!(testString.compare("test surface") == 0) ,"Get StringProperty from previously stored surface node"); surfacenode->GetStringProperty("greetings", testString); MITK_TEST_CONDITION_REQUIRED(!(testString.compare("to dad") == 0) ,"Get another StringProperty from previously stored surface node"); mitk::Surface::Pointer surface = dynamic_cast(surfacenode->GetData()); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(),"Loading test surface from Datastorage"); //PointSet mitk::DataNode::Pointer pointsnode = storage->GetNamedNode("points"); MITK_TEST_CONDITION_REQUIRED(pointsnode.IsNotNull(),"Get previously stored PointSet node"); mitk::PointSet::Pointer pointset = dynamic_cast(pointsnode->GetData()); MITK_TEST_CONDITION_REQUIRED(pointset.IsNotNull(),"Loading test PointSet from Datastorage"); mitk::PointSet::PointType p = pointset->GetPoint(0); MITK_TEST_CONDITION_REQUIRED(p[0] == 1.0 && p[1] == -2.0 && p[2] == 33.0, "Test Pointset entry 0 after loading"); p = pointset->GetPoint(1); MITK_TEST_CONDITION_REQUIRED(p[0] == 100.0 && p[1] == -200.0 && p[2] == 3300.0, "Test Pointset entry 1 after loading"); p = pointset->GetPoint(2); MITK_TEST_CONDITION_REQUIRED(p[0] == 2.0 && p[1] == -3.0 && p[2] == 22.0, "Test Pointset entry 2 after loading"); } }; // end test helper class int mitkSceneIOTest(int argc, char* argv[]) { MITK_TEST_BEGIN("SceneIO") std::string sceneFileName; for (unsigned int i = 0; i < 1; ++i) // TODO change to " < 2" to check cases where file system would be full { if (i == 1) { // call ulimit and restrict maximum file size to something small #ifndef WIN32 errno = 0; long int value = ulimit(UL_SETFSIZE, 1); MITK_TEST_CONDITION_REQUIRED( value != -1, "ulimit() returned with errno = " << errno ); #else continue; #endif } // create a data storage and fill it with some test data mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); MITK_TEST_CONDITION_REQUIRED(sceneIO.IsNotNull(),"SceneIO instantiation") mitk::DataStorage::Pointer storage = mitk::StandaloneDataStorage::New().GetPointer(); MITK_TEST_CONDITION_REQUIRED(storage.IsNotNull(),"StandaloneDataStorage instantiation"); std::cout << "ImageName: " << argv[1] << std::endl; std::cout << "SurfaceName: " << argv[2] << std::endl; SceneIOTestClass::FillStorage(storage, argv[1], argv[2]); // attempt to save it Poco::Path newname( Poco::TemporaryFile::tempName() ); sceneFileName = std::string( MITK_TEST_OUTPUT_DIR ) + Poco::Path::separator() + newname.getFileName() + ".zip"; MITK_TEST_CONDITION_REQUIRED( sceneIO->SaveScene( storage->GetAll(), storage, sceneFileName), "Saving scene file '" << sceneFileName << "'"); // test if no errors were reported mitk::SceneIO::FailedBaseDataListType::ConstPointer failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT( << "The following nodes could not be serialized:"); for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { MITK_TEST_OUTPUT_NO_ENDL( << " - "); if ( mitk::BaseData* data =(*iter)->GetData() ) { MITK_TEST_OUTPUT_NO_ENDL( << data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL( << "(NULL)"); } MITK_TEST_OUTPUT( << " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } mitk::PropertyList::ConstPointer failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT( << "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { - MITK_TEST_OUTPUT( << " - " << iter->second.first->GetNameOfClass() << " associated to key '" << iter->first << "'"); + MITK_TEST_OUTPUT( << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } MITK_TEST_CONDITION_REQUIRED(failedProperties.IsNotNull() && failedProperties->IsEmpty(), "Checking if all properties have been saved.") MITK_TEST_CONDITION_REQUIRED(failedNodes.IsNotNull() && failedNodes->empty(), "Checking if all nodes have been saved.") //Now do the loading part sceneIO = mitk::SceneIO::New(); //Load scene into the datastorage and clean the DS first MITK_TEST_OUTPUT(<< "Loading scene again"); storage = sceneIO->LoadScene(sceneFileName,storage,true); // test if no errors were reported failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT( << "The following nodes could not be serialized:"); for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { MITK_TEST_OUTPUT_NO_ENDL( << " - "); if ( mitk::BaseData* data =(*iter)->GetData() ) { MITK_TEST_OUTPUT_NO_ENDL( << data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL( << "(NULL)"); } MITK_TEST_OUTPUT( << " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT( << "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { - MITK_TEST_OUTPUT( << " - " << iter->second.first->GetNameOfClass() << " associated to key '" << iter->first << "'"); + MITK_TEST_OUTPUT( << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } // check if data storage content has been restored correctly SceneIOTestClass::VerifyStorage(storage); } // if no sub-test failed remove the scene file, otherwise it is kept for debugging purposes if ( mitk::TestManager::GetInstance()->NumberOfFailedTests() == 0 ) { Poco::File pocoSceneFile( sceneFileName ); MITK_TEST_CONDITION_REQUIRED( pocoSceneFile.exists(), "Checking if scene file still exists before cleaning up." ) pocoSceneFile.remove(); } MITK_TEST_END(); } diff --git a/Modules/SceneSerializationBase/Testing/mitkPropertySerializationTest.cpp b/Modules/SceneSerializationBase/Testing/mitkPropertySerializationTest.cpp index 5122d51767..b41256b0bf 100644 --- a/Modules/SceneSerializationBase/Testing/mitkPropertySerializationTest.cpp +++ b/Modules/SceneSerializationBase/Testing/mitkPropertySerializationTest.cpp @@ -1,284 +1,284 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTestingMacros.h" #include "mitkDataNodeFactory.h" #include "mitkCoreObjectFactory.h" #include "mitkBaseProperty.h" #include "mitkProperties.h" #include #include #include #include /* #include #include #include */ #include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPropertyList.h" #include "mitkPropertyListSerializer.h" #include "mitkBasePropertySerializer.h" #include "mitkBasePropertyDeserializer.h" #include #include #include #include /* #include #include #include #include #include #include #include #include #include #include */ void TestAllProperties(const mitk::PropertyList* propList); /**Documentation * \brief Test for all PropertySerializer and PropertyDeserializer classes. * */ int mitkPropertySerializationTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("PropertySerializationTest"); mitk::PropertyListSerializer::Pointer serializer = mitk::PropertyListSerializer::New(); // make sure something from the lib is actually used (registration of serializers/deserializers) /* build list of properties that will be serialized and deserialized */ mitk::PropertyList::Pointer propList = mitk::PropertyList::New(); propList->SetProperty("booltrue", mitk::BoolProperty::New(true)); propList->SetProperty("boolfalse", mitk::BoolProperty::New(false)); propList->SetProperty("int", mitk::IntProperty::New(-32)); propList->SetProperty("float", mitk::FloatProperty::New(-31.337)); propList->SetProperty("double", mitk::DoubleProperty::New(-31.337)); propList->SetProperty("string", mitk::StringProperty::New("Hello MITK")); mitk::Point3D p3d; mitk::FillVector3D(p3d, 1.0, 2.2, -3.3); propList->SetProperty("p3d", mitk::Point3dProperty::New(p3d)); mitk::Point3I p3i; mitk::FillVector3D(p3i, 1, 2, -3); propList->SetProperty("p3i", mitk::Point3iProperty::New(p3i)); mitk::Point4D p4d; mitk::FillVector4D(p4d, 1.5, 2.6, -3.7, 4.44); propList->SetProperty("p4d", mitk::Point4dProperty::New(p4d)); mitk::Vector3D v3d; mitk::FillVector3D(v3d, 1.0, 2.2, -3.3); propList->SetProperty("v3d", mitk::Vector3DProperty::New(v3d)); propList->SetProperty("annotation", mitk::AnnotationProperty::New("My Annotation", p3d)); propList->SetProperty("clipping", mitk::ClippingProperty::New(p3d, v3d)); propList->SetProperty("color", mitk::ColorProperty::New(1.0, 0.2, 0.2)); //mitk::EnumerationProperty::Pointer en = mitk::EnumerationProperty::New(); //en->AddEnum("PC", 1); en->AddEnum("Playstation", 2); en->AddEnum("Wii", 111); en->AddEnum("XBox", 7); //en->SetValue("XBox"); //propList->SetProperty("enum", en); /* propList->SetProperty("gridrep", mitk::GridRepresentationProperty::New(2)); propList->SetProperty("gridvol", mitk::GridVolumeMapperProperty::New(0)); propList->SetProperty("OrganTypeProperty", mitk::OrganTypeProperty::New("Larynx")); */ propList->SetProperty("modality", mitk::ModalityProperty::New("Color Doppler")); //propList->SetProperty("OdfNormalizationMethodProperty", mitk::OdfNormalizationMethodProperty::New("Global Maximum")); //propList->SetProperty("OdfScaleByProperty", mitk::OdfScaleByProperty::New("Principal Curvature")); propList->SetProperty("PlaneOrientationProperty", mitk::PlaneOrientationProperty::New("Arrows in positive direction")); propList->SetProperty("ShaderProperty", mitk::ShaderProperty::New("fixed")); propList->SetProperty("VtkInterpolationProperty", mitk::VtkInterpolationProperty::New("Gouraud")); propList->SetProperty("VtkRepresentationProperty", mitk::VtkRepresentationProperty::New("Surface")); propList->SetProperty("VtkResliceInterpolationProperty", mitk::VtkResliceInterpolationProperty::New("Cubic")); propList->SetProperty("VtkScalarModeProperty", mitk::VtkScalarModeProperty::New("PointFieldData")); propList->SetProperty("VtkVolumeRenderingProperty", mitk::VtkVolumeRenderingProperty::New("COMPOSITE")); mitk::BoolLookupTable blt; blt.SetTableValue(0, true); blt.SetTableValue(1, false); blt.SetTableValue(2, true); propList->SetProperty("BoolLookupTableProperty", mitk::BoolLookupTableProperty::New(blt)); mitk::FloatLookupTable flt; flt.SetTableValue(0, 3.1); flt.SetTableValue(1, 3.3); flt.SetTableValue(2, 7.0); propList->SetProperty("FloatLookupTableProperty", mitk::FloatLookupTableProperty::New(flt)); mitk::IntLookupTable ilt; ilt.SetTableValue(0, 3); ilt.SetTableValue(1, 2); ilt.SetTableValue(2, 11); propList->SetProperty("IntLookupTableProperty", mitk::IntLookupTableProperty::New(ilt)); mitk::StringLookupTable slt; slt.SetTableValue(0, "Hello"); slt.SetTableValue(1, "MITK"); slt.SetTableValue(2, "world"); propList->SetProperty("StringLookupTableProperty", mitk::StringLookupTableProperty::New(slt)); propList->SetProperty("GroupTagProperty", mitk::GroupTagProperty::New()); propList->SetProperty("LevelWindowProperty", mitk::LevelWindowProperty::New(mitk::LevelWindow(100.0, 50.0))); mitk::LookupTable::Pointer lt = mitk::LookupTable::New(); lt->ChangeOpacityForAll(0.25); lt->ChangeOpacity(17, 0.88); propList->SetProperty("LookupTableProperty", mitk::LookupTableProperty::New(lt)); propList->SetProperty("StringProperty", mitk::StringProperty::New("Oh why, gruel world")); //mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); //tf->SetTransferFunctionMode(1); //propList->SetProperty("TransferFunctionProperty", mitk::TransferFunctionProperty::New(tf)); MITK_TEST_CONDITION_REQUIRED(propList->GetMap()->size() > 0, "Initialize PropertyList"); TestAllProperties(propList); /* test default property lists of basedata objects */ // activate the following tests after MaterialProperty is deleted mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(mitk::PointSet::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Image::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Surface::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::VtkWidgetRendering::New()); TestAllProperties(node->GetPropertyList()); /* node->SetData(mitk::Contour::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::ContourSet::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Mesh::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Cone::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Cuboid::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Cylinder::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Ellipsoid::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::ExtrudedContour::New()); TestAllProperties(node->GetPropertyList()); node->SetData(mitk::Plane::New()); TestAllProperties(node->GetPropertyList()); //node->SetData(mitk::TrackingVolume::New()); // TrackingVolume is in IGT Module, it does not have special properties, therefore we skip it here //TestAllProperties(node->GetPropertyList()); node->SetData(mitk::UnstructuredGrid::New()); TestAllProperties(node->GetPropertyList()); */ /* untested base data types: BaseDataTestImplementation RenderWindowFrame mitk::DiffusionImage< TPixelType > GeometryData mitk::Geometry2DData GradientBackground ItkBaseDataAdapter ManufacturerLogo SlicedData QBallImage SeedsImage TensorImage BoundingObject BoundingObjectGroup */ MITK_TEST_END(); } void TestAllProperties(const mitk::PropertyList* propList) { assert(propList); /* try to serialize each property in the list, then deserialize again and check for equality */ for (mitk::PropertyList::PropertyMap::const_iterator it = propList->GetMap()->begin(); it != propList->GetMap()->end(); ++it) { - const mitk::BaseProperty* prop = it->second.first; + const mitk::BaseProperty* prop = it->second; // construct name of serializer class std::string serializername = std::string(prop->GetNameOfClass()) + "Serializer"; std::list allSerializers = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str()); MITK_TEST_CONDITION(allSerializers.size() > 0, std::string("Creating serializers for ") + serializername); if (allSerializers.size() == 0) { MITK_TEST_OUTPUT( << "serialization not possible, skipping " << prop->GetNameOfClass()); continue; } if (allSerializers.size() > 1) { MITK_TEST_OUTPUT (<< "Warning: " << allSerializers.size() << " serializers found for " << prop->GetNameOfClass() << "testing only the first one."); } mitk::BasePropertySerializer* serializer = dynamic_cast( allSerializers.begin()->GetPointer()); MITK_TEST_CONDITION(serializer != NULL, serializername + std::string(" is valid")); if (serializer != NULL) { serializer->SetProperty(prop); TiXmlElement* valueelement = NULL; try { valueelement = serializer->Serialize(); } catch (...) { } MITK_TEST_CONDITION(valueelement != NULL, std::string("Serialize property with ") + serializername); if (valueelement == NULL) { MITK_TEST_OUTPUT( << "serialization failed, skipping deserialization"); continue; } /* build deserializer and try to deserialize property */ std::string deserializerName = std::string(prop->GetNameOfClass()) + std::string("Deserializer"); std::list allDeserializers = itk::ObjectFactoryBase::CreateAllInstance(deserializerName.c_str()); MITK_TEST_CONDITION(allDeserializers.size() > 0, std::string("Creating deserializers for ") + deserializerName); if (allDeserializers.size() == 0) { MITK_TEST_OUTPUT( << "deserialization not possible, skipping deserialization of " << prop->GetNameOfClass()); continue; } if (allDeserializers.size() > 1) { MITK_TEST_OUTPUT (<< "Warning: " << allDeserializers.size() << " deserializers found for " << prop->GetNameOfClass() << "testing only the first one."); } mitk::BasePropertyDeserializer* deserializer = dynamic_cast( allDeserializers.begin()->GetPointer()); MITK_TEST_CONDITION(deserializer != NULL, deserializerName + std::string(" is valid")); if (deserializer != NULL) { mitk::BaseProperty::Pointer deserializedProp = deserializer->Deserialize( valueelement ); MITK_TEST_CONDITION(deserializedProp.IsNotNull(), "deserializer created valid property"); if (deserializedProp.IsNotNull()) { MITK_TEST_CONDITION(*(deserializedProp.GetPointer()) == *prop, "deserialized property equals initial property for type " << prop->GetNameOfClass()); } } } else { MITK_TEST_OUTPUT( << "created serializer object is of class " << allSerializers.begin()->GetPointer()->GetNameOfClass()) } } // for all properties } diff --git a/Modules/SceneSerializationBase/mitkPropertyListSerializer.cpp b/Modules/SceneSerializationBase/mitkPropertyListSerializer.cpp index 0f99d98081..3390c36c9e 100644 --- a/Modules/SceneSerializationBase/mitkPropertyListSerializer.cpp +++ b/Modules/SceneSerializationBase/mitkPropertyListSerializer.cpp @@ -1,167 +1,167 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkPropertyListSerializer.h" #include "mitkBasePropertySerializer.h" #include #include "mitkStandardFileLocations.h" #include mitk::PropertyListSerializer::PropertyListSerializer() : m_FilenameHint("unnamed") , m_WorkingDirectory("") { } mitk::PropertyListSerializer::~PropertyListSerializer() { } std::string mitk::PropertyListSerializer::Serialize() { m_FailedProperties = PropertyList::New(); if ( m_PropertyList.IsNull() || m_PropertyList->IsEmpty() ) { MITK_ERROR << "Not serializing NULL or empty PropertyList"; return ""; } // tmpname static unsigned long count = 1; unsigned long n = count++; std::ostringstream name; for (int i = 0; i < 6; ++i) { name << char('a' + (n % 26)); n /= 26; } std::string filename; filename.append(name.str()); std::string fullname(m_WorkingDirectory); fullname += "/"; fullname += filename; fullname = itksys::SystemTools::ConvertToOutputPath(fullname.c_str()); TiXmlDocument document; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); // TODO what to write here? encoding? etc.... document.LinkEndChild( decl ); TiXmlElement* version = new TiXmlElement("Version"); version->SetAttribute("Writer", __FILE__ ); version->SetAttribute("Revision", "$Revision: 17055 $" ); version->SetAttribute("FileVersion", 1 ); document.LinkEndChild(version); // add XML contents const PropertyList::PropertyMap* propmap = m_PropertyList->GetMap(); for ( PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { std::string key = iter->first; - const BaseProperty* property = iter->second.first; + const BaseProperty* property = iter->second; TiXmlElement* element = SerializeOneProperty( key, property ); if (element) { document.LinkEndChild( element ); // TODO test serializer for error } else { m_FailedProperties->ReplaceProperty( key, const_cast(property) ); } } // save XML file if ( !document.SaveFile( fullname ) ) { MITK_ERROR << "Could not write PropertyList to " << fullname << "\nTinyXML reports '" << document.ErrorDesc() << "'"; return ""; } return filename; } TiXmlElement* mitk::PropertyListSerializer::SerializeOneProperty( const std::string& key, const BaseProperty* property ) { TiXmlElement* keyelement = new TiXmlElement("property"); keyelement->SetAttribute("key", key); keyelement->SetAttribute("type", property->GetNameOfClass()); // construct name of serializer class std::string serializername(property->GetNameOfClass()); serializername += "Serializer"; std::list allSerializers = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str()); if (allSerializers.size() < 1) { MITK_ERROR << "No serializer found for " << property->GetNameOfClass() << ". Skipping object"; m_FailedProperties->ReplaceProperty( key, const_cast(property) ); } if (allSerializers.size() > 1) { MITK_WARN << "Multiple serializers found for " << property->GetNameOfClass() << "Using arbitrarily the first one."; } for ( std::list::iterator iter = allSerializers.begin(); iter != allSerializers.end(); ++iter ) { if (BasePropertySerializer* serializer = dynamic_cast( iter->GetPointer() ) ) { serializer->SetProperty(property); try { TiXmlElement* valueelement = serializer->Serialize(); if (valueelement) { keyelement->LinkEndChild( valueelement ); // \TODO: put 'return keyelement;' here? } else { m_FailedProperties->ReplaceProperty( key, const_cast(property) ); } } catch (std::exception& e) { MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what(); m_FailedProperties->ReplaceProperty( key, const_cast(property) ); // \TODO: log only if all potential serializers fail? } break; } } return keyelement; } mitk::PropertyList* mitk::PropertyListSerializer::GetFailedProperties() { if (m_FailedProperties.IsNotNull() && !m_FailedProperties->IsEmpty()) { return m_FailedProperties; } else { return NULL; } }