Beispiel #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;
}
Beispiel #2
0
void sreLookAt(float viewpx, float viewpy, float viewpz, float lookx, float looky, float lookz,
float upx, float upy, float upz) {
    Vector3D F = Vector3D(lookx, looky, lookz) - Vector3D(viewpx, viewpy, viewpz);
    Vector3D Up = Vector3D(upx, upy, upz);
    Vector3D f = F.Normalize();
    sre_internal_camera_vector = f;
    Up.Normalize();
    sre_internal_up_vector = Up;
    Vector3D s = Cross(f, Up);
    Vector3D u = Cross(s, f);
    MatrixTransform M;
    M.Set(
        s.x, s.y, s.z, 0.0f,
        u.x, u.y, u.z, 0.0f,
        - f.x, - f.y, - f.z, 0.0f);
    MatrixTransform T;
    T.AssignTranslation(Vector3D(- viewpx, - viewpy, -viewpz));
    sre_internal_view_matrix = M * T;
    sre_internal_view_projection_matrix = sre_internal_projection_matrix * sre_internal_view_matrix;
//    printf("View-projection matrix:\n");
//    for (int row = 0; row < 4; row++)
//        for (int column = 0; column < 4; column++)
//            printf("%f, ", sre_internal_view_projection_matrix(row, column));
//    printf("\n");
}
Beispiel #3
0
float twoVectorAngle(Vector3D vectorA, Vector3D vectorB, Vector3D planeNormal)
{
	// Calculating the relative angle of two joints given their vectors


	vectorA.Normalize();
	vectorB.Normalize();	

	// The minimum angle between the vectors
	float dotProduct = vectorA * vectorB;
	float segmentAngle = acos(dotProduct);

	// Determining the sign
	Vector3D crossProduct = vectorA % vectorB;
	float angleSign = planeNormal * crossProduct;
	if (angleSign < 0){
		segmentAngle = -segmentAngle;
	}

	// uncomment for degrees
	// segmentAngle = segmentAngle *(180 / M_PI);

	return segmentAngle;

}
Beispiel #4
0
double Sphere::RayIntersect(Ray &ray, IntersectData *intersectData)
{
	double A = 1.0; // normalized ray vector
	double B = 2.0 * (ray.Vector().x * (ray.Point().x - center.x) + ray.Vector().y * (ray.Point().y - center.y) + ray.Vector().z * (ray.Point().z - center.z));
	double C = pow(ray.Point().x - center.x, 2.0) + pow(ray.Point().y - center.y, 2.0) + pow(ray.Point().z - center.z, 2.0) - radius * radius;
	double Det = B * B - 4.0 * A * C;

	if (Det >= 0.0)
	{
		double t = (-B - sqrt(Det)) / 2;

		if (t > 0.0)
		{
			if (intersectData)
			{
				Point3D contact = (Vector3D)ray.Point() + ray.Vector() * t;
				Vector3D normal = (Vector3D)contact - center;
				normal = normal.Normalize();

				intersectData->contact = contact;
				intersectData->normal = normal;
				intersectData->color = color;
			}

			return t;
		}

		t = (-B + sqrt(Det)) / 2;

		if (t > 0.0)
		{
			if (intersectData)
			{
				Point3D contact = (Vector3D)ray.Point() + ray.Vector() * t;
				Vector3D normal = (Vector3D)contact - center;
				normal = normal.Normalize();

				intersectData->contact = contact;
				intersectData->normal = normal;
				intersectData->color = color;

				return t;
			}
		}
	}

	return INFINITY;
}
Beispiel #5
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;
}
Beispiel #6
0
void Screen::CalculatePosition(Vector3D eye, Vector3D center, Vector3D up) {
	Vector3D f = (center - eye).Normalize();
	pos = eye + f;
	this->up = up.Normalize();
	right = Vector3D::VectorProduct(f, this->up).Normalize();
	if(DEBUG) std::cout << "Position: " << pos << "\nUp: " << this->up << "\nRight: " <<
			right << "\nHeight: " << plane_height << "\nWidth: " << plane_width << std::endl;
}
Beispiel #7
0
Vector3D Vector3D::truncVector(Vector3D vector3, float max)
{
	if(vector3.length() > max)
	{
		vector3.Normalize();
		vector3 *= max;
	}
			
	return vector3;
}
Beispiel #8
0
TEST(vec3d, norm)
{
	Vector3D testingVector = Vector3D();
	testingVector.x = 2;
	testingVector.y = 5;
	testingVector.z = 7;
	testingVector.Normalize();
	EXPECT_FLOAT_EQ(0.22645540682f, testingVector.x);
	EXPECT_FLOAT_EQ(0.56613851707f, testingVector.y);
	EXPECT_FLOAT_EQ(0.7925939239f, testingVector.z);
}
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;
}
Beispiel #10
0
void Weapon::SetFireVector( Vector3D& Aim)
{
	//Point the bullet particles somewhere. Also
	//make sure that it ignores the rotation values
	//if we're using this.
	AimUsingRotation = false;
	Aim.Normalize();
	Bullets.StreamHeading.x = Aim.x*ProjectileSpeed;
	Bullets.StreamHeading.y = Aim.y*ProjectileSpeed;
	Bullets.StreamHeading.z = Aim.z*ProjectileSpeed;	

}
void
  mitk::SlicedGeometry3D
  ::SetDirectionVector( const mitk::Vector3D& directionVector )
{
  Vector3D newDir = directionVector;
  newDir.Normalize();
  if ( newDir != m_DirectionVector )
  {
    m_DirectionVector = newDir;
    this->Modified();
  }
}
Beispiel #12
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::AffineImageCropperInteractor::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return;

  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
  if(currentPickedDisplayPoint.EuclideanDistanceTo(m_InitialPickedDisplayPoint) < 1)
    return;

  vtkRenderer* currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();

  if ( currentVtkRenderer &&  currentVtkRenderer->GetActiveCamera())
  {
    double vpn[3];
    currentVtkRenderer->GetActiveCamera()->GetViewPlaneNormal( vpn );

    Vector3D rotationAxis;
    rotationAxis[0] = vpn[0];
    rotationAxis[1] = vpn[1];
    rotationAxis[2] = vpn[2];
    rotationAxis.Normalize();

    Vector2D move = currentPickedDisplayPoint - m_InitialPickedDisplayPoint;

    double rotationAngle = -57.3 * atan(move[0]/move[1]);
    if(move[1]<0) rotationAngle +=180;

    // Use center of data bounding box as center of rotation
    Point3D rotationCenter = m_OriginalGeometry->GetCenter();
    if(positionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D)
      rotationCenter = m_InitialPickedPoint;

    // 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 );
    m_SelectedNode->GetData()->SetGeometry(newGeometry);

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
  }
}
Beispiel #14
0
void Matrix4x4::RotateAxis(double angle, Vector3D axis)
{
	axis.Normalize();

	float sinAngle = (float)sin(PI_CONST * angle / 180);
	float cosAngle = (float)cos(PI_CONST * angle / 180);
	float oneSubCos = 1.0f - cosAngle;

	matrix[0] = (axis.x * axis.x) * oneSubCos + cosAngle;
	matrix[4] = (axis.x * axis.y) * oneSubCos - (axis.z * sinAngle);
	matrix[8] = (axis.x * axis.z) * oneSubCos + (axis.y * sinAngle);

	matrix[1] = (axis.y * axis.x) * oneSubCos + (sinAngle * axis.z);
	matrix[5] = (axis.y * axis.y) * oneSubCos + cosAngle;
	matrix[9] = (axis.y * axis.z) * oneSubCos - (axis.x * sinAngle);
	
	matrix[2] = (axis.z * axis.x) * oneSubCos - (axis.y * sinAngle);
	matrix[6] = (axis.z * axis.y) * oneSubCos + (axis.x * sinAngle);
	matrix[10] = (axis.z * axis.z) * oneSubCos + cosAngle;
}
Beispiel #15
0
void GLMesh::CalculateNormals()
{
    for (unsigned int i = 0; i < _iCount - 2; i++)
    {
        GLVertex p1 = _vertices[_indices[i+0]];
        GLVertex p2 = _vertices[_indices[i+1]];
        GLVertex p3 = _vertices[_indices[i+2]];
        Vector3D normal = (p2.Position - p1.Position) * (p3.Position - p1.Position);
        normal.Normalize();
        if (i%2) normal *= -1;

        _vertices[_indices[i+0]].Normal += normal;
        _vertices[_indices[i+1]].Normal += normal;
        _vertices[_indices[i+2]].Normal += normal;
    }

    for (unsigned int v=0; v< _vCount - 2; v++)
    {
        _vertices[v].Normal.Normalize();
    }
}
void mitk::PlaneGeometryDataMapper2D::CreateVtkCrosshair(mitk::BaseRenderer *renderer)
{
  bool visible = true;
  LocalStorage* ls = m_LSH.GetLocalStorage(renderer);
  ls->m_CrosshairActor->SetVisibility(0);
  ls->m_ArrowActor->SetVisibility(0);
  ls->m_CrosshairHelperLineActor->SetVisibility(0);

  GetDataNode()->GetVisibility(visible, renderer, "visible");

  if(!visible)
  {
    return;
  }

  PlaneGeometryData::Pointer input = const_cast< PlaneGeometryData * >(this->GetInput());
  mitk::DataNode* geometryDataNode = renderer->GetCurrentWorldPlaneGeometryNode();
  const PlaneGeometryData* rendererWorldPlaneGeometryData = dynamic_cast< PlaneGeometryData * >(geometryDataNode->GetData());

  // intersecting with ourself?
  if ( input.IsNull() || input.GetPointer() == rendererWorldPlaneGeometryData)
  {
    return; //nothing to do in this case
  }

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

  const PlaneGeometry* worldPlaneGeometry = dynamic_cast< const PlaneGeometry* >(
        rendererWorldPlaneGeometryData->GetPlaneGeometry() );

  if ( worldPlaneGeometry && dynamic_cast<const AbstractTransformGeometry*>(worldPlaneGeometry)==NULL
       && inputPlaneGeometry && dynamic_cast<const AbstractTransformGeometry*>(input->GetPlaneGeometry() )==NULL
       && inputPlaneGeometry->GetReferenceGeometry() )
  {
    const BaseGeometry *referenceGeometry = inputPlaneGeometry->GetReferenceGeometry();

    // calculate intersection of the plane data with the border of the
    // world geometry rectangle
    Point3D point1, point2;

    Line3D crossLine;

    // Calculate the intersection line of the input plane with the world plane
    if ( worldPlaneGeometry->IntersectionLine( inputPlaneGeometry, crossLine ) )
    {
      Point3D boundingBoxMin, boundingBoxMax;
      boundingBoxMin = referenceGeometry->GetCornerPoint(0);
      boundingBoxMax = referenceGeometry->GetCornerPoint(7);

      Point3D indexLinePoint;
      Vector3D indexLineDirection;

      referenceGeometry->WorldToIndex(crossLine.GetPoint(),indexLinePoint);
      referenceGeometry->WorldToIndex(crossLine.GetDirection(),indexLineDirection);

      referenceGeometry->WorldToIndex(boundingBoxMin,boundingBoxMin);
      referenceGeometry->WorldToIndex(boundingBoxMax,boundingBoxMax);

      // Then, clip this line with the (transformed) bounding box of the
      // reference geometry.
      Line3D::BoxLineIntersection(
            boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2],
          boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2],
          indexLinePoint, indexLineDirection,
          point1, point2 );

      referenceGeometry->IndexToWorld(point1,point1);
      referenceGeometry->IndexToWorld(point2,point2);
      crossLine.SetPoints(point1,point2);

      vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
      vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
      vtkSmartPointer<vtkPolyData> linesPolyData = vtkSmartPointer<vtkPolyData>::New();


      // Now iterate through all other lines displayed in this window and
      // calculate the positions of intersection with the line to be
      // rendered; these positions will be stored in lineParams to form a
      // gap afterwards.
      NodesVectorType::iterator otherPlanesIt = m_OtherPlaneGeometries.begin();
      NodesVectorType::iterator otherPlanesEnd = m_OtherPlaneGeometries.end();

      std::vector<Point3D> intersections;

      intersections.push_back(point1);

      otherPlanesIt = m_OtherPlaneGeometries.begin();
      int gapsize = 32;
      this->GetDataNode()->GetPropertyValue( "Crosshair.Gap Size",gapsize, NULL );


      ScalarType lineLength = point1.EuclideanDistanceTo(point2);
      DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();

      ScalarType gapinmm = gapsize * displayGeometry->GetScaleFactorMMPerDisplayUnit();

      float gapSizeParam = gapinmm / lineLength;

      while ( otherPlanesIt != otherPlanesEnd )
      {
        PlaneGeometry *otherPlane = static_cast< PlaneGeometry * >(
              static_cast< PlaneGeometryData * >((*otherPlanesIt)->GetData() )->GetPlaneGeometry() );

        if (otherPlane != inputPlaneGeometry && otherPlane != worldPlaneGeometry)
        {
          Point3D planeIntersection;
          otherPlane->IntersectionPoint(crossLine,planeIntersection);
          ScalarType sectionLength = point1.EuclideanDistanceTo(planeIntersection);
          ScalarType lineValue = sectionLength/lineLength;
          if(lineValue-gapSizeParam > 0.0)
            intersections.push_back(crossLine.GetPoint(lineValue-gapSizeParam));
          else intersections.pop_back();
          if(lineValue+gapSizeParam < 1.0)
            intersections.push_back(crossLine.GetPoint(lineValue+gapSizeParam));
        }
        ++otherPlanesIt;
      }
      if(intersections.size()%2 == 1)
        intersections.push_back(point2);

      if(intersections.empty())
      {
        this->DrawLine(point1,point2,lines,points);
      }
      else
        for(unsigned int i = 0 ; i< intersections.size()-1 ; i+=2)
        {
          this->DrawLine(intersections[i],intersections[i+1],lines,points);
        }

      // Add the points to the dataset
      linesPolyData->SetPoints(points);
      // Add the lines to the dataset
      linesPolyData->SetLines(lines);

      Vector3D orthogonalVector;
      orthogonalVector = inputPlaneGeometry->GetNormal();
      worldPlaneGeometry->Project(orthogonalVector,orthogonalVector);
      orthogonalVector.Normalize();

      // Visualize
      ls->m_Mapper->SetInputData(linesPolyData);
      ls->m_CrosshairActor->SetMapper(ls->m_Mapper);

      // Determine if we should draw the area covered by the thick slicing, default is false.
      // This will also show the area of slices that do not have thick slice mode enabled
      bool showAreaOfThickSlicing = false;
      GetDataNode()->GetBoolProperty( "reslice.thickslices.showarea", showAreaOfThickSlicing );

      // determine the pixelSpacing in that direction
      double thickSliceDistance = SlicedGeometry3D::CalculateSpacing( referenceGeometry->GetSpacing(), orthogonalVector );

      IntProperty *intProperty=0;
      if( GetDataNode()->GetProperty( intProperty, "reslice.thickslices.num" ) && intProperty )
        thickSliceDistance *= intProperty->GetValue()+0.5;
      else
        showAreaOfThickSlicing = false;

      // not the nicest place to do it, but we have the width of the visible bloc in MM here
      // so we store it in this fancy property
      GetDataNode()->SetFloatProperty( "reslice.thickslices.sizeinmm", thickSliceDistance*2 );

      ls->m_CrosshairActor->SetVisibility(1);

      vtkSmartPointer<vtkPolyData> arrowPolyData = vtkSmartPointer<vtkPolyData>::New();
      ls->m_Arrowmapper->SetInputData(arrowPolyData);
      if(this->m_RenderOrientationArrows)
      {
        ScalarType triangleSizeMM = 7.0 * displayGeometry->GetScaleFactorMMPerDisplayUnit();

        vtkSmartPointer<vtkCellArray> triangles = vtkSmartPointer<vtkCellArray>::New();
        vtkSmartPointer<vtkPoints> triPoints = vtkSmartPointer<vtkPoints>::New();

        DrawOrientationArrow(triangles,triPoints,triangleSizeMM,orthogonalVector,point1,point2);
        DrawOrientationArrow(triangles,triPoints,triangleSizeMM,orthogonalVector,point2,point1);
        arrowPolyData->SetPoints(triPoints);
        arrowPolyData->SetPolys(triangles);
        ls->m_ArrowActor->SetVisibility(1);
      }

      // Visualize
      vtkSmartPointer<vtkPolyData> helperlinesPolyData = vtkSmartPointer<vtkPolyData>::New();
      ls->m_HelperLinesmapper->SetInputData(helperlinesPolyData);
      if ( showAreaOfThickSlicing )
      {
        vtkSmartPointer<vtkCellArray> helperlines = vtkSmartPointer<vtkCellArray>::New();
        // vectorToHelperLine defines how to reach the helperLine from the mainLine
        // got the right direction, so we multiply the width
        Vector3D vecToHelperLine = orthogonalVector * thickSliceDistance;

        this->DrawLine(point1 - vecToHelperLine, point2 - vecToHelperLine,helperlines,points);
        this->DrawLine(point1 + vecToHelperLine, point2 + vecToHelperLine,helperlines,points);

        // Add the points to the dataset
        helperlinesPolyData->SetPoints(points);

        // Add the lines to the dataset
        helperlinesPolyData->SetLines(helperlines);

        ls->m_CrosshairActor->GetProperty()->SetLineStipplePattern(0xf0f0);
        ls->m_CrosshairActor->GetProperty()->SetLineStippleRepeatFactor(1);
        ls->m_CrosshairHelperLineActor->SetVisibility(1);
      }
    }
  }
}
Beispiel #17
0
//
//#############################################################################
//#############################################################################
//
UnitQuaternion&
	UnitQuaternion::Subtract(
		const UnitVector3D &end,
		const UnitVector3D &start
	)
{
	Check_Pointer(this);
	Check_Object(&start);
	Check_Object(&end);

	Vector3D
		axis;
	SinCosPair
		delta;
	delta.cosine = start*end;

	//
	//----------------------------------------------------------------------
	// See if the vectors point in the same direction.  If so, return a null
	// rotation
	//----------------------------------------------------------------------
	//
	if (Close_Enough(delta.cosine, 1.0f))
	{
		x = 0.0f;
		y = 0.0f;
		z = 0.0f;
		w = 1.0f;
	}

	//
	//-------------------------------------------------------------------------
	// See if the vectors directly oppose each other.  If so, pick the smallest
	// axis coordinate and generate a vector along it.  Project this onto the
	// base vector and subtract it out, leaving a perpendicular projection.
	// Extend that out to unit length, then set the angle to PI
	//-------------------------------------------------------------------------
	//
	else if (Close_Enough(delta.cosine, -1.0f))
	{
		//
		//---------------------------
		// Pick out the smallest axis
		//---------------------------
		//
		int
			smallest=0;
		Scalar
			value=2.0f;
		for (int i=X_Axis; i<=Z_Axis; ++i)
		{
			if (Abs(start[i]) < value)
			{
				smallest = i;
				value = Abs(start[i]);
			}
		}

		//
		//----------------------------------------
		// Set up a vector along the selected axis
		//----------------------------------------
		//
		axis.x = 0.0f;
		axis.y = 0.0f;
		axis.z = 0.0f;
		axis[smallest] = 1.0f;

		//
		//-------------------------------------------------------------------
		// If the value on that axis wasn't zero, subtract out the projection
		//-------------------------------------------------------------------
		//
		if (!Small_Enough(value))
		{
			Vector3D t;
			t.Multiply(start, start*axis);
			axis.Subtract(axis, t);
			axis.Normalize(axis);
		}

		//
		//----------------------
		// Convert to quaternion
		//----------------------
		//
		x = axis.x;
		y = axis.y;
		z = axis.z;
		w = 0.0f;
	}

	//
	//--------------------------------------------------
	// Otherwise, generate the cross product and unitize
	//--------------------------------------------------
	//
	else
	{
		axis.Cross(start, end);
		delta.sine = axis.GetLength();
		axis /= delta.sine;

		//
		//---------------------------------------------------------------
		// Now compute sine and cosine of half the angle and generate the
		// quaternion
		//---------------------------------------------------------------
		//
		delta.sine = Sqrt((1.0f - delta.cosine)*0.5f);
		x = axis.x * delta.sine;
		y = axis.y * delta.sine;
		z = axis.z * delta.sine;
		w = Sqrt((1.0f + delta.cosine)*0.5f);
	}
	return *this;
}
void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer )
{
    if ( IsVisible( renderer ) == false )
        return ;

    // ok, das ist aus GenerateData kopiert
    mitk::BaseData::Pointer input = const_cast<mitk::BaseData*>( GetData() );

    assert( input );

    input->Update();

    vtkPolyData * vtkpolydata = this->GetVtkPolyData();
    assert( vtkpolydata );


    vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform();

    if (vtktransform)
    {
      vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();

      Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
      PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );

      if ( vtkpolydata != NULL )
      {
          Point3D point;
          Vector3D normal;

          if(worldPlaneGeometry.IsNotNull())
          {
            // set up vtkPlane according to worldGeometry
            point=worldPlaneGeometry->GetOrigin();
            normal=worldPlaneGeometry->GetNormal(); normal.Normalize();
            m_Plane->SetTransform((vtkAbstractTransform*)NULL);
          }
          else
          {
            //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"?
            return;
            AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D());
            if(worldAbstractGeometry.IsNotNull())
            {
              // set up vtkPlane according to worldGeometry
              point=const_cast<mitk::BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
              FillVector3D(normal, 0, 0, 1);
              m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
            }
            else
              return;
          }

          vtkFloatingPointType vp[ 3 ], vnormal[ 3 ];

          vnl2vtk(point.Get_vnl_vector(), vp);
          vnl2vtk(normal.Get_vnl_vector(), vnormal);

          //normally, we would need to transform the surface and cut the transformed surface with the cutter.
          //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
          //@todo It probably does not work for scaling operations yet:scaling operations have to be
          //dealed with after the cut is performed by scaling the contour.
          inversetransform->TransformPoint( vp, vp );
          inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal );

          m_Plane->SetOrigin( vp );
          m_Plane->SetNormal( vnormal );

          // set data into cutter
          m_Cutter->SetInput( vtkpolydata );
          //    m_Cutter->GenerateCutScalarsOff();
          //    m_Cutter->SetSortByToSortByCell();

          // calculate the cut
          m_Cutter->Update();

          // fetch geometry
          mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
          assert( displayGeometry );
          //  float toGL=displayGeometry->GetSizeInDisplayUnits()[1];

          //apply color and opacity read from the PropertyList
          ApplyProperties( renderer );

          // traverse the cut contour
          vtkPolyData * contour = m_Cutter->GetOutput();

          vtkPoints *vpoints = contour->GetPoints();
          vtkCellArray *vpolys = contour->GetLines();
          vtkPointData *vpointdata = contour->GetPointData();
          vtkDataArray* vscalars = vpointdata->GetScalars();

          vtkCellData *vcelldata = contour->GetCellData();
          vtkDataArray* vcellscalars = vcelldata->GetScalars();

          int i, numberOfCells = vpolys->GetNumberOfCells();

          Point3D p;
          Point2D p2d, last, first;

          vpolys->InitTraversal();
          vtkScalarsToColors* lut = GetVtkLUT();
          assert ( lut != NULL );

          for ( i = 0;i < numberOfCells;++i )
          {
              vtkIdType *cell(NULL);
              vtkIdType cellSize(0);

              vpolys->GetNextCell( cellSize, cell );

              if ( m_ColorByCellData )
              {  // color each cell according to cell data
                vtkFloatingPointType* color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
              }
              if ( m_ColorByPointData )
              {
                vtkFloatingPointType* color = lut->GetColor( vscalars->GetComponent( cell[0], 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
              }

              glBegin ( GL_LINE_LOOP );
              for ( int j = 0;j < cellSize;++j )
              {
                  vpoints->GetPoint( cell[ j ], vp );
                  //take transformation via vtktransform into account
                  vtktransform->TransformPoint( vp, vp );

                  vtk2itk( vp, p );

                  //convert 3D point (in mm) to 2D point on slice (also in mm)
                  worldGeometry->Map( p, p2d );

                  //convert point (until now mm and in worldcoordinates) to display coordinates (units )
                  displayGeometry->WorldToDisplay( p2d, p2d );

                  //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
                  //p2d[1]=toGL-p2d[1];

                  //add the current vertex to the line
                  glVertex2f( p2d[0], p2d[1] );
              }
              glEnd ();
          }
      }
    }
}
void mitk::SurfaceGLMapper2D::Paint(mitk::BaseRenderer * renderer)
{
  bool visible = true;
  GetDataNode()->GetVisibility(visible, renderer, "visible");
  if(!visible) return;

  Surface::Pointer input  = const_cast<Surface*>(this->GetInput());

  if(input.IsNull())
    return;

  //
  // get the TimeGeometry of the input object
  //
  const TimeGeometry* inputTimeGeometry = input->GetTimeGeometry();
  if(( inputTimeGeometry == NULL ) || ( inputTimeGeometry->CountTimeSteps() == 0 ) )
    return;

  m_LineWidth = 1;
  GetDataNode()->GetIntProperty("line width", m_LineWidth, renderer);

  //
  // get the world time
  //
  ScalarType time =renderer->GetTime();
  int timestep=0;

  if( time > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin() )
    timestep = inputTimeGeometry->TimePointToTimeStep( time );

 // int timestep = this->GetTimestep();

  if( inputTimeGeometry->IsValidTimeStep( timestep ) == false )
    return;

  vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
  if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 ))
    return;

  //apply color and opacity read from the PropertyList
  this->ApplyAllProperties(renderer);

  if (m_DrawNormals)
  {
    m_PointLocator->SetDataSet( vtkpolydata );
    m_PointLocator->BuildLocatorFromPoints( vtkpolydata->GetPoints() );
  }

  if(vtkpolydata!=NULL)
  {
    Point3D point;
    Vector3D normal;

    //Check if Lookup-Table is already given, else use standard one.
    double* scalarLimits = m_LUT->GetTableRange();
    double scalarsMin = scalarLimits[0], scalarsMax = scalarLimits[1];

    vtkLookupTable *lut;

    LookupTableProperty::Pointer lookupTableProp;
    this->GetDataNode()->GetProperty(lookupTableProp, "LookupTable", renderer);
    if (lookupTableProp.IsNotNull() )
    {
      lut = lookupTableProp->GetLookupTable()->GetVtkLookupTable();

      GetDataNode()->GetDoubleProperty("ScalarsRangeMinimum", scalarsMin, renderer);
      GetDataNode()->GetDoubleProperty("ScalarsRangeMaximum", scalarsMax, renderer);

      // check if the scalar range has been changed, e.g. manually, for the data tree node, and rebuild the LUT if necessary.
      double* oldRange = lut->GetTableRange();
      if( oldRange[0] != scalarsMin || oldRange[1] != scalarsMax )
      {
        lut->SetTableRange(scalarsMin, scalarsMax);
        lut->Build();
      }
    }
    else
    {
      lut = m_LUT;
    }

    vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform(timestep);
    PlaneGeometry::ConstPointer worldGeometry = renderer->GetCurrentWorldPlaneGeometry();
    assert( worldGeometry.IsNotNull() );
    if (worldGeometry.IsNotNull())
    {
      // set up vtkPlane according to worldGeometry
      point=worldGeometry->GetOrigin();
      normal=worldGeometry->GetNormal(); normal.Normalize();
      m_Plane->SetTransform((vtkAbstractTransform*)NULL);
    }
    else
    {
      AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldPlaneGeometry());
      if(worldAbstractGeometry.IsNotNull())
      {
        AbstractTransformGeometry::ConstPointer surfaceAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(input->GetTimeGeometry()->GetGeometryForTimeStep(0).GetPointer());
        if(surfaceAbstractGeometry.IsNotNull()) //@todo substitude by operator== after implementation, see bug id 28
        {
          PaintCells(renderer, vtkpolydata, worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut);
          return;
        }
        else
        {
          //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "flat plane" into a "curved plane"?
          return;
          // set up vtkPlane according to worldGeometry
          point=const_cast<BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
          FillVector3D(normal, 0, 0, 1);
          m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
        }
      }
      else
        return;
    }

    double vp[3], vnormal[3];

    vnl2vtk(point.GetVnlVector(), vp);
    vnl2vtk(normal.GetVnlVector(), vnormal);

    //normally, we would need to transform the surface and cut the transformed surface with the cutter.
    //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
    //@todo It probably does not work for scaling operations yet:scaling operations have to be
    //dealed with after the cut is performed by scaling the contour.
    vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();
    inversetransform->TransformPoint(vp, vp);
    inversetransform->TransformNormalAtPoint(vp, vnormal, vnormal);

    m_Plane->SetOrigin(vp);
    m_Plane->SetNormal(vnormal);

    //set data into cutter
    m_Cutter->SetInputData(vtkpolydata);
    m_Cutter->Update();
    //    m_Cutter->GenerateCutScalarsOff();
    //    m_Cutter->SetSortByToSortByCell();

    if (m_DrawNormals)
    {
      m_Stripper->SetInputData( m_Cutter->GetOutput() );
      // calculate the cut
      m_Stripper->Update();
      PaintCells(renderer, m_Stripper->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
    }
    else
    {
      PaintCells(renderer, m_Cutter->GetOutput(), worldGeometry, renderer->GetDisplayGeometry(), vtktransform, lut, vtkpolydata);
    }
  }
}
void mitk::VectorImageMapper2D::Paint( mitk::BaseRenderer * renderer )
{
  //std::cout << "2d vector mapping..." << std::endl;

  bool visible = true;
  GetDataNode()->GetVisibility(visible, renderer, "visible");

  if ( !visible )
    return ;

  mitk::Image::Pointer input = const_cast<mitk::Image*>( this->GetInput() );

  if ( input.IsNull() )
    return ;


  mitk::PlaneGeometry::Pointer worldPlaneGeometry2D = dynamic_cast< mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>( renderer->GetCurrentWorldGeometry2D() ) );
  assert( worldPlaneGeometry2D.IsNotNull() );

  vtkImageData* vtkImage = input->GetVtkImageData( this->GetCurrentTimeStep( input, renderer ) );

  //
  // set up the cutter orientation according to the current geometry of
  // the renderers plane
  //
  Point3D point;
  Vector3D normal;
  Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
  PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );

  if ( worldPlaneGeometry.IsNotNull() )
  {
    // set up vtkPlane according to worldGeometry
    point = worldPlaneGeometry->GetOrigin();
    normal = worldPlaneGeometry->GetNormal(); normal.Normalize();
    m_Plane->SetTransform( (vtkAbstractTransform*)NULL );
  }
  else
  {
    itkWarningMacro( << "worldPlaneGeometry is NULL!" );
    return ;
  }

  double vp[ 3 ], vp_slice[ 3 ], vnormal[ 3 ];
  vnl2vtk( point.GetVnlVector(), vp );
  vnl2vtk( normal.GetVnlVector(), vnormal );
  //std::cout << "Origin: " << vp[0] <<" "<< vp[1] <<" "<< vp[2] << std::endl;
  //std::cout << "Normal: " << vnormal[0] <<" "<< vnormal[1] <<" "<< vnormal[2] << std::endl;

  //normally, we would need to transform the surface and cut the transformed surface with the cutter.
  //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
  //@todo It probably does not work for scaling operations yet:scaling operations have to be
  //dealed with after the cut is performed by scaling the contour.
  vtkLinearTransform * vtktransform = GetDataNode() ->GetVtkTransform();

  vtkTransform* world2vtk = vtkTransform::New();
  world2vtk->Identity();
  world2vtk->Concatenate(vtktransform->GetLinearInverse());
  double myscale[3];
  world2vtk->GetScale(myscale);
  world2vtk->PostMultiply();
  world2vtk->Scale(1/myscale[0],1/myscale[1],1/myscale[2]);
  world2vtk->TransformPoint( vp, vp );
  world2vtk->TransformNormalAtPoint( vp, vnormal, vnormal );
  world2vtk->Delete();

    // vtk works in axis align coords
  // thus the normal also must be axis align, since
  // we do not allow arbitrary cutting through volume
  //
  // vnormal should already be axis align, but in order
  // to get rid of precision effects, we set the two smaller
  // components to zero here
  int dims[3];
  vtkImage->GetDimensions(dims);
  double spac[3];
  vtkImage->GetSpacing(spac);
  vp_slice[0] = vp[0];
  vp_slice[1] = vp[1];
  vp_slice[2] = vp[2];
  if(fabs(vnormal[0]) > fabs(vnormal[1]) && fabs(vnormal[0]) > fabs(vnormal[2]) )
  {
    if(fabs(vp_slice[0]/spac[0]) < 0.4)
      vp_slice[0] = 0.4*spac[0];
    if(fabs(vp_slice[0]/spac[0]) > (dims[0]-1)-0.4)
      vp_slice[0] = ((dims[0]-1)-0.4)*spac[0];
    vnormal[1] = 0;
    vnormal[2] = 0;
  }

  if(fabs(vnormal[1]) > fabs(vnormal[0]) && fabs(vnormal[1]) > fabs(vnormal[2]) )
  {
    if(fabs(vp_slice[1]/spac[1]) < 0.4)
      vp_slice[1] = 0.4*spac[1];
    if(fabs(vp_slice[1]/spac[1]) > (dims[1]-1)-0.4)
      vp_slice[1] = ((dims[1]-1)-0.4)*spac[1];
    vnormal[0] = 0;
    vnormal[2] = 0;
  }

  if(fabs(vnormal[2]) > fabs(vnormal[1]) && fabs(vnormal[2]) > fabs(vnormal[0]) )
  {
    if(fabs(vp_slice[2]/spac[2]) < 0.4)
      vp_slice[2] = 0.4*spac[2];
    if(fabs(vp_slice[2]/spac[2]) > (dims[2]-1)-0.4)
      vp_slice[2] = ((dims[2]-1)-0.4)*spac[2];
    vnormal[0] = 0;
    vnormal[1] = 0;
  }


  m_Plane->SetOrigin( vp_slice );
  m_Plane->SetNormal( vnormal );

  vtkPolyData* cuttedPlane;
  if(!( (dims[0] == 1 && vnormal[0] != 0) ||
        (dims[1] == 1 && vnormal[1] != 0) ||
        (dims[2] == 1 && vnormal[2] != 0) ))
  {
    m_Cutter->SetCutFunction( m_Plane );
    m_Cutter->SetInputData( vtkImage );
    m_Cutter->GenerateCutScalarsOff();//!
    m_Cutter->Update();
    cuttedPlane = m_Cutter->GetOutput();
  }
  else
  {
    // cutting of a 2D-Volume does not work,
    // so we have to build up our own polydata object
    cuttedPlane = vtkPolyData::New();
    vtkPoints* points = vtkPoints::New();
    points->SetNumberOfPoints(vtkImage->GetNumberOfPoints());
    for(int i=0; i<vtkImage->GetNumberOfPoints(); i++)
      points->SetPoint(i, vtkImage->GetPoint(i));
    cuttedPlane->SetPoints(points);
    vtkFloatArray* pointdata = vtkFloatArray::New();
    int comps  = vtkImage->GetPointData()->GetScalars()->GetNumberOfComponents();
    pointdata->SetNumberOfComponents(comps);
    int tuples = vtkImage->GetPointData()->GetScalars()->GetNumberOfTuples();
    pointdata->SetNumberOfTuples(tuples);
    for(int i=0; i<tuples; i++)
      pointdata->SetTuple(i,vtkImage->GetPointData()->GetScalars()->GetTuple(i));
    pointdata->SetName( "vector" );
    cuttedPlane->GetPointData()->AddArray(pointdata);
  }

  if ( cuttedPlane->GetNumberOfPoints() != 0)
  {
    //
    // make sure, that we have point data with more than 1 component (as vectors)
    //
    vtkPointData * pointData = cuttedPlane->GetPointData();
    if ( pointData == NULL )
    {
      itkWarningMacro( << "no point data associated with cutters result!" );
      return ;
    }
bool AffineInteractor3D
::ExecuteAction( Action *action, StateEvent const *stateEvent )
{
  bool ok = false;

  // Get data object
  BaseData *data = m_DataNode->GetData();
  if ( data == NULL )
  {
    MITK_ERROR << "No data object present!";
    return ok;
  }

  // Get Event and extract renderer
  const Event *event = stateEvent->GetEvent();
  BaseRenderer *renderer = NULL;
  vtkRenderWindow *renderWindow = NULL;
  vtkRenderWindowInteractor *renderWindowInteractor = NULL;
  vtkRenderer *currentVtkRenderer = NULL;
  vtkCamera *camera = NULL;

  if ( event != NULL )
  {
    renderer = event->GetSender();
    if ( renderer != NULL )
    {
      renderWindow = renderer->GetRenderWindow();
      if ( renderWindow != NULL )
      {
        renderWindowInteractor = renderWindow->GetInteractor();
        if ( renderWindowInteractor != NULL )
        {
          currentVtkRenderer = renderWindowInteractor
            ->GetInteractorStyle()->GetCurrentRenderer();
          if ( currentVtkRenderer != NULL )
          {
            camera = currentVtkRenderer->GetActiveCamera();
          }
        }
      }
    }
  }

  // Check if we have a DisplayPositionEvent
  const DisplayPositionEvent *dpe =
    dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
  if ( dpe != NULL )
  {
    m_CurrentPickedPoint = dpe->GetWorldPosition();
    m_CurrentPickedDisplayPoint = dpe->GetDisplayPosition();
  }

  // Get the timestep to also support 3D+t
  int timeStep = 0;
  ScalarType timeInMS = 0.0;
  if ( renderer != NULL )
  {
    timeStep = renderer->GetTimeStep( data );
    timeInMS = renderer->GetTime();
  }

  // If data is an mitk::Surface, extract it
  Surface *surface = dynamic_cast< Surface * >( data );
  vtkPolyData *polyData = NULL;
  if ( surface != NULL )
  {
    polyData = surface->GetVtkPolyData( timeStep );

    // Extract surface normal from surface (if existent, otherwise use default)
    vtkPointData *pointData = polyData->GetPointData();
    if ( pointData != NULL )
    {
      vtkDataArray *normal = polyData->GetPointData()->GetVectors( "planeNormal" );
      if ( normal != NULL )
      {
        m_ObjectNormal[0] = normal->GetComponent( 0, 0 );
        m_ObjectNormal[1] = normal->GetComponent( 0, 1 );
        m_ObjectNormal[2] = normal->GetComponent( 0, 2 );
      }
    }
  }

  // Get geometry object
  m_Geometry = data->GetGeometry( timeStep );


  // Make sure that the data (if time-resolved) has enough entries;
  // if not, create the required extra ones (empty)
  data->Expand( timeStep+1 );


  switch (action->GetActionId())
  {
  case AcDONOTHING:
    ok = true;
    break;


  case AcCHECKOBJECT:
    {
      // Re-enable VTK interactor (may have been disabled previously)
      if ( renderWindowInteractor != NULL )
      {
        renderWindowInteractor->Enable();
      }

      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      // Check if an object is present at the current mouse position
      DataNode *pickedNode = dpe->GetPickedObjectNode();
      StateEvent *newStateEvent;
      if ( pickedNode == m_DataNode )
      {
        // Yes: object will be selected
        newStateEvent = new StateEvent( EIDYES );
      }
      else
      {
        // No: back to start state
        newStateEvent = new StateEvent( EIDNO );
      }

      this->HandleEvent( newStateEvent );

      ok = true;
      break;
    }

  case AcDESELECTOBJECT:
    {
      // Color object white
      m_DataNode->SetColor( 1.0, 1.0, 1.0 );
      RenderingManager::GetInstance()->RequestUpdateAll();

      // Colorize surface / wireframe as inactive
      this->ColorizeSurface( polyData,
        m_CurrentPickedPoint, -1.0 );

      ok = true;
      break;
    }

  case AcSELECTPICKEDOBJECT:
    {
      // Color object red
      m_DataNode->SetColor( 1.0, 0.0, 0.0 );
      RenderingManager::GetInstance()->RequestUpdateAll();

      // Colorize surface / wireframe dependend on distance from picked point
      this->ColorizeSurface( polyData,
        m_CurrentPickedPoint, 0.0 );

      ok = true;
      break;
    }

  case AcINITMOVE:
    {
      // Disable VTK interactor until MITK interaction has been completed
      if ( renderWindowInteractor != NULL )
      {
        renderWindowInteractor->Disable();
      }

      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      //DataNode *pickedNode = dpe->GetPickedObjectNode();

      m_InitialPickedPoint = m_CurrentPickedPoint;
      m_InitialPickedDisplayPoint = m_CurrentPickedDisplayPoint;

      if ( currentVtkRenderer != NULL )
      {
        vtkInteractorObserver::ComputeDisplayToWorld(
          currentVtkRenderer,
          m_InitialPickedDisplayPoint[0],
          m_InitialPickedDisplayPoint[1],
          0.0, //m_InitialInteractionPickedPoint[2],
          m_InitialPickedPointWorld );
      }


      // Make deep copy of current Geometry3D of the plane
      data->UpdateOutputInformation(); // make sure that the Geometry is up-to-date
      m_OriginalGeometry = static_cast< Geometry3D * >(
        data->GetGeometry( timeStep )->Clone().GetPointer() );

      ok = true;
      break;
    }

  case AcMOVE:
    {
      // Check if we have a DisplayPositionEvent
      const DisplayPositionEvent *dpe =
        dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );
      if ( dpe == NULL )
      {
        ok = true;
        break;
      }

      if ( currentVtkRenderer != NULL )
      {
        vtkInteractorObserver::ComputeDisplayToWorld(
          currentVtkRenderer,
          m_CurrentPickedDisplayPoint[0],
          m_CurrentPickedDisplayPoint[1],
          0.0, //m_InitialInteractionPickedPoint[2],
          m_CurrentPickedPointWorld );
      }


      Vector3D interactionMove;
      interactionMove[0] = m_CurrentPickedPointWorld[0] - m_InitialPickedPointWorld[0];
      interactionMove[1] = m_CurrentPickedPointWorld[1] - m_InitialPickedPointWorld[1];
      interactionMove[2] = m_CurrentPickedPointWorld[2] - m_InitialPickedPointWorld[2];

      if ( m_InteractionMode == INTERACTION_MODE_TRANSLATION )
      {
        Point3D origin = m_OriginalGeometry->GetOrigin();

        Vector3D transformedObjectNormal;
        data->GetGeometry( timeStep )->IndexToWorld(
          m_ObjectNormal, transformedObjectNormal );

        data->GetGeometry( timeStep )->SetOrigin(
          origin + transformedObjectNormal * (interactionMove * transformedObjectNormal) );
      }
      else if ( m_InteractionMode == INTERACTION_MODE_ROTATION )
      {
        if ( camera )
        {
          double vpn[3];
          camera->GetViewPlaneNormal( vpn );

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

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

          int *size = currentVtkRenderer->GetSize();
          double l2 =
            (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) *
            (m_CurrentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) +
            (m_CurrentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) *
            (m_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();;

          // 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 );
          data->SetClonedGeometry(newGeometry, timeStep);
        }
      }

      RenderingManager::GetInstance()->RequestUpdateAll();
      ok = true;
      break;
    }



  default:
    return Superclass::ExecuteAction( action, stateEvent );
  }

  return ok;
}
void mitk::UnstructuredGridMapper2D::Paint( mitk::BaseRenderer* renderer )
{
  if ( IsVisible( renderer ) == false )
    return ;

  vtkLinearTransform * vtktransform = GetDataNode()->GetVtkTransform();
  vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();

  Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
  PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );

  Point3D point;
  Vector3D normal;

  if(worldPlaneGeometry.IsNotNull())
  {
    // set up vtkPlane according to worldGeometry
    point=worldPlaneGeometry->GetOrigin();
    normal=worldPlaneGeometry->GetNormal(); normal.Normalize();
    m_Plane->SetTransform((vtkAbstractTransform*)NULL);
  }
  else
  {
    //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"?
    return;
    AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>(renderer->GetCurrentWorldGeometry2D());
    if(worldAbstractGeometry.IsNotNull())
    {
      // set up vtkPlane according to worldGeometry
      point=const_cast<mitk::BoundingBox*>(worldAbstractGeometry->GetParametricBoundingBox())->GetMinimum();
      FillVector3D(normal, 0, 0, 1);
      m_Plane->SetTransform(worldAbstractGeometry->GetVtkAbstractTransform()->GetInverse());
    }
    else
      return;
  }

  vtkFloatingPointType vp[ 3 ], vnormal[ 3 ];

  vnl2vtk(point.Get_vnl_vector(), vp);
  vnl2vtk(normal.Get_vnl_vector(), vnormal);

  //normally, we would need to transform the surface and cut the transformed surface with the cutter.
  //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
  //@todo It probably does not work for scaling operations yet:scaling operations have to be
  //dealed with after the cut is performed by scaling the contour.
  inversetransform->TransformPoint( vp, vp );
  inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal );

  m_Plane->SetOrigin( vp );
  m_Plane->SetNormal( vnormal );

  // set data into cutter
  m_Slicer->SetInput( m_VtkPointSet );
  //    m_Cutter->GenerateCutScalarsOff();
  //    m_Cutter->SetSortByToSortByCell();

  // calculate the cut
  m_Slicer->Update();

  // fetch geometry
  mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
  assert( displayGeometry );
  //  float toGL=displayGeometry->GetSizeInDisplayUnits()[1];

  //apply color and opacity read from the PropertyList
  ApplyProperties( renderer );

  // traverse the cut contour
  vtkPolyData * contour = m_Slicer->GetOutput();

  vtkPoints *vpoints = contour->GetPoints();
  vtkCellArray *vlines = contour->GetLines();
  vtkCellArray *vpolys = contour->GetPolys();
  vtkPointData *vpointdata = contour->GetPointData();
  vtkDataArray* vscalars = vpointdata->GetScalars();

  vtkCellData *vcelldata = contour->GetCellData();
  vtkDataArray* vcellscalars = vcelldata->GetScalars();

  const int numberOfLines = contour->GetNumberOfLines();
  const int numberOfPolys = contour->GetNumberOfPolys();

  const bool useCellData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT ||
              m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA;
  const bool usePointData = m_ScalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA;

  Point3D p;
  Point2D p2d;

  vlines->InitTraversal();
  vpolys->InitTraversal();
  
  mitk::Color outlineColor = m_Color->GetColor();

  glLineWidth((float)m_LineWidth->GetValue());

  for (int i = 0;i < numberOfLines;++i )
  {
    vtkIdType *cell(0);
    vtkIdType cellSize(0);

    vlines->GetNextCell( cellSize, cell );

    float rgba[4] = {outlineColor[0], outlineColor[1], outlineColor[2], 1.0f};
    if (m_ScalarVisibility->GetValue() && vcellscalars)
    {
      if ( useCellData )
      {  // color each cell according to cell data
        double scalar = vcellscalars->GetComponent( i, 0 );
        double rgb[3] = { 1.0f, 1.0f, 1.0f };
        m_ScalarsToColors->GetColor(scalar, rgb);
        rgba[0] = (float)rgb[0];
        rgba[1] = (float)rgb[1];
        rgba[2] = (float)rgb[2];
        rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar);
      }
      else if ( usePointData )
      {
        double scalar = vscalars->GetComponent( i, 0 );
        double rgb[3] = { 1.0f, 1.0f, 1.0f };
        m_ScalarsToColors->GetColor(scalar, rgb);
        rgba[0] = (float)rgb[0];
        rgba[1] = (float)rgb[1];
        rgba[2] = (float)rgb[2];
        rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar);
      }
    }
    
    glColor4fv( rgba );
    
    glBegin ( GL_LINE_LOOP );
    for ( int j = 0;j < cellSize;++j )
    {
      vpoints->GetPoint( cell[ j ], vp );
      //take transformation via vtktransform into account
      vtktransform->TransformPoint( vp, vp );

      vtk2itk( vp, p );

      //convert 3D point (in mm) to 2D point on slice (also in mm)
      worldGeometry->Map( p, p2d );

      //convert point (until now mm and in worldcoordinates) to display coordinates (units )
      displayGeometry->WorldToDisplay( p2d, p2d );

      //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
      //p2d[1]=toGL-p2d[1];

      //add the current vertex to the line
      glVertex2f( p2d[0], p2d[1] );
    }
    glEnd ();

  }
  
  bool polyOutline = m_Outline->GetValue();
  bool scalarVisibility = m_ScalarVisibility->GetValue();

  // only draw polygons if there are cell scalars
  // or the outline property is set to true
  if ((scalarVisibility && vcellscalars) || polyOutline)
  {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    // cache the transformed points
    // a fixed size array is way faster than 'new'
    // slices through 3d cells usually do not generated
    // polygons with more than 6 vertices
    Point2D cachedPoints[10];

    for (int i = 0;i < numberOfPolys;++i )
    {
      vtkIdType *cell(0);
      vtkIdType cellSize(0);

      vpolys->GetNextCell( cellSize, cell );

      float rgba[4] = {1.0f, 1.0f, 1.0f, 0};
      if (scalarVisibility && vcellscalars)
      {
        if ( useCellData )
        {  // color each cell according to cell data
          double scalar = vcellscalars->GetComponent( i, 0 );
          double rgb[3] = { 1.0f, 1.0f, 1.0f };
          m_ScalarsToColors->GetColor(scalar, rgb);
          rgba[0] = (float)rgb[0];
          rgba[1] = (float)rgb[1];
          rgba[2] = (float)rgb[2];
          rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar);
        }
        else if ( usePointData )
        {
          double scalar = vscalars->GetComponent( i, 0 );
          double rgb[3] = { 1.0f, 1.0f, 1.0f };
          m_ScalarsToColors->GetColor(scalar, rgb);
          rgba[0] = (float)rgb[0];
          rgba[1] = (float)rgb[1];
          rgba[2] = (float)rgb[2];
          rgba[3] = (float)m_ScalarsToOpacity->GetValue(scalar);
        }
      }
      glColor4fv( rgba );

      glBegin( GL_POLYGON );
      for (int j = 0; j < cellSize; ++j)
      {
        vpoints->GetPoint( cell[ j ], vp );
        //take transformation via vtktransform into account
        vtktransform->TransformPoint( vp, vp );

        vtk2itk( vp, p );

        //convert 3D point (in mm) to 2D point on slice (also in mm)
        worldGeometry->Map( p, p2d );

        //convert point (until now mm and in worldcoordinates) to display coordinates (units )
        displayGeometry->WorldToDisplay( p2d, p2d );

        //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
        //p2d[1]=toGL-p2d[1];

        cachedPoints[j][0] = p2d[0];
        cachedPoints[j][1] = p2d[1];

        //add the current vertex to the line
        glVertex2f( p2d[0], p2d[1] );
      }
      glEnd();

      if (polyOutline)
      {
        glColor4f(outlineColor[0], outlineColor[1], outlineColor[2], 1.0f);

        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glBegin( GL_POLYGON );
        //glPolygonOffset(1.0, 1.0);
        for (int j = 0; j < cellSize; ++j)
        {
          //add the current vertex to the line
          glVertex2f( cachedPoints[j][0], cachedPoints[j][1] );
        }
        glEnd();
      }
    }
    glDisable(GL_BLEND);
  }
}
// Fills a polygon using a texture, gouraud shading and a normal map given 3 points and a color.
void Rasterizer::FillPolygonTexturedNormalMapped(Vertex v1, Vertex v2, Vertex v3, Gdiplus::Color color, Model3D& model, std::vector<DirectionalLight*> directionalLights, std::vector<AmbientLight*> ambientLights, std::vector<PointLight*> pointLights)
{
	ScanLine* _scanlines = new ScanLine[_height];

	BYTE* texture;
	Gdiplus::Color* palette;
	BYTE* normalTexture;
	Gdiplus::Color* normalPalette;
	int textureWidth;

	// Get the texture properties of the model.
	model.GetTexture(&texture, &palette, &textureWidth); 
	model.GetNormalMapTexture(&normalTexture, &normalPalette, &textureWidth); 
	
	// Set the scanlines to very high and very low values so
	// they will be set on the first set of interpolation.
	for (unsigned int i = 0; i < _height; i++)
	{
		_scanlines[i].xStart = 99999;
		_scanlines[i].xEnd = -99999;
	}

	// Interpolates between each of the vertexs of the polygon and sets the start
	// and end values for each of the scanlines it comes in contact with.
	InterpolateScanline(_scanlines, v1, v2);
	InterpolateScanline(_scanlines, v2, v3);
	InterpolateScanline(_scanlines, v3, v1);

	// Go through each scanline and each pixel in the scanline and 
	// sets its color.
	for (unsigned int y = 0; y < _height; y++)
	{
		// Work out the color and UV differences between the start and end of the scanline.
		float redColorDiff = (_scanlines[y].redEnd - _scanlines[y].redStart);
		float greenColorDiff = (_scanlines[y].greenEnd - _scanlines[y].greenStart);
		float blueColorDiff = (_scanlines[y].blueEnd - _scanlines[y].blueStart);
		float uCoordDiff = _scanlines[y].uEnd - _scanlines[y].uStart;
		float vCoordDiff = _scanlines[y].vEnd - _scanlines[y].vStart;
		float zCoordDiff = _scanlines[y].zEnd - _scanlines[y].zStart;

		float xNormalDiff = (_scanlines[y].xNormalEnd - _scanlines[y].xNormalStart);
		float yNormalDiff = (_scanlines[y].yNormalEnd - _scanlines[y].yNormalStart);
		float zNormalDiff = (_scanlines[y].zNormalEnd - _scanlines[y].zNormalStart);

		float xDiff = (_scanlines[y].pixelXEnd - _scanlines[y].pixelXStart);
		float yDiff = (_scanlines[y].pixelYEnd - _scanlines[y].pixelYStart);
		float zDiff = (_scanlines[y].pixelZEnd - _scanlines[y].pixelZStart);

		float diff = (_scanlines[y].xEnd - _scanlines[y].xStart) + 1;

		for (int x = (int)_scanlines[y].xStart; x <= (int)_scanlines[y].xEnd; x++)
		{
			if (x < 0 || x >= (int)_width)
				continue;

			int offset = (int)(x - _scanlines[y].xStart);
			
			// Work out the UV coordinate of the current pixel.
			float uCoord = _scanlines[y].uStart + ((uCoordDiff / diff) * offset);
			float vCoord = _scanlines[y].vStart + ((vCoordDiff / diff) * offset);
			float zCoord = _scanlines[y].zStart + ((zCoordDiff / diff) * offset);

			uCoord /= zCoord;
			vCoord /= zCoord;

			// Work out the normal of the pixel.
			float xNormal = _scanlines[y].xNormalStart + ((xNormalDiff / diff) * offset);
			float yNormal = _scanlines[y].yNormalStart + ((yNormalDiff / diff) * offset);
			float zNormal = _scanlines[y].zNormalStart + ((zNormalDiff / diff) * offset);

			// Work out the position of the pixel.
			float pixelX = _scanlines[y].pixelXStart + ((xDiff / diff) * offset);
			float pixelY = _scanlines[y].pixelYStart + ((yDiff / diff) * offset);
			float pixelZ = _scanlines[y].pixelZStart + ((zDiff / diff) * offset);

			// Work out the lighting colour of the current pixel.
			//float lightR = (_scanlines[y].redStart + ((redColorDiff / diff) * offset)) / 180.0f;
			//float lightG = (_scanlines[y].greenStart + ((greenColorDiff / diff) * offset)) / 180.0f;
			//float lightB = (_scanlines[y].blueStart + ((blueColorDiff / diff) * offset)) / 180.0f;	

			// Using the UV coordinate work out which pixel in the texture to use to draw this pixel.
			int pixelIndex = (int)vCoord * textureWidth + (int)uCoord;
			if (pixelIndex >= textureWidth * textureWidth || pixelIndex < 0)
			{
				pixelIndex = (textureWidth * textureWidth) - 1;
			}

			int paletteOffset = texture[pixelIndex]; 
			if (paletteOffset >= 255)
				paletteOffset = 255;

			Gdiplus::Color textureColor = palette[paletteOffset];

			// Work out the pixel colour of the normalmap.
			pixelIndex = (int)vCoord * textureWidth + (int)uCoord;
			if (pixelIndex >= textureWidth * textureWidth || pixelIndex < 0)
			{
				pixelIndex = (textureWidth * textureWidth) - 1;
			}

			paletteOffset = normalTexture[pixelIndex]; 
			if (paletteOffset >= 255)
				paletteOffset = 255;

			Gdiplus::Color normalTextureColor = normalPalette[paletteOffset];

			// Calculate normal lighting for the pixel.
			Vector3D heightMapVector = Vector3D(normalTextureColor.GetR() / 180.0f, normalTextureColor.GetG() / 180.0f, normalTextureColor.GetB() / 180.0f); 
			heightMapVector = Vector3D((heightMapVector.GetX() - 0.5f) * 2.0f, (heightMapVector.GetY() - 0.5f) * 2.0f, (heightMapVector.GetZ() - 0.5f) * 2.0f);

			// Work out he pixels normal and position.
			Vector3D pixelNormal = Vector3D(xNormal, yNormal, zNormal);//;Vector3D(heightMapVector.GetX(), heightMapVector.GetY(), heightMapVector.GetZ());
			Vertex pixelPosition = Vertex(pixelX, pixelY, pixelZ, 1, Gdiplus::Color::White, Vector3D(0, 0, 0), 0);

			heightMapVector = Vector3D((pixelNormal.GetX() * heightMapVector.GetX()) , 
										(pixelNormal.GetY() * heightMapVector.GetY()) , 
										(pixelNormal.GetZ() * heightMapVector.GetZ()) );

			// Calculate the sum dot product of all lighting vectors for this pixel and divide by the number
			// of lights.
			float lightDot = 0.0f;
			int count = 0;
			for (unsigned int j = 0; j < pointLights.size(); j++)
			{
				PointLight* light = pointLights[j];
				if (light->GetEnabled() == false)
					continue;
			
				// Work out vector to light source.
				Vector3D lightVector = Vertex::GetVector(pixelPosition, light->GetPosition());
				float distance = lightVector.GetLength();
				lightVector.Normalize();

				// Work out dot product.
				lightDot += Vector3D::DotProduct(heightMapVector, lightVector);
				count++;
			}
			for (unsigned int j = 0; j < directionalLights.size(); j++)
			{
				DirectionalLight* light = directionalLights[j];
				if (light->GetEnabled() == false)
					continue;
			
				// Work out vector to light source.
				Vector3D lightVector = Vertex::GetVector(pixelPosition, light->GetPosition());
				float distance = lightVector.GetLength();
				lightVector.Normalize();

				// Work out dot product.
				lightDot += Vector3D::DotProduct(heightMapVector, lightVector);
				count++;
			}
			lightDot /= count;

			// Adjust texture colour based on the lighting dot product.
			Gdiplus::Color pixelColor = textureColor;
			//pixelColor = model.CalculateLightingAmbientPerPixel(ambientLights, pixelPosition, pixelNormal, pixelColor);
			//pixelColor = model.CalculateLightingDirectionalPerPixel(directionalLights, pixelPosition, pixelNormal, pixelColor);
			//pixelColor = model.CalculateLightingPointPerPixel(pointLights, pixelPosition, pixelNormal, pixelColor);

			float lightR = (_scanlines[y].redStart + ((redColorDiff / diff) * offset)) / 180.0f;
			float lightG = (_scanlines[y].greenStart + ((greenColorDiff / diff) * offset)) / 180.0f;
			float lightB = (_scanlines[y].blueStart + ((blueColorDiff / diff) * offset)) / 180.0f;	

			// Apply the lighting value to the texture colour and use the result to set the colour of the current pixel.
			int finalR = (int)max(0, min(255, (lightR * textureColor.GetR()) - ((lightR * textureColor.GetR()) * lightDot) ));
			int finalG = (int)max(0, min(255, (lightG * textureColor.GetG()) - ((lightG * textureColor.GetG()) * lightDot) ));
			int finalB = (int)max(0, min(255, (lightB * textureColor.GetB()) - ((lightB * textureColor.GetB()) * lightDot) ));

			WritePixel(x, y, Gdiplus::Color(finalR, finalG, finalB));
		}
	}
	
	// Dispose of dynamic objects.
	delete[] _scanlines;

	_polygonsRendered++;
}
void mitk::SurfaceGLMapper2D::PaintCells(mitk::BaseRenderer* renderer, vtkPolyData* contour,
                                       const PlaneGeometry* worldGeometry,
                                       const DisplayGeometry* displayGeometry,
                                       vtkLinearTransform * vtktransform,
                                       vtkLookupTable *lut,
                                       vtkPolyData* original3DObject)
{
  // deprecated settings
  bool usePointData = false;

  bool useCellData = false;
  this->GetDataNode()->GetBoolProperty("deprecated useCellDataForColouring", useCellData, renderer);

  bool scalarVisibility = false;
  this->GetDataNode()->GetBoolProperty("scalar visibility", scalarVisibility, renderer);

  if(scalarVisibility)
  {
    VtkScalarModeProperty* scalarMode;
    if(this->GetDataNode()->GetProperty(scalarMode, "scalar mode", renderer))
    {
      if( (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_POINT_DATA) ||
        (scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_DEFAULT) )
      {
        usePointData = true;
      }
      if(scalarMode->GetVtkScalarMode() == VTK_SCALAR_MODE_USE_CELL_DATA)
      {
        useCellData = true;
      }
    }
    else
    {
      usePointData = true;
    }
  }

  vtkPoints    *vpoints = contour->GetPoints();
  vtkDataArray *vpointscalars = contour->GetPointData()->GetScalars();

  vtkCellArray *vlines  = contour->GetLines();
  vtkDataArray* vcellscalars = contour->GetCellData()->GetScalars();

  Point3D p; Point2D p2d, last;
  int i, j;
  int numberOfLines = vlines->GetNumberOfCells();

  glLineWidth( m_LineWidth );
  glBegin (GL_LINES);

  glColor4fv(m_LineColor);

  double distanceSinceLastNormal(0.0);

  vlines->InitTraversal();
  for(i=0;i<numberOfLines;++i)
  {
    vtkIdType *cell(NULL);
    vtkIdType cellSize(0);
    double vp[3];

    vlines->GetNextCell(cellSize, cell);

    vpoints->GetPoint(cell[0], vp);
    //take transformation via vtktransform into account
    vtktransform->TransformPoint(vp, vp);
    vtk2itk(vp, p);

    //convert 3D point (in mm) to 2D point on slice (also in mm)
    worldGeometry->Map(p, p2d);

    //convert point (until now mm and in world coordinates) to display coordinates (units )
    displayGeometry->WorldToDisplay(p2d, p2d);
    last=p2d;

    for(j=1; j<cellSize; ++j)
    {
      vpoints->GetPoint(cell[j], vp);
      Point3D originalPoint;
      vtk2itk(vp, originalPoint);
      //take transformation via vtktransform into account
      vtktransform->TransformPoint(vp, vp);
      vtk2itk(vp, p);

      //convert 3D point (in mm) to 2D point on slice (also in mm)
      worldGeometry->Map(p, p2d);

      //convert point (until now mm and in world coordinates) to display coordinates (units )
      displayGeometry->WorldToDisplay(p2d, p2d);

      double color[3];
      if (useCellData && vcellscalars != NULL )
      {
        // color each cell according to cell data
        lut->GetColor( vcellscalars->GetComponent(i,0),color);
        glColor3f(color[0],color[1],color[2]);
        glVertex2f(last[0], last[1]);
        glVertex2f(p2d[0], p2d[1]);
      }
      else if (usePointData && vpointscalars != NULL )
      {
        lut->GetColor( vpointscalars->GetComponent(cell[j-1],0),color);
        glColor3f(color[0],color[1],color[2]);
        glVertex2f(last[0], last[1]);
        lut->GetColor( vpointscalars->GetComponent(cell[j],0),color);
        glColor3f(color[0],color[1],color[2]);
        glVertex2f(p2d[0], p2d[1]);
      }
      else
      {
        glVertex2f(last[0], last[1]);
        glVertex2f(p2d[0], p2d[1]);

        // draw normals ?
        if (m_DrawNormals && original3DObject)
        {
          distanceSinceLastNormal += sqrt((p2d[0]-last[0])*(p2d[0]-last[0]) + (p2d[1]-last[1])*(p2d[1]-last[1]));
          if (distanceSinceLastNormal >= 5.0)
          {
            distanceSinceLastNormal = 0.0;

            vtkPointData* pointData = original3DObject->GetPointData();
            if (!pointData) break;

            vtkDataArray* normalsArray = pointData->GetNormals();
            if (!normalsArray) break;

            // find 3D point closest to the currently drawn point
            double distance(0.0);
            vtkIdType closestPointId = m_PointLocator->FindClosestPoint(originalPoint[0], originalPoint[1], originalPoint[2], distance);
            if (closestPointId >= 0)
            {
              // find normal of 3D object at this 3D point
              double* normal = normalsArray->GetTuple3(closestPointId);
              double transformedNormal[3];
              vtktransform->TransformNormal(normal, transformedNormal);

              Vector3D normalITK;
              vtk2itk(transformedNormal, normalITK);
              normalITK.Normalize();

              // calculate a point (point from the cut 3D object) + (normal vector of closest point)
              Point3D tip3D = p + normalITK;

              // map this point into our 2D coordinate system
              Point2D tip2D;
              worldGeometry->Map(tip3D, tip2D);

              displayGeometry->WorldToDisplay(tip2D, tip2D);

              // calculate 2D vector from point to point+normal, normalize it to standard length
              Vector2D tipVectorGLFront = tip2D - p2d;
              tipVectorGLFront.Normalize();
              tipVectorGLFront *= m_FrontNormalLengthInPixels;

              Vector2D tipVectorGLBack = p2d - tip2D;
              tipVectorGLBack.Normalize();
              tipVectorGLBack *= m_BackNormalLengthInPixels;

              Point2D tipPoint2D = p2d + tipVectorGLFront;
              Point2D backTipPoint2D = p2d + tipVectorGLBack;

              // draw normalized mapped normal vector
              glColor4f(m_BackSideColor[0], m_BackSideColor[1], m_BackSideColor[2], m_BackSideColor[3]); // red backside
              glVertex2f(p2d[0], p2d[1]);
              glVertex2f(tipPoint2D[0], tipPoint2D[1]);
              glColor4f(m_FrontSideColor[0], m_FrontSideColor[1], m_FrontSideColor[2], m_FrontSideColor[3]); // green backside
              glVertex2f(p2d[0], p2d[1]);
              glVertex2f(backTipPoint2D[0], backTipPoint2D[1]);
              glColor4fv(m_LineColor); // back to line color
            }
          }
        }
      }
      last=p2d;
    }
  }

  glEnd();
  glLineWidth(1.0);
}
void mitk::ExtrudePlanarFigureFilter::GenerateData()
{
  typedef PlanarFigure::PolyLineType PolyLine;
  typedef PolyLine::const_iterator PolyLineConstIter;

  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!";

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

  if (input == NULL)
    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 PlaneGeometry* planeGeometry = dynamic_cast<const PlaneGeometry*>(input->GetPlaneGeometry());

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

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

  Point2D centerPoint2d = GetCenterPoint(input);

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

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

  ScalarType radius = m_Length * (360 / m_BendAngle) / (2 * vnl_math::pi);
  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)
  {
    PolyLine polyLine = input->GetPolyLine(i);
    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;

    PolyLineConstIter polyLineEnd = polyLine.end();

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

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

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

    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)
      {
        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();

  Surface* output = static_cast<Surface*>(this->GetPrimaryOutput());
  output->SetVtkPolyData(polyDataNormals->GetOutput());
}
void mitk::AffineBaseDataInteractor3D::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
  InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
  if(positionEvent == NULL)
    return;

  Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen();
  Point3D currentWorldPoint = positionEvent->GetPositionInWorld();

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

  if ((interactionEvent->GetSender()) != NULL)
  {
    camera = interactionEvent->GetSender()->GetVtkRenderer()->GetActiveCamera();
    currentVtkRenderer = interactionEvent->GetSender()->GetVtkRenderer();
  }
  if ( camera && currentVtkRenderer)
  {
    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();
  }
}
Beispiel #27
0
void DrawFace ( void )
{
    frame=cvCloneImage(patrolbot->getInstance().Ptz.get_image());
    cvFlip ( frame, frame,1 );
    detect_and_draw ( frame );



    glLoadIdentity();
    glPushMatrix();
    glTranslatef(0.0f,-2.9f,-15.0f);
    glScalef(1.25,1.2,1);
    glPushMatrix();
    Vector3D n, up;
    n=Vector3D (( headX-320 ) /500, ( -1* ( headY-240 ) /500 ) -.1,2  );
    up=Vector3D ( 0,1,0 );
    up.Normalize();
    n.Normalize();
    Vector3D u = up.Cross ( up,n );
    u.Normalize();
    Vector3D v = n.Cross ( n,u );
    v.Normalize();

    //create the viewmatrix
    double curmat[16];

    curmat[0]=u.X;
    curmat[1]=u.Y;
    curmat[2]=u.Z;
    curmat[3]=0;

    curmat[4]=v.X;
    curmat[5]=v.Y;
    curmat[6]=v.Z;
    curmat[7]=0;

    curmat[8]=n.X;
    curmat[9]=n.Y;
    curmat[10]=n.Z;
    curmat[11]=0;

    curmat[12]=0;
    curmat[13]=0;
    curmat[14]=0;
    curmat[15]=1;
    glMultMatrixd ( curmat );

    glColor3f(1,1,1);

    glEnable ( GL_TEXTURE_2D );
    glPolygonMode ( GL_FRONT, GL_FILL );
    glBindTexture(GL_TEXTURE_2D, head_tex);

    head->renderFrameImmediate(patrolbot->getInstance().face_frame);
    if (patrolbot->getInstance().face_frame<100)
        if(skip<3)
            skip++;
        else
        {
            patrolbot->getInstance().face_frame++;
            skip=0;
        }
    else
        patrolbot->getInstance().face_frame=0;

    glPopMatrix();


    glPopMatrix();

    cvReleaseImage(&frame);

    usleep(10000);
}
Beispiel #28
0
void SCRenderer::DrawModel(RSEntity* object, size_t lodLevel ){

    if (!initialized)
        return;
    
    if (lodLevel >= object->NumLods()){
        printf("Unable to render this Level Of Details (out of range): Max level is  %lu\n",
               std::min(0UL,object->NumLods()-1));
        return;
    }
    
    
    float ambientLamber = 0.4f;
    
    Lod* lod = &object->lods[lodLevel] ;
    
    
    
        
        
    glDisable(GL_CULL_FACE);
    
    glEnable(GL_BLEND);
    
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    
    
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    
    
    //Texture pass
    if (lodLevel == 0){
        glEnable(GL_TEXTURE_2D);
        
        //glDepthFunc(GL_EQUAL);
        
        glAlphaFunc ( GL_GREATER, 0.0 ) ;
        glEnable ( GL_ALPHA_TEST ) ;
        
        
        for (int i=0 ; i < object->NumUVs(); i++) {
            
            uvxyEntry* textInfo = &object->uvs[i];
            
            //Seems we have a textureID that we don't have :( !
            if (textInfo->textureID >= object->images.size())
                continue;
            
            RSImage* image = object->images[textInfo->textureID];
            
            Texture* texture = image->GetTexture();
            
            glBindTexture(GL_TEXTURE_2D, texture->id);
            
            Triangle* triangle = &object->triangles[textInfo->triangleID];
            
            Vector3D normal;
            GetNormal(object, triangle, &normal);
            
            
            glBegin(GL_TRIANGLES);
            for(int j=0 ; j < 3 ; j++){
                
                Point3D vertice = object->vertices[triangle->ids[j]];
                
                Vector3D lighDirection;
                lighDirection = light;
                lighDirection.Substract(&vertice);
                lighDirection.Normalize();
                
                float lambertianFactor = lighDirection.DotProduct(&normal);
                if (lambertianFactor < 0  )
                    lambertianFactor = 0;
                
                lambertianFactor+= ambientLamber;
                if (lambertianFactor > 1)
                    lambertianFactor = 1;
                
                
                
                glColor4f(lambertianFactor, lambertianFactor, lambertianFactor,1);
                glTexCoord2f(textInfo->uvs[j].u/(float)texture->width, textInfo->uvs[j].v/(float)texture->height);
                glVertex3f(object->vertices[triangle->ids[j]].x,
                           object->vertices[triangle->ids[j]].y,
                           object->vertices[triangle->ids[j]].z);
            }
            glEnd();
            
            
        }
        
        
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_BLEND);
    }


    
    

   
    //Pass 3: Let's draw the transparent stuff render RSEntity::TRANSPARENT)
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glBlendEquation(GL_ADD);

    //glDepthFunc(GL_LESS);
        
        
    for(int i = 0 ; i < lod->numTriangles ; i++){
        
        uint16_t triangleID = lod->triangleIDs[i];
        
        Triangle* triangle = &object->triangles[triangleID];
        
        if (triangle->property != RSEntity::TRANSPARENT)
            continue;
        
        
        Vector3D normal;
        GetNormal(object,triangle,&normal);
        
        glBegin(GL_TRIANGLES);
        for(int j=0 ; j < 3 ; j++){
            
            
            
            Point3D vertice = object->vertices[triangle->ids[j]];
            
            
            Vector3D sunDirection;
            sunDirection = light;
            sunDirection.Substract(&vertice);
            sunDirection.Normalize();

            
            float lambertianFactor = sunDirection.DotProduct(&normal);
            if (lambertianFactor < 0  )
                lambertianFactor = 0;
            
            lambertianFactor=0.2f;
            
            // int8_t gouraud = 255 * lambertianFactor;
            
            
            //gouraud = 255;
            
            glColor4f(lambertianFactor, lambertianFactor, lambertianFactor,1);
            
            glVertex3f(vertice.x,
                       vertice.y,
                       vertice.z);
        }
        glEnd();
    }

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    
    
    
    
    
    
    //Pass 1, draw color
    for(int i = 0 ; i < lod->numTriangles ; i++){
        //for(int i = 60 ; i < 62 ; i++){  //Debug purpose only back governal of F-16 is 60-62
        
        uint16_t triangleID = lod->triangleIDs[i];
        
        Triangle* triangle = &object->triangles[triangleID];
        
        if (triangle->property == RSEntity::TRANSPARENT)
            continue;
        
        Vector3D normal;
        GetNormal(object, triangle, &normal);
        
        glBegin(GL_TRIANGLES);
        for(int j=0 ; j < 3 ; j++){
            
            Point3D vertice = object->vertices[triangle->ids[j]];
            
            Vector3D lighDirection;
            lighDirection = light;
            lighDirection.Substract(&vertice);
            lighDirection.Normalize();
            
            float lambertianFactor = lighDirection.DotProduct(&normal);
            if (lambertianFactor < 0  )
                lambertianFactor = 0;
            
            lambertianFactor+= ambientLamber;
            if (lambertianFactor > 1)
                lambertianFactor = 1;
            
            const Texel* texel = palette.GetRGBColor(triangle->color);
            
            glColor4f(texel->r/255.0f*lambertianFactor, texel->g/255.0f*lambertianFactor, texel->b/255.0f*lambertianFactor,1);
            //glColor4f(texel->r/255.0f, texel->g/255.0f, texel->b/255.0f,1);
            
            glVertex3f(object->vertices[triangle->ids[j]].x,
                       object->vertices[triangle->ids[j]].y,
                       object->vertices[triangle->ids[j]].z);
        }
        glEnd();
    }
    

}
//
//  This one works for planes that are explicitly parallel to the z
//  axis and are bounded in the z direction.
//  This time we get ourselves a square at zMin and search that
//  for our intersections.
//
int FieldView::ViewPlane(Point3D& p, double theta, double zMin, double zMax)
{
  const double degree = 3.141592653589 / 180.0;
  //
  //  We know <0,0,1> lies in the plane, figure out what else
  //  does from the angle.
  //
  Vector3D norm(cos(theta * degree), sin(theta * degree), 0.0);
  const Real* min = mField->GetBounds()->GetMin().mCoords;
  const Real* max = mField->GetBounds()->GetMax().mCoords;
  Point3D corner[4];
  for (int i = 0; i < 4; i++) {
    corner[i].mCoords[0] = (((i/2)&1)==0) ? min[0] : max[0];
    corner[i].mCoords[1] = ((((i+1)/2)&1)==0) ? min[1] : max[1];
    corner[i].mCoords[2] = zMin;
  }
  int nIntersection = 0;
  Point3D frameCorner[4];
  for (int edge = 0; edge < 4; edge++) {
    if (Intersect(p, norm,
                  corner[edge], corner[(edge+1)%4],
                  frameCorner[nIntersection])) {
      bool used = false;
      for (int e = 0; e < nIntersection; e++) {
        if (frameCorner[nIntersection] == frameCorner[e]) {
          used = true;
        }
      }
      if (!used) {
        nIntersection++;
        if (nIntersection >= 2) break;
      }
    }
  }
  if (nIntersection != 2) {
    return -1;        // MUST have two intersections.
  }
  //
  //  Right, we have two intersections. They are on the min side in the
  //  dir direction. The other two intersections are on the max side
  //  so we make them from these two. The order is chosen carefully
  //  to make corners adjacent.
  //
  frameCorner[2] = frameCorner[1];
  frameCorner[2].mCoords[2] = zMax;
  frameCorner[3] = frameCorner[0];
  frameCorner[3].mCoords[2] = zMax;
  //
  //  Now we can construct the FrameRect3D representing the intersection.
  //
  mFrame = new FrameRect3D(frameCorner);
  if (mFrame->IsValid()) {
    mValid = true;
  }
  //
  //  Then we can construct the legend. It sits in the same plane as
  //  the mFrame but is thinner and translated by 10% of the mFrame width.
  //
  Vector3D horiz = mFrame->GetHorizontal();
  horiz.Normalize();
  double displacement = mFrame->GetWidth() * 0.1;
  double legendWidth = displacement * 1.3; // 3% of frame
  frameCorner[0] = frameCorner[1] + horiz * displacement;
  frameCorner[1] = frameCorner[0] + horiz * legendWidth;
  frameCorner[3] = frameCorner[2] + horiz * displacement;
  frameCorner[2] = frameCorner[3] + horiz * legendWidth;
  mLegendFrame = new FrameRect3D(frameCorner);
  return 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();
}