mitk::ProportionalTimeGeometry::Pointer mitk::ProportionalTimeGeometryToXML::FromXML(TiXmlElement *timeGeometryElement)
{
  if (!timeGeometryElement)
  {
    MITK_ERROR << "Cannot deserialize ProportionalTimeGeometry from nullptr.";
    return nullptr;
  }

  int numberOfTimeSteps = 0;

  if (TIXML_SUCCESS != timeGeometryElement->QueryIntAttribute("NumberOfTimeSteps", &numberOfTimeSteps))
  {
    MITK_WARN << "<ProportionalTimeGeometry> found without NumberOfTimeSteps attribute. Counting...";
  }

  // might be missing!
  TimePointType firstTimePoint;
  std::string firstTimePoint_s;
  TimePointType stepDuration;
  std::string stepDuration_s;
  try
  {
    if (TIXML_SUCCESS == timeGeometryElement->QueryStringAttribute("FirstTimePoint", &firstTimePoint_s))
    {
      firstTimePoint = boost::lexical_cast<double>(firstTimePoint_s);
    }
    else
    {
      firstTimePoint = -std::numeric_limits<TimePointType>::max();
    }

    if (TIXML_SUCCESS == timeGeometryElement->QueryStringAttribute("StepDuration", &stepDuration_s))
    {
      stepDuration = boost::lexical_cast<double>(stepDuration_s);
    }
    else
    {
      stepDuration = std::numeric_limits<TimePointType>::infinity();
    }
  }
  catch (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<TimeStepType, BaseGeometry::Pointer> allReadGeometries;

  int indexForUnlabeledTimeStep(-1);
  for (TiXmlElement *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 (TIXML_SUCCESS != currentElement->QueryIntAttribute("TimeStep", &timeStep))
        {
          timeStep = indexForUnlabeledTimeStep--; // decrement index for next one
          MITK_WARN << "Found <Geometry3D> without 'TimeStep' attribute in <ProportionalTimeGeometry>. No guarantees "
                       "on order anymore.";
        }

        if (allReadGeometries.count(static_cast<TimeStepType>(timeStep)) > 0)
        {
          MITK_WARN << "Found <Geometry3D> tags with identical 'TimeStep' attribute in <ProportionalTimeGeometry>. No "
                       "guarantees on order anymore.";
        }

        allReadGeometries.insert(std::make_pair(static_cast<TimeStepType>(timeStep), restoredGeometry.GetPointer()));
      }
    }
    else
    {
      MITK_WARN << "Found unsupported tag <" << tagName << "> inside <ProportionalTimeGeometry>. 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;
}
Example #2
0
mitk::BaseGeometry::Pointer mitk::PointSetReaderService::ReadGeometry(TiXmlElement *parentElement)
{
    TiXmlElement *geometryElem = parentElement->FirstChildElement("geometry3d");
    if (!geometryElem)
        return nullptr;

    // data to generate
    AffineTransform3D::MatrixType matrix;
    AffineTransform3D::OffsetType offset;
    bool isImageGeometry(false);
    unsigned int frameOfReferenceID(0);
    BaseGeometry::BoundsArrayType bounds;

    bool somethingMissing(false);

    // find data in xml structure
    TiXmlElement *imageGeometryElem = geometryElem->FirstChildElement("image_geometry");
    if (imageGeometryElem)
    {
        std::string igs = imageGeometryElem->GetText();
        isImageGeometry = igs == "true" || igs == "TRUE" || igs == "1";
    }
    else
        somethingMissing = true;

    TiXmlElement *frameOfReferenceElem = geometryElem->FirstChildElement("frame_of_reference_id");
    if (frameOfReferenceElem)
    {
        frameOfReferenceID = atoi(frameOfReferenceElem->GetText());
    }
    else
        somethingMissing = true;

    TiXmlElement *indexToWorldElem = geometryElem->FirstChildElement("index_to_world");
    if (indexToWorldElem)
    {
        TiXmlElement *matrixElem = indexToWorldElem->FirstChildElement("matrix3x3");
        TiXmlElement *offsetElem = indexToWorldElem->FirstChildElement("offset");
        if (indexToWorldElem && offsetElem)
        {
            TiXmlElement *col0 = matrixElem->FirstChildElement("column_0");
            TiXmlElement *col1 = matrixElem->FirstChildElement("column_1");
            TiXmlElement *col2 = matrixElem->FirstChildElement("column_2");

            if (col0 && col1 && col2)
            {
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("x", &matrix[0][0]);
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("y", &matrix[1][0]);
                somethingMissing |= TIXML_SUCCESS != col0->QueryDoubleAttribute("z", &matrix[2][0]);

                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("x", &matrix[0][1]);
                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("y", &matrix[1][1]);
                somethingMissing |= TIXML_SUCCESS != col1->QueryDoubleAttribute("z", &matrix[2][1]);

                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("x", &matrix[0][2]);
                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("y", &matrix[1][2]);
                somethingMissing |= TIXML_SUCCESS != col2->QueryDoubleAttribute("z", &matrix[2][2]);
            }
            else
                somethingMissing = true;

            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("x", &offset[0]);
            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("y", &offset[1]);
            somethingMissing |= TIXML_SUCCESS != offsetElem->QueryDoubleAttribute("z", &offset[2]);
        }
        else
            somethingMissing = true;

        TiXmlElement *boundsElem = geometryElem->FirstChildElement("bounds");
        if (boundsElem)
        {
            TiXmlElement *minBoundsElem = boundsElem->FirstChildElement("min");
            TiXmlElement *maxBoundsElem = boundsElem->FirstChildElement("max");

            if (minBoundsElem && maxBoundsElem)
            {
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("x", &bounds[0]);
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("y", &bounds[2]);
                somethingMissing |= TIXML_SUCCESS != minBoundsElem->QueryDoubleAttribute("z", &bounds[4]);

                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("x", &bounds[1]);
                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("y", &bounds[3]);
                somethingMissing |= TIXML_SUCCESS != maxBoundsElem->QueryDoubleAttribute("z", &bounds[5]);
            }
            else
                somethingMissing = true;
        }
        else
            somethingMissing = true;
    }
    else
        somethingMissing = true;

    if (somethingMissing)
    {
        MITK_ERROR << "XML structure of geometry inside a PointSet file broken. Refusing to build Geometry3D";
        return nullptr;
    }
    else
    {
        Geometry3D::Pointer g = Geometry3D::New();
        g->SetImageGeometry(isImageGeometry);
        g->SetFrameOfReferenceID(frameOfReferenceID);
        g->SetBounds(bounds);

        AffineTransform3D::Pointer transform = AffineTransform3D::New();
        transform->SetMatrix(matrix);
        transform->SetOffset(offset);

        g->SetIndexToWorldTransform(transform);

        return g.GetPointer();
    }
}