Example #1
0
bool
PlaneGeometry::IntersectionLine(
  const PlaneGeometry* plane, Line3D& crossline ) const
{
  Vector3D normal = this->GetNormal();
  normal.Normalize();

  Vector3D planeNormal = plane->GetNormal();
  planeNormal.Normalize();

  Vector3D direction = itk::CrossProduct( normal, planeNormal );

  if ( direction.GetSquaredNorm() < eps )
    return false;

  crossline.SetDirection( direction );

  double N1dN2 = normal * planeNormal;
  double determinant = 1.0 - N1dN2 * N1dN2;

  Vector3D origin = this->GetOrigin().GetVectorFromOrigin();
  Vector3D planeOrigin = plane->GetOrigin().GetVectorFromOrigin();

  double d1 = normal * origin;
  double d2 = planeNormal * planeOrigin;

  double c1 = ( d1 - d2 * N1dN2 ) / determinant;
  double c2 = ( d2 - d1 * N1dN2 ) / determinant;

  Vector3D p = normal * c1 + planeNormal * c2;
  crossline.GetPoint().GetVnlVector() = p.GetVnlVector();

  return true;
}
Example #2
0
mitk::Vector3D
  mitk::SlicedGeometry3D::AdjustNormal( const mitk::Vector3D &normal ) const
{
  TransformType::Pointer inverse = TransformType::New();
  m_ReferenceGeometry->GetIndexToWorldTransform()->GetInverse( inverse );

  Vector3D transformedNormal = inverse->TransformVector( normal );

  transformedNormal.Normalize();
  return transformedNormal;
}
Example #3
0
void
  mitk::SlicedGeometry3D
  ::SetDirectionVector( const mitk::Vector3D& directionVector )
{
  Vector3D newDir = directionVector;
  newDir.Normalize();
  if ( newDir != m_DirectionVector )
  {
    m_DirectionVector = newDir;
    this->Modified();
  }
}
Example #4
0
bool PlaneGeometry::IntersectionPoint(
  const Line3D &line, Point3D &intersectionPoint ) const
{
  Vector3D planeNormal = this->GetNormal();
  planeNormal.Normalize();

  Vector3D lineDirection = line.GetDirection();
  lineDirection.Normalize();

  double t = planeNormal * lineDirection;
  if ( fabs( t ) < eps )
  {
    return false;
  }

  Vector3D diff;
  diff = this->GetOrigin() - line.GetPoint();
  t = ( planeNormal * diff ) / t;

  intersectionPoint = line.GetPoint() + lineDirection * t;
  return true;
}
void mitk::ClippingPlaneInteractor3D::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
    InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
    if(positionEvent == NULL)
        return;

    double currentWorldPoint[4];
    Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
    vtkInteractorObserver::ComputeDisplayToWorld(
        interactionEvent->GetSender()->GetVtkRenderer(),
        currentPickedDisplayPoint[0],
        currentPickedDisplayPoint[1],
        0.0, //m_InitialInteractionPickedPoint[2],
        currentWorldPoint);

    vtkCamera* camera = NULL;
    vtkRenderer* currentVtkRenderer = NULL;

    if ((interactionEvent->GetSender()) != NULL)
    {
        vtkRenderWindow* renderWindow = interactionEvent->GetSender()->GetRenderWindow();
        if (renderWindow != NULL)
        {
            vtkRenderWindowInteractor* renderWindowInteractor = renderWindow->GetInteractor();
            if ( renderWindowInteractor != NULL )
            {
                currentVtkRenderer = renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer();
                if (currentVtkRenderer != NULL)
                    camera = currentVtkRenderer->GetActiveCamera();
            }
        }
    }
    if ( camera )
    {
        double vpn[3];
        camera->GetViewPlaneNormal( vpn );

        Vector3D viewPlaneNormal;
        viewPlaneNormal[0] = vpn[0];
        viewPlaneNormal[1] = vpn[1];
        viewPlaneNormal[2] = vpn[2];

        Vector3D interactionMove;
        interactionMove[0] = currentWorldPoint[0] - m_InitialPickedWorldPoint[0];
        interactionMove[1] = currentWorldPoint[1] - m_InitialPickedWorldPoint[1];
        interactionMove[2] = currentWorldPoint[2] - m_InitialPickedWorldPoint[2];

        if (interactionMove[0] == 0 && interactionMove[1] == 0  && interactionMove[2] == 0)
            return;

        Vector3D rotationAxis = itk::CrossProduct(viewPlaneNormal, interactionMove);
        rotationAxis.Normalize();

        int* size = currentVtkRenderer->GetSize();
        double l2 =
            (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) *
            (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) +
            (currentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) *
            (currentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]);

        double rotationAngle = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1]));

        // Use center of data bounding box as center of rotation
        Point3D rotationCenter = m_OriginalGeometry->GetCenter();

        int timeStep = 0;
        if ((interactionEvent->GetSender()) != NULL)
            timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData());

        // Reset current Geometry3D to original state (pre-interaction) and
        // apply rotation
        RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle );
        Geometry3D::Pointer newGeometry = static_cast<Geometry3D*>(m_OriginalGeometry->Clone().GetPointer());
        newGeometry->ExecuteOperation( &op );
        mitk::TimeGeometry::Pointer timeGeometry = this->GetDataNode()->GetData()->GetTimeGeometry();
        if (timeGeometry.IsNotNull())
            timeGeometry->SetTimeStepGeometry(newGeometry, timeStep);

        interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
    }
}
//-------------------------------------------------------------
//- GetMeshPointFromSecondTexCoord
//- Get real vertex position and normal from mesh according to TexCoord1
//-------------------------------------------------------------
bool CSGPModelMF1::GetMeshPointFromSecondTexCoord( Vector3D& position, Vector3D& normal, const Vector2D& uv, const Matrix4x4& modelMatrix  )
{
	for( uint32 i=0; i<m_Header.m_iNumMeshes; i++ )
	{
		if( !m_pLOD0Meshes[i].m_pTexCoords1 || (m_pLOD0Meshes[i].m_iNumUV1==0) )
			continue;

		jassert( m_pLOD0Meshes[i].m_iNumUV0 == m_pLOD0Meshes[i].m_iNumUV1 );


		for( uint32 j=0; j<m_pLOD0Meshes[i].m_iNumIndices; j += 3 )
		{
			Vector3D v0(
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vPos[0],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vPos[1],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vPos[2] );
			Vector3D v1(
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vPos[0],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vPos[1],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vPos[2] );
			Vector3D v2(
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vPos[0],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vPos[1],
				m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vPos[2] );

			v0 = v0 * modelMatrix;
			v1 = v1 * modelMatrix;
			v2 = v2 * modelMatrix;

			Vector2D t0(m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].m_fTexCoord[0],
						m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].m_fTexCoord[1]	);
			Vector2D t1(m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].m_fTexCoord[0],
						m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].m_fTexCoord[1]	);
			Vector2D t2(m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].m_fTexCoord[0],
						m_pLOD0Meshes[i].m_pTexCoords1[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].m_fTexCoord[1]	);

			Vector3D samplePos = TexcoordToPos( v0, v1, v2, t0, t1, t2, uv );
			if( !IsPointInsideTriangle(v0, v1, v2, samplePos, 0.1f) )
				continue;
			else
			{
				Vector4D n0(
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vNormal[0],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vNormal[1],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j  ]  ].vNormal[2],
					0);
				Vector4D n1(
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vNormal[0],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vNormal[1],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+1]  ].vNormal[2],
					0);
				Vector4D n2(
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vNormal[0],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vNormal[1],
					m_pLOD0Meshes[i].m_pVertex[  m_pLOD0Meshes[i].m_pIndices[j+2]  ].vNormal[2],
					0);


				n0 = n0 * modelMatrix;
				n1 = n1 * modelMatrix;
				n2 = n2 * modelMatrix;

				Vector3D nn0(n0.x, n0.y, n0.z);
				Vector3D nn1(n1.x, n1.y, n1.z);
				Vector3D nn2(n2.x, n2.y, n2.z);
				nn0.Normalize();
				nn1.Normalize();
				nn2.Normalize();

				normal = TexcoordToPos( nn0, nn1, nn2, t0, t1, t2, uv );
				normal.Normalize();
				position = samplePos;

				return true;
			}
		}
	}
	return false;
}
void mitk::ExtractDirectedPlaneImageFilterNew::ItkSliceExtraction(const itk::Image<TPixel, VImageDimension> *inputImage)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef itk::Image<TPixel, VImageDimension - 1> SliceImageType;

  typedef itk::ImageRegionConstIterator<SliceImageType> SliceIterator;

  // Creating an itk::Image that represents the sampled slice
  typename SliceImageType::Pointer resultSlice = SliceImageType::New();

  typename SliceImageType::IndexType start;

  start[0] = 0;
  start[1] = 0;

  Point3D origin = m_CurrentWorldPlaneGeometry->GetOrigin();
  Vector3D right = m_CurrentWorldPlaneGeometry->GetAxisVector(0);
  Vector3D bottom = m_CurrentWorldPlaneGeometry->GetAxisVector(1);

  // Calculation the sample-spacing, i.e the half of the smallest spacing existing in the original image
  Vector3D newPixelSpacing = m_ImageGeometry->GetSpacing();
  float minSpacing = newPixelSpacing[0];
  for (unsigned int i = 1; i < newPixelSpacing.Size(); i++)
  {
    if (newPixelSpacing[i] < minSpacing)
    {
      minSpacing = newPixelSpacing[i];
    }
  }

  newPixelSpacing[0] = 0.5 * minSpacing;
  newPixelSpacing[1] = 0.5 * minSpacing;
  newPixelSpacing[2] = 0.5 * minSpacing;

  float pixelSpacing[2];
  pixelSpacing[0] = newPixelSpacing[0];
  pixelSpacing[1] = newPixelSpacing[1];

  // Calculating the size of the sampled slice
  typename SliceImageType::SizeType size;
  Vector2D extentInMM;
  extentInMM[0] = m_CurrentWorldPlaneGeometry->GetExtentInMM(0);
  extentInMM[1] = m_CurrentWorldPlaneGeometry->GetExtentInMM(1);

  // The maximum extent is the lenght of the diagonal of the considered plane
  double maxExtent = sqrt(extentInMM[0] * extentInMM[0] + extentInMM[1] * extentInMM[1]);
  unsigned int xTranlation = (maxExtent - extentInMM[0]);
  unsigned int yTranlation = (maxExtent - extentInMM[1]);
  size[0] = (maxExtent + xTranlation) / newPixelSpacing[0];
  size[1] = (maxExtent + yTranlation) / newPixelSpacing[1];

  // Creating an ImageRegion Object
  typename SliceImageType::RegionType region;

  region.SetSize(size);
  region.SetIndex(start);

  // Defining the image`s extent and origin by passing the region to it and allocating memory for it
  resultSlice->SetRegions(region);
  resultSlice->SetSpacing(pixelSpacing);
  resultSlice->Allocate();

  /*
  * Here we create an new geometry so that the transformations are calculated correctly (our resulting slice has a
  * different bounding box and spacing)
  * The original current worldgeometry must be cloned because we have to keep the directions of the axis vector which
  * represents the rotation
  */
  right.Normalize();
  bottom.Normalize();
  // Here we translate the origin to adapt the new geometry to the previous calculated extent
  origin[0] -= xTranlation * right[0] + yTranlation * bottom[0];
  origin[1] -= xTranlation * right[1] + yTranlation * bottom[1];
  origin[2] -= xTranlation * right[2] + yTranlation * bottom[2];

  // Putting it together for the new geometry
  mitk::BaseGeometry::Pointer newSliceGeometryTest =
    dynamic_cast<BaseGeometry *>(m_CurrentWorldPlaneGeometry->Clone().GetPointer());
  newSliceGeometryTest->ChangeImageGeometryConsideringOriginOffset(true);

  // Workaround because of BUG (#6505)
  newSliceGeometryTest->GetIndexToWorldTransform()->SetMatrix(
    m_CurrentWorldPlaneGeometry->GetIndexToWorldTransform()->GetMatrix());
  // Workaround end

  newSliceGeometryTest->SetOrigin(origin);
  ScalarType bounds[6] = {0, static_cast<ScalarType>(size[0]), 0, static_cast<ScalarType>(size[1]), 0, 1};
  newSliceGeometryTest->SetBounds(bounds);
  newSliceGeometryTest->SetSpacing(newPixelSpacing);
  newSliceGeometryTest->Modified();

  // Workaround because of BUG (#6505)
  itk::MatrixOffsetTransformBase<mitk::ScalarType, 3, 3>::MatrixType tempTransform =
    newSliceGeometryTest->GetIndexToWorldTransform()->GetMatrix();
  // Workaround end

  /*
  * Now we iterate over the recently created slice.
  * For each slice - pixel we check whether there is an according
  * pixel in the input - image which can be set in the slice.
  * In this way a slice is sampled out of the input - image regrading to the given PlaneGeometry
  */
  Point3D currentSliceIndexPointIn2D;
  Point3D currentImageWorldPointIn3D;
  typename InputImageType::IndexType inputIndex;

  SliceIterator sliceIterator(resultSlice, resultSlice->GetLargestPossibleRegion());
  sliceIterator.GoToBegin();

  while (!sliceIterator.IsAtEnd())
  {
    /*
    * Here we add 0.5 to to assure that the indices are correctly transformed.
    * (Because of the 0.5er Bug)
    */
    currentSliceIndexPointIn2D[0] = sliceIterator.GetIndex()[0] + 0.5;
    currentSliceIndexPointIn2D[1] = sliceIterator.GetIndex()[1] + 0.5;
    currentSliceIndexPointIn2D[2] = 0;

    newSliceGeometryTest->IndexToWorld(currentSliceIndexPointIn2D, currentImageWorldPointIn3D);

    m_ImageGeometry->WorldToIndex(currentImageWorldPointIn3D, inputIndex);

    if (m_ImageGeometry->IsIndexInside(inputIndex))
    {
      resultSlice->SetPixel(sliceIterator.GetIndex(), inputImage->GetPixel(inputIndex));
    }
    else
    {
      resultSlice->SetPixel(sliceIterator.GetIndex(), 0);
    }

    ++sliceIterator;
  }

  Image::Pointer resultImage = ImageToImageFilter::GetOutput();
  GrabItkImageMemory(resultSlice, resultImage, nullptr, false);
  resultImage->SetClonedGeometry(newSliceGeometryTest);
  // Workaround because of BUG (#6505)
  resultImage->GetGeometry()->GetIndexToWorldTransform()->SetMatrix(tempTransform);
  // Workaround end
}
Example #8
0
void
  mitk::SlicedGeometry3D::InitializeEvenlySpaced(
  mitk::PlaneGeometry* geometry2D, mitk::ScalarType zSpacing,
  unsigned int slices, bool flipped )
{
  assert( geometry2D != nullptr );
  assert( geometry2D->GetExtent(0) > 0 );
  assert( geometry2D->GetExtent(1) > 0 );

  geometry2D->Register();

  Superclass::Initialize();
  m_Slices = slices;

  BoundingBox::BoundsArrayType bounds = geometry2D->GetBounds();
  bounds[4] = 0;
  bounds[5] = slices;

  // clear and reserve
  PlaneGeometry::Pointer gnull = nullptr;
  m_PlaneGeometries.assign( m_Slices, gnull );

  Vector3D directionVector = geometry2D->GetAxisVector(2);
  directionVector.Normalize();
  directionVector *= zSpacing;

  if ( flipped == false )
  {
    // Normally we should use the following four lines to create a copy of
    // the transform contrained in geometry2D, because it may not be changed
    // by us. But we know that SetSpacing creates a new transform without
    // changing the old (coming from geometry2D), so we can use the fifth
    // line instead. We check this at (**).
    //
    // AffineTransform3D::Pointer transform = AffineTransform3D::New();
    // transform->SetMatrix(geometry2D->GetIndexToWorldTransform()->GetMatrix());
    // transform->SetOffset(geometry2D->GetIndexToWorldTransform()->GetOffset());
    // SetIndexToWorldTransform(transform);

    this->SetIndexToWorldTransform( const_cast< AffineTransform3D * >(
      geometry2D->GetIndexToWorldTransform() ));
  }
  else
  {
    directionVector *= -1.0;
    this->SetIndexToWorldTransform( AffineTransform3D::New());
    this->GetIndexToWorldTransform()->SetMatrix(
      geometry2D->GetIndexToWorldTransform()->GetMatrix() );

    AffineTransform3D::OutputVectorType scaleVector;
    FillVector3D(scaleVector, 1.0, 1.0, -1.0);
    this->GetIndexToWorldTransform()->Scale(scaleVector, true);
    this->GetIndexToWorldTransform()->SetOffset(
      geometry2D->GetIndexToWorldTransform()->GetOffset() );
  }

  mitk::Vector3D spacing;
  FillVector3D( spacing,
    geometry2D->GetExtentInMM(0) / bounds[1],
    geometry2D->GetExtentInMM(1) / bounds[3],
    zSpacing );

  this->SetDirectionVector( directionVector );
  this->SetBounds( bounds );
  this->SetPlaneGeometry( geometry2D, 0 );
  this->SetSpacing( spacing, true);
  this->SetEvenlySpaced();

  //this->SetTimeBounds( geometry2D->GetTimeBounds() );

  assert(this->GetIndexToWorldTransform()
    != geometry2D->GetIndexToWorldTransform()); // (**) see above.

  this->SetFrameOfReferenceID( geometry2D->GetFrameOfReferenceID() );
  this->SetImageGeometry( geometry2D->GetImageGeometry() );

  geometry2D->UnRegister();
}
Example #9
0
Vector3D reflectionDirection(const Vector3D& incomingVec, const Vector3D& normalVec) {
    Vector3D vout = incomingVec - 2.0*(DotProduct(incomingVec, normalVec))*normalVec;
    return vout.Normalize();
}
void
mitk::NormalDirectionConsistencySorter
::Sort()
{
  DICOMDatasetList datasets = GetInput();

  if (datasets.size() > 1)
  {
    // at some point in the code, there is the expectation that
    // the direction of the slice normals is the same as the direction between
    // first and last slice origin. We need to make this sure here, because
    // we want to feed the files into itk::ImageSeriesReader with the consistent
    // setting of ReverseOrderOff.

    static const DICOMTag tagImagePositionPatient = DICOMTag(0x0020,0x0032); // Image Position (Patient)
    static const DICOMTag    tagImageOrientation = DICOMTag(0x0020, 0x0037); // Image Orientation

    DICOMDatasetAccess* firstDS = datasets.front();
    DICOMDatasetAccess*  lastDS = datasets.back();

    // make sure here that the direction from slice to slice is the direction of
    // image normals...
    std::string imageOrientationString = firstDS->GetTagValueAsString( tagImageOrientation );
    std::string imagePositionPatientFirst = firstDS->GetTagValueAsString( tagImagePositionPatient );
    std::string imagePositionPatientLast = lastDS->GetTagValueAsString( tagImagePositionPatient );

    Vector3D right; right.Fill(0.0);
    Vector3D up; up.Fill(0.0);
    bool hasOrientation(false);
    DICOMStringToOrientationVectors( imageOrientationString,
        right, up, hasOrientation );

    Point3D firstOrigin; firstOrigin.Fill(0.0f);
    bool firstHasOrigin(false);
    firstOrigin = DICOMStringToPoint3D( imagePositionPatientFirst, firstHasOrigin );

    Point3D lastOrigin; lastOrigin.Fill(0.0f);
    bool lastHasOrigin(false);
    lastOrigin = DICOMStringToPoint3D( imagePositionPatientLast, lastHasOrigin );

    Vector3D normal;
    normal[0] = right[1] * up[2] - right[2] * up[1];
    normal[1] = right[2] * up[0] - right[0] * up[2];
    normal[2] = right[0] * up[1] - right[1] * up[0];
    normal.Normalize();

    Vector3D directionOfSlices;
    directionOfSlices = lastOrigin - firstOrigin;
    directionOfSlices.Normalize();

    double projection = normal * directionOfSlices;

    MITK_DEBUG << "Making sense of \norientation '" << imageOrientationString
               << "'\nfirst position '" << imagePositionPatientFirst
               << "'\nlast position '" << imagePositionPatientLast << "'";
    MITK_DEBUG << "Normal: " << normal;
    MITK_DEBUG << "Direction of slices: " << directionOfSlices;
    MITK_DEBUG << "Projection of direction onto slice normal: " << projection;

    if ( projection < 0.0 )
    {
      MITK_DEBUG << "Need to reverse filenames";
      std::reverse( datasets.begin(), datasets.end() );

      m_TiltInfo = GantryTiltInformation::MakeFromTagValues(
          imagePositionPatientLast,
          imagePositionPatientFirst,
          imageOrientationString,
          datasets.size() - 1
          );
    }
    else
    {
      m_TiltInfo = GantryTiltInformation::MakeFromTagValues(
          imagePositionPatientFirst,
          imagePositionPatientLast,
          imageOrientationString,
          datasets.size() - 1
          );
    }
  }
  else // just ONE dataset, do not forget to reset tilt information
  {
    m_TiltInfo = GantryTiltInformation(); // empty info
  }

  this->SetNumberOfOutputs(1);
  this->SetOutput(0, datasets);
}
void mitk::ExtrudePlanarFigureFilter::GenerateData()
{
  typedef PlanarFigure::PolyLineType PolyLine;

  if (m_Length <= 0)
    mitkThrow() << "Length is not positive!";

  if (m_NumberOfSegments == 0)
    mitkThrow() << "Number of segments is zero!";

  if (m_BendAngle != 0 && m_BendDirection[0] == 0 && m_BendDirection[1] == 0)
    mitkThrow() << "Bend direction is zero-length vector!";

  auto *input = dynamic_cast<PlanarFigure *>(this->GetPrimaryInput());

  if (input == nullptr)
    mitkThrow() << "Primary input is not a planar figure!";

  size_t numPolyLines = input->GetPolyLinesSize();

  if (numPolyLines == 0)
    mitkThrow() << "Primary input does not contain any poly lines!";

  const auto *planeGeometry = dynamic_cast<const PlaneGeometry *>(input->GetPlaneGeometry());

  if (planeGeometry == nullptr)
    mitkThrow() << "Could not get plane geometry from primary input!";

  Vector3D planeNormal = planeGeometry->GetNormal();
  planeNormal.Normalize();

  const Point2D centerPoint2d = GetCenterPoint(input);

  Point3D centerPoint3d;
  planeGeometry->Map(centerPoint2d, centerPoint3d);

  const Vector3D bendDirection3d =
    m_BendAngle != 0 ? ::GetBendDirection(planeGeometry, centerPoint2d, m_BendDirection) : Vector3D();

  const ScalarType radius = m_Length * (360 / m_BendAngle) / (2 * vnl_math::pi);
  const Vector3D scaledBendDirection3d = bendDirection3d * radius;

  Vector3D bendAxis = itk::CrossProduct(planeNormal, bendDirection3d);
  bendAxis.Normalize();

  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
  vtkIdType baseIndex = 0;

  for (size_t i = 0; i < numPolyLines; ++i)
  {
    const PolyLine polyLine = input->GetPolyLine(i);
    const size_t numPoints = polyLine.size();

    if (numPoints < 2)
      mitkThrow() << "Poly line " << i << " of primary input consists of less than two points!";

    std::vector<mitk::Point3D> crossSection;

    auto polyLineEnd = polyLine.end();

    for (auto polyLineIter = polyLine.begin(); polyLineIter != polyLineEnd; ++polyLineIter)
    {
      Point3D point;
      planeGeometry->Map(*polyLineIter, point);
      crossSection.push_back(point);
    }

    const ScalarType segmentLength = m_Length / m_NumberOfSegments;
    Vector3D translation = planeNormal * segmentLength;

    const bool bend = std::abs(m_BendAngle) > mitk::eps;
    const bool twist = std::abs(m_TwistAngle) > mitk::eps;

    const ScalarType twistAngle = twist ? m_TwistAngle / m_NumberOfSegments * vnl_math::pi / 180 : 0;

    ScalarType bendAngle = bend ? m_BendAngle / m_NumberOfSegments * vnl_math::pi / 180 : 0;

    if (m_FlipDirection)
    {
      translation *= -1;
      bendAngle *= -1;
    }

    for (size_t k = 0; k < numPoints; ++k)
      points->InsertNextPoint(crossSection[k].GetDataPointer());

    for (size_t j = 1; j <= m_NumberOfSegments; ++j)
    {
      mitk::AffineTransform3D::Pointer transform = mitk::AffineTransform3D::New();

      if (bend || twist)
        transform->Translate(centerPoint3d.GetVectorFromOrigin(), true);

      if (bend)
      {
        transform->Translate(scaledBendDirection3d, true);
        transform->Rotate3D(bendAxis, bendAngle * j, true);
        transform->Translate(-scaledBendDirection3d, true);
      }
      else
      {
        transform->Translate(translation * j, true);
      }

      if (twist)
        transform->Rotate3D(planeNormal, twistAngle * j, true);

      if (bend || twist)
        transform->Translate(-centerPoint3d.GetVectorFromOrigin(), true);

      for (size_t k = 0; k < numPoints; ++k)
      {
        const mitk::Point3D transformedPoint = transform->TransformPoint(crossSection[k]);
        points->InsertNextPoint(transformedPoint.GetDataPointer());
      }
    }

    for (size_t j = 0; j < m_NumberOfSegments; ++j)
    {
      for (size_t k = 1; k < numPoints; ++k)
      {
        vtkIdType cell[3];
        cell[0] = baseIndex + j * numPoints + (k - 1);
        cell[1] = baseIndex + (j + 1) * numPoints + (k - 1);
        cell[2] = baseIndex + j * numPoints + k;

        cells->InsertNextCell(3, cell);

        cell[0] = cell[1];
        cell[1] = baseIndex + (j + 1) * numPoints + k;

        cells->InsertNextCell(3, cell);
      }

      if (input->IsClosed() && numPoints > 2)
      {
        vtkIdType cell[3];
        cell[0] = baseIndex + j * numPoints + (numPoints - 1);
        cell[1] = baseIndex + (j + 1) * numPoints + (numPoints - 1);
        cell[2] = baseIndex + j * numPoints;

        cells->InsertNextCell(3, cell);

        cell[0] = cell[1];
        cell[1] = baseIndex + (j + 1) * numPoints;

        cells->InsertNextCell(3, cell);
      }
    }

    baseIndex += points->GetNumberOfPoints();
  }

  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
  polyData->SetPoints(points);
  polyData->SetPolys(cells);

  vtkSmartPointer<vtkPolyDataNormals> polyDataNormals = vtkSmartPointer<vtkPolyDataNormals>::New();
  polyDataNormals->SetFlipNormals(m_FlipNormals);
  polyDataNormals->SetInputData(polyData);
  polyDataNormals->SplittingOff();

  polyDataNormals->Update();

  auto *output = static_cast<Surface *>(this->GetPrimaryOutput());
  output->SetVtkPolyData(polyDataNormals->GetOutput());
}
Example #12
0
bool mitk::SegTool2D::DetermineAffectedImageSlice(const Image *image,
                                                  const PlaneGeometry *plane,
                                                  int &affectedDimension,
                                                  int &affectedSlice)
{
  assert(image);
  assert(plane);

  // compare normal of plane to the three axis vectors of the image
  Vector3D normal = plane->GetNormal();
  Vector3D imageNormal0 = image->GetSlicedGeometry()->GetAxisVector(0);
  Vector3D imageNormal1 = image->GetSlicedGeometry()->GetAxisVector(1);
  Vector3D imageNormal2 = image->GetSlicedGeometry()->GetAxisVector(2);

  normal.Normalize();
  imageNormal0.Normalize();
  imageNormal1.Normalize();
  imageNormal2.Normalize();

  imageNormal0.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal0.GetVnlVector()));
  imageNormal1.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal1.GetVnlVector()));
  imageNormal2.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal2.GetVnlVector()));

  double eps(0.00001);
  // axial
  if (imageNormal2.GetNorm() <= eps)
  {
    affectedDimension = 2;
  }
  // sagittal
  else if (imageNormal1.GetNorm() <= eps)
  {
    affectedDimension = 1;
  }
  // frontal
  else if (imageNormal0.GetNorm() <= eps)
  {
    affectedDimension = 0;
  }
  else
  {
    affectedDimension = -1; // no idea
    return false;
  }

  // determine slice number in image
  BaseGeometry *imageGeometry = image->GetGeometry(0);
  Point3D testPoint = imageGeometry->GetCenter();
  Point3D projectedPoint;
  plane->Project(testPoint, projectedPoint);

  Point3D indexPoint;

  imageGeometry->WorldToIndex(projectedPoint, indexPoint);
  affectedSlice = ROUND(indexPoint[affectedDimension]);
  MITK_DEBUG << "indexPoint " << indexPoint << " affectedDimension " << affectedDimension << " affectedSlice "
             << affectedSlice;

  // check if this index is still within the image
  if (affectedSlice < 0 || affectedSlice >= static_cast<int>(image->GetDimension(affectedDimension)))
    return false;

  return true;
}
Example #13
0
void Grass::Draw() {
	//        grass = qSort(grass,0,grass_num-1);
	vector<Vector3D> newgrass;
	vector<int> number;
	float newgrass_size = 0;
	float yaw = 0.0;
	if (!Info::GetShader() || Info::GetRefract() || Info::GetReflect()) yaw = 3.0;
	if (Info::GetShader()) {
		glUseProgram(shaderprogram);
		setShader();
	}
	const GLint u_model0 = glGetUniformLocation(shaderprogram, "model");
	const GLint u_ter0 = glGetUniformLocation(shaderprogram, "terNormal");
	const GLint u_type0 = glGetUniformLocation(shaderprogram, "type");

	bool tmp = Info::GetShader();
	Info::SetShader(false);
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//  glDepthMask(false);
	if (yaw == 0) offset += (rnd() / 5.0 + 0.05)*Info::GetElapsedTime();
	float pi = 3.141592;
	const Vector3D player = Camera::getPosition();
	int samples = 0;
	float *distVec = new float[grass_num];
	const float* dist0 = &distVec[0];
	Vector3D b = Info::GetEyeNormal();
	b.Normalize();
	Vector3D *grass0 = &grass[0];

	newgrass.reserve(grass_num * 0.25);
	number.reserve(grass_num * 0.25);

	for (int i = 0; i < grass_num; i++) {
		Vector3D grassLeaf = *(grass0 + i);
		const float dst = distance(grassLeaf, player);
		distVec[i] = dst;
		if (dst > WINDOW) {
			bool flag = false;
			if (grass[i].x - player.x < -WINDOW) {
				grass[i].x += WINDOW * 2.0;
				flag = true;
			}
			if (grass[i].y - player.y < -WINDOW) {
				grass[i].y += WINDOW * 2.0;
				flag = true;
			}
			if (grass[i].x - player.x > WINDOW) {
				grass[i].x -= WINDOW * 2.0;
				flag = true;
			}
			if (grass[i].y - player.y > WINDOW) {
				grass[i].y -= WINDOW * 2.0;
				flag = true;
			}
			if (flag) {
				grass[i].z = CalcTerHeight(Vector3D(grass[i].x, grass[i].y, 0.0));
				CalcGrassType(i);
				int number = 0;
				for (int p = grass[i].x - 5; p <= grass[i].x + 5; p += 10) {
					for (int k = grass[i].y - 5; k <= grass[i].y + 5; k += 10) {
						borders[i][number].z = CalcTerHeight(Vector3D(p, k, 0.0));
						borders[i][number].x = p;
						borders[i][number].y = k;
						number++;
					}
				}
			}
			continue;
		}
		if (dst > 500) continue;
		if (grass[i].z > 150 || grass[i].z < 10) continue;
		if (yaw == 1.0 && dst > 40.0) continue;
		else if (yaw == 2.0 && dst > 100.0) continue;
		else if (yaw == 3.0 && dst > 200.0) continue;

		Vector3D a = *(grass0 + i) - player;
		a.Normalize();

		float norm_vec = a*b;
		if (yaw == 0.0) if (norm_vec < 0.7 && dst > 30.0) continue;
		newgrass.push_back(*(grass0 + i));
		number.push_back(i);
		newgrass_size++;
	}
	//if(newgrass_size > 5) qSort(newgrass,number,0,newgrass_size-1);
	const int *number0 = &number[0];
	const int *type0 = &type[0];
	const float *angle0 = &angle[0];
	for (int i = 0; i < newgrass_size; i++) {
		const int numberI = *(number0 + i);
		const float dst = *(dist0 + numberI);
		if (dst > 500) continue;
		glPushMatrix();
		glTranslated(newgrass[i].x, newgrass[i].y, newgrass[i].z - 0.3);
		glRotated(*(angle0 + numberI), 0, 0, 1);
		if (type[numberI] == 0 || type[numberI] == 1 || type[numberI] == 2) {

			if (yaw == 0) {
				glUniform1i(u_model0, 10 + type[numberI]);
				/*if ((*(angle0 + numberI)) > 50.0) {
					glScaled(1.0, 1.0, 1.3);
					glUniform1i(u_model0, 16);
				}
				else {
					glUniform1i(u_model0, 10);
				}*/
				glUniform1i(u_type0, 0);
				glUniform3f(u_ter0, terNormal[numberI].x, terNormal[numberI].y, terNormal[numberI].z);
				glUniform3f(glGetUniformLocation(
					shaderprogram, "border1"), borders[numberI][0].x, borders[numberI][0].y, borders[numberI][0].z);
				glUniform3f(glGetUniformLocation(
					shaderprogram, "border2"), borders[numberI][1].x, borders[numberI][1].y, borders[numberI][1].z);
				glUniform3f(glGetUniformLocation(
					shaderprogram, "border3"), borders[numberI][2].x, borders[numberI][2].y, borders[numberI][2].z);
				glUniform3f(glGetUniformLocation(
					shaderprogram, "border4"), borders[numberI][3].x, borders[numberI][3].y, borders[numberI][3].z);
				glUniform3f(glGetUniformLocation(
					shaderprogram, "center"), newgrass[i].x, newgrass[i].y, newgrass[i].z);
				//std::cout << borders[numberI][0].x << " " << borders[numberI][0].y << " " << borders[numberI][0].z << " " << newgrass[i].x << " " << newgrass[i].y << " " << newgrass[i].z << std::endl;


				//if(dst < 30) {
				model[0].draw();
				samples += 480;

				if ((*(angle0 + numberI)) > 50.0) glScaled(1.0, 1.0, 1.0 / 1.3);
			}
		}
		else if (type[numberI] == 3){
			glUniform1i(u_model0, 13);
			glUniform1i(u_type0, 1);
			glTranslated(0, 0, 0.3);
				model[3].draw();
			glTranslated(0, 0, -0.3);
			samples += 2936;
		}
		else if (type[numberI] == 4){
			glUniform1i(u_model0, 14);
			glUniform1i(u_type0, 1);
			glTranslated(0, 0, 0.3);
				model[4].draw();
			glTranslated(0, 0, -0.3);
			samples += 2936;
		}
		else if (type[numberI] == 5){
			glUniform1i(u_model0, 15);
			glUniform1i(u_type0, 1);
				glTranslated(0, 0, 0.3);
				model[5].draw();
				glTranslated(0, 0, -0.3);
			samples += 2936;
		}
		glRotated(-*(angle0 + numberI), 0, 0, 1);
		glTranslated(-newgrass[i].x, -newgrass[i].y, -newgrass[i].z + 0.3);
		glPopMatrix();
	}
	//	printf("grass triangles drawing: %d\n",samples);
	//   glDepthMask(true);
	glDisable(GL_ALPHA_TEST);
	glDisable(GL_BLEND);
	newgrass.clear();
	number.clear();
	Info::SetShader(tmp);
	//		if(Info::shader)  
	glUseProgram(0);
	if (yaw == 0) windWave += 5.0 * Info::GetElapsedTime();
	delete[] distVec;
}