예제 #1
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();
    }
}
예제 #2
0
bool
RenderingManager
::InitializeViews( const Geometry3D * dataGeometry, RequestType type, bool preserveRoughOrientationInWorldSpace )
{
    MITK_DEBUG << "initializing views";

    bool boundingBoxInitialized = false;

    Geometry3D::ConstPointer geometry = dataGeometry;

    if (dataGeometry && preserveRoughOrientationInWorldSpace)
    {

        // clone the input geometry
        Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
        assert(modifiedGeometry.IsNotNull());

        // construct an affine transform from it
        AffineGeometryFrame3D::TransformType::Pointer transform = AffineGeometryFrame3D::TransformType::New();
        assert( modifiedGeometry->GetIndexToWorldTransform() );
        transform->SetMatrix( modifiedGeometry->GetIndexToWorldTransform()->GetMatrix() );
        transform->SetOffset( modifiedGeometry->GetIndexToWorldTransform()->GetOffset() );

        // get transform matrix
        AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& oldMatrix =
            const_cast< AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType& > ( transform->GetMatrix().GetVnlMatrix() );
        AffineGeometryFrame3D::TransformType::MatrixType::InternalMatrixType newMatrix(oldMatrix);

        // get offset and bound
        Vector3D offset = modifiedGeometry->GetIndexToWorldTransform()->GetOffset();
        Geometry3D::BoundsArrayType oldBounds = modifiedGeometry->GetBounds();
        Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds();

        // get rid of rotation other than pi/2 degree
        for ( unsigned int i = 0; i < 3; ++i )
        {

            // i-th column of the direction matrix
            Vector3D currentVector;
            currentVector[0] = oldMatrix(0,i);
            currentVector[1] = oldMatrix(1,i);
            currentVector[2] = oldMatrix(2,i);

            // matchingRow will store the row that holds the biggest
            // value in the column
            unsigned int matchingRow = 0;

            // maximum value in the column
            float max = std::numeric_limits<float>::min();

            // sign of the maximum value (-1 or 1)
            int sign = 1;

            // iterate through the column vector
            for (unsigned int dim = 0; dim < 3; ++dim)
            {
                if ( fabs(currentVector[dim]) > max )
                {
                    matchingRow = dim;
                    max = fabs(currentVector[dim]);
                    if(currentVector[dim]<0)
                        sign = -1;
                    else
                        sign = 1;
                }
            }

            // in case we found a negative maximum,
            // we negate the column and adjust the offset
            // (in order to run through the dimension in the opposite direction)
            if(sign == -1)
            {
                currentVector *= sign;
                offset += modifiedGeometry->GetAxisVector(i);
            }


            // matchingRow is now used as column index to place currentVector
            // correctly in the new matrix
            vnl_vector<ScalarType> newMatrixColumn(3);
            newMatrixColumn[0] = currentVector[0];
            newMatrixColumn[1] = currentVector[1];
            newMatrixColumn[2] = currentVector[2];
            newMatrix.set_column( matchingRow, newMatrixColumn );

            // if a column is moved, we also have to adjust the bounding
            // box accordingly, this is done here
            newBounds[2*matchingRow  ] = oldBounds[2*i  ];
            newBounds[2*matchingRow+1] = oldBounds[2*i+1];
        }

        // set the newly calculated bounds array
        modifiedGeometry->SetBounds(newBounds);

        // set new offset and direction matrix
        AffineGeometryFrame3D::TransformType::MatrixType newMatrixITK( newMatrix );
        transform->SetMatrix( newMatrixITK );
        transform->SetOffset( offset );
        modifiedGeometry->SetIndexToWorldTransform( transform );
        geometry = modifiedGeometry;

    }

    int warningLevel = vtkObject::GetGlobalWarningDisplay();
    vtkObject::GlobalWarningDisplayOff();

    if ( (geometry.IsNotNull() ) && (const_cast< mitk::BoundingBox * >(
                                         geometry->GetBoundingBox())->GetDiagonalLength2() > mitk::eps) )
    {
        boundingBoxInitialized = true;
    }

    if (geometry.IsNotNull() )
    {   // make sure bounding box has an extent bigger than zero in any direction
        // clone the input geometry
        Geometry3D::Pointer modifiedGeometry = dynamic_cast<Geometry3D*>( dataGeometry->Clone().GetPointer() );
        assert(modifiedGeometry.IsNotNull());
        Geometry3D::BoundsArrayType newBounds = modifiedGeometry->GetBounds();
        for( unsigned int dimension = 0; ( 2 * dimension ) < newBounds.Size() ; dimension++ )
        {
            //check for equality but for an epsilon
            if( Equal( newBounds[ 2 * dimension ], newBounds[ 2 * dimension + 1 ] ) )
            {
                newBounds[ 2 * dimension + 1 ] += 1;
            }
        }

        // set the newly calculated bounds array
        modifiedGeometry->SetBounds(newBounds);

        geometry = modifiedGeometry;
    }

    RenderWindowList::iterator it;
    for ( it = m_RenderWindowList.begin(); it != m_RenderWindowList.end(); ++it )
    {
        mitk::BaseRenderer *baseRenderer =
            mitk::BaseRenderer::GetInstance( it->first );

        baseRenderer->GetDisplayGeometry()->SetConstrainZoomingAndPanning(m_ConstrainedPaddingZooming);

        int id = baseRenderer->GetMapperID();
        if ( ((type == REQUEST_UPDATE_ALL)
                || ((type == REQUEST_UPDATE_2DWINDOWS) && (id == 1))
                || ((type == REQUEST_UPDATE_3DWINDOWS) && (id == 2)))
           )
        {
            this->InternalViewInitialization( baseRenderer, geometry,
                                              boundingBoxInitialized, id );
        }
    }

    if ( m_TimeNavigationController != NULL )
    {
        if ( boundingBoxInitialized )
        {
            m_TimeNavigationController->SetInputWorldGeometry( geometry );
        }
        m_TimeNavigationController->Update();
    }

    this->RequestUpdateAll( type );

    vtkObject::SetGlobalWarningDisplay( warningLevel );

    // Inform listeners that views have been initialized
    this->InvokeEvent( mitk::RenderingManagerViewsInitializedEvent() );


    return boundingBoxInitialized;
}
예제 #3
0
mitk::Geometry3D::Pointer mitk::Geometry3DToXML::FromXML( TiXmlElement* geometryElement )
{
  if (!geometryElement)
  {
    MITK_ERROR << "Cannot deserialize Geometry3D from nullptr.";
    return nullptr;
  }

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

  if ( TIXML_SUCCESS != geometryElement->QueryUnsignedAttribute("FrameOfReferenceID", &frameOfReferenceID) )
  {
    MITK_WARN << "Missing FrameOfReference for Geometry3D.";
  }

  if ( TIXML_SUCCESS != geometryElement->QueryBoolAttribute("ImageGeometry", &isImageGeometry) )
  {
    MITK_WARN << "Missing bool ImageGeometry for Geometry3D.";
  }

  // matrix
  if ( TiXmlElement* matrixElem = geometryElement->FirstChildElement("IndexToWorld")->ToElement() )
  {
    bool matrixComplete = true;
    for ( unsigned int r = 0; r < 3; ++r )
    {
      for ( unsigned int c = 0; c < 3; ++c )
      {
        std::stringstream element_namer;
        element_namer << "m_" << r << "_" << c;

        std::string string_value;
        if (TIXML_SUCCESS == matrixElem->QueryStringAttribute(element_namer.str().c_str(),
                                                              &string_value))
        {
          try
          {
            matrix[r][c] = boost::lexical_cast<double>(string_value);
          }
          catch (boost::bad_lexical_cast& e)
          {
            MITK_ERROR << "Could not parse '" << string_value << "' as number: " << e.what();
            return nullptr;
          }
        }
        else
        {
          matrixComplete = false;
        }
      }
    }

    if ( !matrixComplete )
    {
      MITK_ERROR << "Could not parse all Geometry3D matrix coefficients!";
      return nullptr;
    }
  } else
  {
    MITK_ERROR << "Parse error: expected Matrix3x3 child below Geometry3D node";
    return nullptr;
  }

  // offset
  if ( TiXmlElement* offsetElem = geometryElement->FirstChildElement("Offset")->ToElement() )
  {
    bool vectorComplete = true;
    std::string offset_string[3];
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("x", &offset_string[0]);
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("y", &offset_string[1]);
    vectorComplete &= TIXML_SUCCESS == offsetElem->QueryStringAttribute("z", &offset_string[2]);

    if ( !vectorComplete )
    {
      MITK_ERROR << "Could not parse complete Geometry3D offset!";
      return nullptr;
    }

    for ( unsigned int d = 0; d < 3; ++d )
      try
      {
        offset[d] = boost::lexical_cast<double>(offset_string[d]);
      }
      catch ( boost::bad_lexical_cast& e )
      {
        MITK_ERROR << "Could not parse '" << offset_string[d] << "' as number: " << e.what();
        return nullptr;
      }
  }
  else
  {
    MITK_ERROR << "Parse error: expected Offset3D child below Geometry3D node";
    return nullptr;
  }

  // bounds
  if ( TiXmlElement* boundsElem = geometryElement->FirstChildElement("Bounds")->ToElement() )
  {
    bool vectorsComplete(true);
    std::string bounds_string[6];
    if ( TiXmlElement* minElem = boundsElem->FirstChildElement("Min")->ToElement() )
    {
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("x", &bounds_string[0]);
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("y", &bounds_string[2]);
      vectorsComplete &= TIXML_SUCCESS == minElem->QueryStringAttribute("z", &bounds_string[4]);
    } else
    {
      vectorsComplete = false;
    }

    if ( TiXmlElement* maxElem = boundsElem->FirstChildElement("Max")->ToElement() )
    {
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("x", &bounds_string[1]);
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("y", &bounds_string[3]);
      vectorsComplete &= TIXML_SUCCESS == maxElem->QueryStringAttribute("z", &bounds_string[5]);
    } else
    {
      vectorsComplete = false;
    }

    if ( !vectorsComplete )
    {
      MITK_ERROR << "Could not parse complete Geometry3D bounds!";
      return nullptr;
    }

    for (unsigned int d = 0; d < 6; ++d)
      try
      {
        bounds[d] = boost::lexical_cast<double>(bounds_string[d]);
      }
      catch (boost::bad_lexical_cast& e)
      {
        MITK_ERROR << "Could not parse '" << bounds_string[d] << "' as number: " << e.what();
        return nullptr;
      }
}

  // build GeometryData from matrix/offset
  AffineTransform3D::Pointer newTransform = AffineTransform3D::New();
  newTransform->SetMatrix(matrix);
  newTransform->SetOffset(offset);

  Geometry3D::Pointer newGeometry = Geometry3D::New();
  newGeometry->SetFrameOfReferenceID(frameOfReferenceID);
  newGeometry->SetImageGeometry(isImageGeometry);

  newGeometry->SetIndexToWorldTransform(newTransform);

  newGeometry->SetBounds(bounds);

  return newGeometry;
}