diff --git a/Modules/Core/src/IO/mitkProportionalTimeGeometryToXML.cpp b/Modules/Core/src/IO/mitkProportionalTimeGeometryToXML.cpp index 081d44c7e4..3b42888705 100644 --- a/Modules/Core/src/IO/mitkProportionalTimeGeometryToXML.cpp +++ b/Modules/Core/src/IO/mitkProportionalTimeGeometryToXML.cpp @@ -1,164 +1,164 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkProportionalTimeGeometryToXML.h" #include "mitkGeometry3DToXML.h" #include #include tinyxml2::XMLElement *mitk::ProportionalTimeGeometryToXML::ToXML(tinyxml2::XMLDocument& doc, const ProportionalTimeGeometry *timeGeom) { assert(timeGeom); auto *timeGeomElem = doc.NewElement("ProportionalTimeGeometry"); - timeGeomElem->SetAttribute("NumberOfTimeSteps", timeGeom->CountTimeSteps()); + timeGeomElem->SetAttribute("NumberOfTimeSteps", static_cast(timeGeom->CountTimeSteps())); // TinyXML cannot serialize infinity (default value for time step) // So we guard this value and the first time point against serialization problems // by not writing them. The reader can then tell that absence of those values // means "keep the default values" if (timeGeom->GetFirstTimePoint() != -std::numeric_limits::max()) timeGeomElem->SetAttribute("FirstTimePoint", boost::lexical_cast(timeGeom->GetFirstTimePoint()).c_str()); if (timeGeom->GetStepDuration() != std::numeric_limits::infinity()) timeGeomElem->SetAttribute("StepDuration", boost::lexical_cast(timeGeom->GetStepDuration()).c_str()); for (TimeStepType t = 0; t < timeGeom->CountTimeSteps(); ++t) { // add a node for the geometry of each time step const Geometry3D *geom3D(nullptr); if ((geom3D = dynamic_cast(timeGeom->GetGeometryForTimeStep(t).GetPointer()))) { auto *geom3DElement = Geometry3DToXML::ToXML(doc, geom3D); - geom3DElement->SetAttribute("TimeStep", t); // mark order for us + geom3DElement->SetAttribute("TimeStep", static_cast(t)); // mark order for us timeGeomElem->InsertEndChild(geom3DElement); } else { MITK_WARN << "Serializing a ProportionalTimeGeometry that contains something other than Geometry3D!" << " (in time step " << t << ")" << " File will miss information!"; } } return timeGeomElem; } mitk::ProportionalTimeGeometry::Pointer mitk::ProportionalTimeGeometryToXML::FromXML(const tinyxml2::XMLElement *timeGeometryElement) { if (!timeGeometryElement) { MITK_ERROR << "Cannot deserialize ProportionalTimeGeometry from nullptr."; return nullptr; } int numberOfTimeSteps = 0; if (tinyxml2::XML_SUCCESS != timeGeometryElement->QueryIntAttribute("NumberOfTimeSteps", &numberOfTimeSteps)) { MITK_WARN << " found without NumberOfTimeSteps attribute. Counting..."; } // might be missing! TimePointType firstTimePoint; const char* firstTimePoint_s = nullptr; TimePointType stepDuration; const char* stepDuration_s = nullptr; try { firstTimePoint_s = timeGeometryElement->Attribute("FirstTimePoint"); if (nullptr != firstTimePoint_s) { firstTimePoint = boost::lexical_cast(firstTimePoint_s); } else { firstTimePoint = -std::numeric_limits::max(); } stepDuration_s = timeGeometryElement->Attribute("StepDuration"); if (nullptr != stepDuration_s) { stepDuration = boost::lexical_cast(stepDuration_s); } else { stepDuration = std::numeric_limits::infinity(); } } catch ( const boost::bad_lexical_cast &e ) { MITK_ERROR << "Could not parse string as number: " << e.what(); return nullptr; } // list of all geometries with their time steps std::multimap allReadGeometries; int indexForUnlabeledTimeStep(-1); for (auto *currentElement = timeGeometryElement->FirstChildElement(); currentElement != nullptr; currentElement = currentElement->NextSiblingElement()) { // different geometries could have been inside a ProportionalTimeGeometry. // By now, we only support Geometry3D std::string tagName = currentElement->Value(); if (tagName == "Geometry3D") { Geometry3D::Pointer restoredGeometry = Geometry3DToXML::FromXML(currentElement); if (restoredGeometry.IsNotNull()) { int timeStep(-1); if (tinyxml2::XML_SUCCESS != currentElement->QueryIntAttribute("TimeStep", &timeStep)) { timeStep = indexForUnlabeledTimeStep--; // decrement index for next one MITK_WARN << "Found without 'TimeStep' attribute in . No guarantees " "on order anymore."; } if (allReadGeometries.count(static_cast(timeStep)) > 0) { MITK_WARN << "Found tags with identical 'TimeStep' attribute in . No " "guarantees on order anymore."; } allReadGeometries.insert(std::make_pair(static_cast(timeStep), restoredGeometry.GetPointer())); } } else { MITK_WARN << "Found unsupported tag <" << tagName << "> inside . Ignoring."; } } // now add all BaseGeometries that were read to a new instance // of ProportionalTimeGeometry ProportionalTimeGeometry::Pointer newTimeGeometry = ProportionalTimeGeometry::New(); newTimeGeometry->SetFirstTimePoint(firstTimePoint); newTimeGeometry->SetStepDuration(stepDuration); newTimeGeometry->ReserveSpaceForGeometries(allReadGeometries.size()); TimeStepType t(0); for (auto entry : allReadGeometries) { // We add items with newly assigned time steps. // This avoids great confusion when a file contains // bogus numbers. newTimeGeometry->SetTimeStepGeometry(entry.second, t++); } // Need to re-calculate global bounding box. // This is neither stored in a file, nor done by SetTimeStepGeometry newTimeGeometry->UpdateBoundingBox(); return newTimeGeometry; } diff --git a/Modules/SceneSerializationBase/src/mitkLookupTablePropertySerializer.cpp b/Modules/SceneSerializationBase/src/mitkLookupTablePropertySerializer.cpp index 559b6e12bc..3f82689963 100644 --- a/Modules/SceneSerializationBase/src/mitkLookupTablePropertySerializer.cpp +++ b/Modules/SceneSerializationBase/src/mitkLookupTablePropertySerializer.cpp @@ -1,227 +1,227 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkLookupTablePropertySerializer.h" #include "mitkStringsToNumbers.h" #include #include #include #include tinyxml2::XMLElement *mitk::LookupTablePropertySerializer::Serialize(tinyxml2::XMLDocument& doc) { if (const auto *prop = dynamic_cast(m_Property.GetPointer())) { LocaleSwitch localeSwitch("C"); LookupTable::Pointer mitkLut = const_cast(prop)->GetLookupTable(); if (mitkLut.IsNull()) return nullptr; // really? vtkLookupTable *lut = mitkLut->GetVtkLookupTable(); if (!lut) return nullptr; auto *element = doc.NewElement("LookupTable"); double *range; double *rgba; - element->SetAttribute("NumberOfColors", lut->GetNumberOfTableValues()); + element->SetAttribute("NumberOfColors", static_cast(lut->GetNumberOfTableValues())); element->SetAttribute("Scale", lut->GetScale()); element->SetAttribute("Ramp", lut->GetRamp()); range = lut->GetHueRange(); auto *child = doc.NewElement("HueRange"); element->InsertEndChild(child); child->SetAttribute("min", boost::lexical_cast(range[0]).c_str()); child->SetAttribute("max", boost::lexical_cast(range[1]).c_str()); range = lut->GetValueRange(); child = doc.NewElement("ValueRange"); element->InsertEndChild(child); child->SetAttribute("min", boost::lexical_cast(range[0]).c_str()); child->SetAttribute("max", boost::lexical_cast(range[1]).c_str()); range = lut->GetSaturationRange(); child = doc.NewElement("SaturationRange"); element->InsertEndChild(child); child->SetAttribute("min", boost::lexical_cast(range[0]).c_str()); child->SetAttribute("max", boost::lexical_cast(range[1]).c_str()); range = lut->GetAlphaRange(); child = doc.NewElement("AlphaRange"); element->InsertEndChild(child); child->SetAttribute("min", boost::lexical_cast(range[0]).c_str()); child->SetAttribute("max", boost::lexical_cast(range[1]).c_str()); range = lut->GetTableRange(); child = doc.NewElement("TableRange"); element->InsertEndChild(child); child->SetAttribute("min", boost::lexical_cast(range[0]).c_str()); child->SetAttribute("max", boost::lexical_cast(range[1]).c_str()); child = doc.NewElement("Table"); element->InsertEndChild(child); for (int index = 0; index < lut->GetNumberOfTableValues(); ++index) { auto grandChild = doc.NewElement("RgbaColor"); rgba = lut->GetTableValue(index); grandChild->SetAttribute("R", boost::lexical_cast(rgba[0]).c_str()); grandChild->SetAttribute("G", boost::lexical_cast(rgba[1]).c_str()); grandChild->SetAttribute("B", boost::lexical_cast(rgba[2]).c_str()); grandChild->SetAttribute("A", boost::lexical_cast(rgba[3]).c_str()); child->InsertEndChild(grandChild); } return element; } else return nullptr; } mitk::BaseProperty::Pointer mitk::LookupTablePropertySerializer::Deserialize(const tinyxml2::XMLElement *element) { if (!element) return nullptr; LocaleSwitch localeSwitch("C"); double range[2]; double rgba[4]; std::array double_strings; vtkSmartPointer lut = vtkSmartPointer::New(); int numberOfColors; int scale; int ramp; // hope the int values don't change betw. vtk versions... if (element->QueryIntAttribute("NumberOfColors", &numberOfColors) == tinyxml2::XML_SUCCESS) { lut->SetNumberOfTableValues(numberOfColors); } else return nullptr; if (element->QueryIntAttribute("Scale", &scale) == tinyxml2::XML_SUCCESS) { lut->SetScale(scale); } else return nullptr; if (element->QueryIntAttribute("Ramp", &ramp) == tinyxml2::XML_SUCCESS) { lut->SetRamp(ramp); } else return nullptr; try { auto *child = element->FirstChildElement("HueRange"); if (child) { double_strings[0] = child->Attribute("min"); double_strings[1] = child->Attribute("max"); if (nullptr == double_strings[0] || nullptr == double_strings[1]) return nullptr; StringsToNumbers(2, double_strings, range); lut->SetHueRange(range); } child = element->FirstChildElement("ValueRange"); if (child) { double_strings[0] = child->Attribute("min"); double_strings[1] = child->Attribute("max"); if (nullptr == double_strings[0] || nullptr == double_strings[1]) return nullptr; StringsToNumbers(2, double_strings, range); lut->SetValueRange(range); } child = element->FirstChildElement("SaturationRange"); if (child) { double_strings[0] = child->Attribute("min"); double_strings[1] = child->Attribute("max"); if (nullptr == double_strings[0] || nullptr == double_strings[1]) return nullptr; StringsToNumbers(2, double_strings, range); lut->SetSaturationRange(range); } child = element->FirstChildElement("AlphaRange"); if (child) { double_strings[0] = child->Attribute("min"); double_strings[1] = child->Attribute("max"); if (nullptr == double_strings[0] || nullptr == double_strings[1]) return nullptr; StringsToNumbers(2, double_strings, range); lut->SetAlphaRange(range); } child = element->FirstChildElement("TableRange"); if (child) { double_strings[0] = child->Attribute("min"); double_strings[1] = child->Attribute("max"); if (nullptr == double_strings[0] || nullptr == double_strings[1]) return nullptr; StringsToNumbers(2, double_strings, range); lut->SetTableRange(range); } child = element->FirstChildElement("Table"); if (child) { unsigned int index(0); for (auto *grandChild = child->FirstChildElement("RgbaColor"); grandChild; grandChild = grandChild->NextSiblingElement("RgbaColor")) { double_strings[0] = grandChild->Attribute("R"); double_strings[1] = grandChild->Attribute("G"); double_strings[2] = grandChild->Attribute("B"); double_strings[3] = grandChild->Attribute("A"); if (nullptr == double_strings[0] || nullptr == double_strings[1] || nullptr == double_strings[2] || nullptr == double_strings[3]) return nullptr; StringsToNumbers(4, double_strings, rgba); lut->SetTableValue(index, rgba); ++index; } } } catch (boost::bad_lexical_cast &e) { MITK_ERROR << "Could not parse string as number: " << e.what(); return nullptr; } LookupTable::Pointer mitkLut = LookupTable::New(); mitkLut->SetVtkLookupTable(lut); return LookupTableProperty::New(mitkLut).GetPointer(); }