void mitk::ClippingPlaneInteractor3D::TranslateObject (StateMachineAction*, InteractionEvent* interactionEvent)
{
    InteractionPositionEvent* positionEvent = dynamic_cast<InteractionPositionEvent*>(interactionEvent);
    if(positionEvent == NULL)
        return;

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

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

    Point3D origin = m_OriginalGeometry->GetOrigin();

    // Get the timestep to also support 3D+t
    int timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData());

    // If data is an mitk::Surface, extract it
    Surface::Pointer surface = dynamic_cast< Surface* >(this->GetDataNode()->GetData());
    vtkPolyData* polyData = NULL;
    if (surface.IsNotNull())
    {
        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 );
            }
        }
    }

    Vector3D transformedObjectNormal;
    this->GetDataNode()->GetData()->GetGeometry( timeStep )->IndexToWorld(m_ObjectNormal, transformedObjectNormal);

    this->GetDataNode()->GetData()->GetGeometry( timeStep )->SetOrigin(origin + transformedObjectNormal * (interactionMove * transformedObjectNormal));

    interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll();
}
bool mitk::AffineDataInteractor3D::ColorizeSurface(BaseRenderer::Pointer renderer, double scalar)
{
  BaseData::Pointer data = this->GetDataNode()->GetData();
  if(data.IsNull())
  {
    MITK_ERROR << "AffineInteractor3D: No data object present!";
    return false;
  }

  // Get the timestep to also support 3D+t
  int timeStep = 0;
  if (renderer.IsNotNull())
    timeStep = renderer->GetTimeStep(data);


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

  if (polyData == NULL)
  {
    MITK_ERROR << "AffineInteractor3D: No poly data present!";
    return false;
  }

  vtkPointData* pointData = polyData->GetPointData();
  if (pointData == NULL)
  {
    MITK_ERROR << "AffineInteractor3D: No point data present!";
    return false;
  }

  vtkDataArray* scalars = pointData->GetScalars();
  if (scalars == NULL)
  {
    MITK_ERROR << "AffineInteractor3D: No scalars for point data present!";
    return false;
  }

  for (unsigned int i = 0; i < pointData->GetNumberOfTuples(); ++i)
  {
    scalars->SetComponent(i, 0, scalar);
  }

  polyData->Modified();
  pointData->Update();

  return true;
}
Example #3
0
bool mitk::MeshMitkLoader::canLoad()
{
  Surface::Pointer surface = GetData<Surface>(m_filename.getValue());

  if (surface.IsNull())
    return false;

  vtkPolyData* polyData = surface->GetVtkPolyData();

  if (polyData == nullptr || polyData->GetNumberOfCells() == 0)
    return false;

  return true;
}
Example #4
0
void mitk::SurfaceGLMapper2D::SetDataNode( mitk::DataNode* node )
{
  Superclass::SetDataNode( node );

  bool useCellData;
  if (dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring")) == NULL)
    useCellData = false;
  else
    useCellData = dynamic_cast<BoolProperty *>(node->GetProperty("deprecated useCellDataForColouring"))->GetValue();

  if (!useCellData)
  {
    // search min/max point scalars over all time steps
    double dataRange[2] = {0,0};
    double range[2];

    Surface::Pointer input  = const_cast< Surface* >(dynamic_cast<const Surface*>( this->GetDataNode()->GetData() ));
    if(input.IsNull()) return;
    const TimeGeometry::Pointer inputTimeGeometry = input->GetTimeGeometry();
    if(( inputTimeGeometry.IsNull() ) || ( inputTimeGeometry->CountTimeSteps() == 0 ) ) return;
    for (unsigned int timestep=0; timestep<inputTimeGeometry->CountTimeSteps(); timestep++)
    {
      vtkPolyData * vtkpolydata = input->GetVtkPolyData( timestep );
      if((vtkpolydata==NULL) || (vtkpolydata->GetNumberOfPoints() < 1 )) continue;
      vtkDataArray *vpointscalars = vtkpolydata->GetPointData()->GetScalars();
      if (vpointscalars) {
        vpointscalars->GetRange( range, 0 );
        if (dataRange[0]==0 && dataRange[1]==0) {
          dataRange[0] = range[0];
          dataRange[1] = range[1];
        }
        else {
          if (range[0] < dataRange[0]) dataRange[0] = range[0];
          if (range[1] > dataRange[1]) dataRange[1] = range[1];
        }
      }
    }
    if (dataRange[1] - dataRange[0] > 0) {
      m_LUT->SetTableRange( dataRange );
      m_LUT->Build();
    }
  }
}
Example #5
0
bool mitk::MeshMitkLoader::load()
{
  Surface::Pointer surface = GetData<Surface>(m_filename.getValue());
  vtkPolyData* polyData = surface->GetVtkPolyData();

  // vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  // transformFilter->SetTransform(surface->GetGeometry()->GetVtkTransform());
  // transformFilter->SetInputConnection(polyData->GetProducerPort());
  // transformFilter->Update();

  // polyData = vtkPolyData::SafeDownCast(transformFilter->GetOutputDataObject(0));

  sofa::helper::vector<sofa::defaulttype::Vector3>& positions = *this->positions.beginEdit();
  sofa::helper::vector<Edge>& edges = *this->edges.beginEdit();
  sofa::helper::vector<Triangle>& triangles = *this->triangles.beginEdit();
  sofa::helper::vector<Quad>& quads = *this->quads.beginEdit();
  sofa::helper::vector<sofa::helper::vector<unsigned int> > polygons = *this->polygons.beginEdit();

  vtkPoints* points = polyData->GetPoints();
  vtkIdType numPoints = points->GetNumberOfPoints();
  double point[3];

  for (vtkIdType i = 0; i < numPoints; ++i)
  {
    points->GetPoint(i, point);
    positions.push_back(sofa::defaulttype::Vec3d(point[0], point[1], point[2]));
  }

  vtkCellArray* polys = polyData->GetPolys();
  vtkIdType numPolys = polys->GetNumberOfCells();
  vtkSmartPointer<vtkIdList> poly = vtkSmartPointer<vtkIdList>::New();
  Edge edge;
  Triangle triangle;
  Quad quad;

  polys->InitTraversal();

  while (polys->GetNextCell(poly) != 0)
  {
    switch (poly->GetNumberOfIds())
    {
    case 1:
      break;

    case 2:
      edge[0] = poly->GetId(0);
      edge[1] = poly->GetId(1);

      edges.push_back(edge);
      break;

    case 3:
      triangle[0] = poly->GetId(0);
      triangle[1] = poly->GetId(1);
      triangle[2] = poly->GetId(2);

      triangles.push_back(triangle);
      break;

    case 4:
      quad[0] = poly->GetId(0);
      quad[1] = poly->GetId(1);
      quad[2] = poly->GetId(2);
      quad[3] = poly->GetId(3);

      quads.push_back(quad);
      break;

    default:
      sofa::helper::vector<unsigned int> polygon;
      vtkIdType numIds = poly->GetNumberOfIds();

      polygon.reserve(numIds);

      for (vtkIdType i = 0; i < numIds; ++i)
        polygon.push_back(poly->GetId(i));

      polygons.push_back(polygon);
      break;
    }
  }

  this->positions.endEdit();
  this->edges.endEdit();
  this->triangles.endEdit();
  this->quads.endEdit();
  this->polygons.endEdit();

  return true;
}
Example #6
0
bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string path)
{
    std::string dir = itksys::SystemTools::GetFilenamePath( path );
    std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path );
    std::string extension = itksys::SystemTools::GetFilenameLastExtension( path );
    std::string finalFileName = dir + "/" + baseFilename;

    if (extension == "") // if no extension has been set we use the default extension
    {
        MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName
                  << DEFAULTSURFACEEXTENSION;
        extension = DEFAULTSURFACEEXTENSION;
    }
    try
    {
        finalFileName += extension;
        if(extension == ".stl" )
        {
            mitk::SurfaceVtkWriter<vtkSTLWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkSTLWriter>::New();

            // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles...
            vtkPolyData* polys = surface->GetVtkPolyData();
            if( polys->GetNumberOfStrips() > 0 )
            {
                vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New();
                triangleFilter->SetInput(polys);
                triangleFilter->Update();
                polys = triangleFilter->GetOutput();
                polys->Register(NULL);
                surface->SetVtkPolyData(polys);
            }
            surfaceWriter->SetInput( surface );
            surfaceWriter->SetFileName( finalFileName.c_str() );
            surfaceWriter->GetVtkWriter()->SetFileTypeToBinary();
            surfaceWriter->Write();
        }
        else if(extension == ".vtp")
        {
            mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkXMLPolyDataWriter>::New();
            surfaceWriter->SetInput( surface );
            surfaceWriter->SetFileName( finalFileName.c_str() );
            surfaceWriter->GetVtkWriter()->SetDataModeToBinary();
            surfaceWriter->Write();
        }
        else if(extension == ".vtk")
        {
            mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
            surfaceWriter->SetInput( surface );
            surfaceWriter->SetFileName( finalFileName.c_str() );
            surfaceWriter->Write();
        }
        else
        {
            // file extension not suitable for writing specified data type
            MITK_ERROR << "File extension is not suitable for writing'" << finalFileName;
            mitkThrow() << "An exception occured during writing the file " << finalFileName <<
                           ". File extension " << extension << " is not suitable for writing.";
        }
    }
    catch(std::exception& e)
    {
        MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:";
        MITK_ERROR << e.what();
        mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what();
    }
    return true;
}
Example #7
0
mitk::Surface::Pointer mitk::ACVD::Remesh(mitk::Surface::Pointer surface, int numVertices, double gradation, int subsampling, double edgeSplitting, int optimizationLevel, bool forceManifold, bool boundaryFixing)
{
  MITK_INFO << "Start remeshing...";

  vtkSmartPointer<vtkPolyData> surfacePolyData = vtkSmartPointer<vtkPolyData>::New();
  surfacePolyData->DeepCopy(surface->GetVtkPolyData());

  vtkSmartPointer<vtkSurface> mesh = vtkSmartPointer<vtkSurface>::New();

  mesh->CreateFromPolyData(surfacePolyData);
  mesh->GetCellData()->Initialize();
  mesh->GetPointData()->Initialize();

  mesh->DisplayMeshProperties();

  if (edgeSplitting != 0.0)
    mesh->SplitLongEdges(edgeSplitting);

  vtkSmartPointer<vtkIsotropicDiscreteRemeshing> remesher = vtkSmartPointer<vtkIsotropicDiscreteRemeshing>::New();

  remesher->GetMetric()->SetGradation(gradation);
  remesher->SetBoundaryFixing(boundaryFixing);
  remesher->SetConsoleOutput(1);
  remesher->SetForceManifold(forceManifold);
  remesher->SetInput(mesh);
  remesher->SetNumberOfClusters(numVertices);
  remesher->SetNumberOfThreads(vtkMultiThreader::GetGlobalDefaultNumberOfThreads());
  remesher->SetSubsamplingThreshold(subsampling);

  remesher->Remesh();

  if (optimizationLevel != 0)
  {
    ClustersQuadrics clustersQuadrics(numVertices);

    vtkSmartPointer<vtkIdList> faceList = vtkSmartPointer<vtkIdList>::New();
    vtkSmartPointer<vtkIntArray> clustering = remesher->GetClustering();
    vtkSmartPointer<vtkSurface> remesherInput = remesher->GetInput();
    int clusteringType = remesher->GetClusteringType();
    int numItems = remesher->GetNumberOfItems();
    int numMisclassifiedItems = 0;

    for (int i = 0; i < numItems; ++i)
    {
      int cluster = clustering->GetValue(i);

      if (cluster >= 0 && cluster < numVertices)
      {
        if (clusteringType != 0)
        {
          remesherInput->GetVertexNeighbourFaces(i, faceList);
          int numIds = static_cast<int>(faceList->GetNumberOfIds());

          for (int j = 0; j < numIds; ++j)
            vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, faceList->GetId(j), false);
        }
        else
        {
          vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, i, false);
        }
      }
      else
      {
        ++numMisclassifiedItems;
      }
    }

    if (numMisclassifiedItems != 0)
      std::cout << numMisclassifiedItems << " items with wrong cluster association" << std::endl;

    vtkSmartPointer<vtkSurface> remesherOutput = remesher->GetOutput();
    double point[3];

    for (int i = 0; i < numVertices; ++i)
    {
      remesherOutput->GetPoint(i, point);
      vtkQuadricTools::ComputeRepresentativePoint(clustersQuadrics.Elements[i], point, optimizationLevel);
      remesherOutput->SetPointCoordinates(i, point);
    }

    std::cout << "After quadrics post-processing:" << std::endl;
    remesherOutput->DisplayMeshProperties();
  }

  vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();

  normals->SetInput(remesher->GetOutput());
  normals->AutoOrientNormalsOn();
  normals->ComputeCellNormalsOff();
  normals->ComputePointNormalsOn();
  normals->ConsistencyOff();
  normals->FlipNormalsOff();
  normals->NonManifoldTraversalOff();
  normals->SplittingOff();

  normals->Update();

  Surface::Pointer remeshedSurface = Surface::New();
  remeshedSurface->SetVtkPolyData(normals->GetOutput());

  MITK_INFO << "Finished remeshing";

  return remeshedSurface;
}
void mitk::ImageToContourFilter::Itk2DContourExtraction(const itk::Image<TPixel, VImageDimension> *sliceImage)
{
  typedef itk::Image<TPixel, VImageDimension> ImageType;
  typedef itk::ContourExtractor2DImageFilter<ImageType> ContourExtractor;

  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
  typename PadFilterType::Pointer padFilter = PadFilterType::New();
  typename ImageType::SizeType lowerExtendRegion;
  lowerExtendRegion[0] = 1;
  lowerExtendRegion[1] = 1;

  typename ImageType::SizeType upperExtendRegion;
  upperExtendRegion[0] = 1;
  upperExtendRegion[1] = 1;

  /*
   * We need to pad here, since the ITK contour extractor fails if the
   * segmentation touches more than one image edge.
   * By padding the image for one row at each edge we overcome this issue
   */
  padFilter->SetInput(sliceImage);
  padFilter->SetConstant(0);
  padFilter->SetPadLowerBound(lowerExtendRegion);
  padFilter->SetPadUpperBound(upperExtendRegion);

  typename ContourExtractor::Pointer contourExtractor = ContourExtractor::New();
  contourExtractor->SetInput(padFilter->GetOutput());
  contourExtractor->SetContourValue(0.5);

  contourExtractor->Update();

  unsigned int foundPaths = contourExtractor->GetNumberOfOutputs();

  vtkSmartPointer<vtkPolyData> contourSurface = vtkSmartPointer<vtkPolyData>::New();
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();

  unsigned int pointId(0);

  for (unsigned int i = 0; i < foundPaths; i++)
  {
    const ContourPath *currentPath = contourExtractor->GetOutput(i)->GetVertexList();

    vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
    polygon->GetPointIds()->SetNumberOfIds(currentPath->Size());

    Point3D currentPoint;
    Point3D currentWorldPoint;

    for (unsigned int j = 0; j < currentPath->Size(); j++)
    {
      currentPoint[0] = currentPath->ElementAt(j)[0];
      currentPoint[1] = currentPath->ElementAt(j)[1];
      currentPoint[2] = 0;

      m_SliceGeometry->IndexToWorld(currentPoint, currentWorldPoint);

      points->InsertPoint(pointId, currentWorldPoint[0], currentWorldPoint[1], currentWorldPoint[2]);
      polygon->GetPointIds()->SetId(j, pointId);
      pointId++;

    } // for2

    polygons->InsertNextCell(polygon);

  } // for1

  contourSurface->SetPoints(points);
  contourSurface->SetPolys(polygons);
  contourSurface->BuildLinks();
  Surface::Pointer finalSurface = this->GetOutput();

  finalSurface->SetVtkPolyData(contourSurface);
}
void mitk::ComputeContourSetNormalsFilter::GenerateData()
{
  unsigned int numberOfInputs = this->GetNumberOfIndexedInputs();
  this->CreateOutputsForAllInputs(numberOfInputs);

  //Iterating over each input
  for(unsigned int i = 0; i < numberOfInputs; i++)
  {
    //Getting the inputs polydata and polygons
    Surface* currentSurface = const_cast<Surface*>( this->GetInput(i) );
    vtkPolyData* polyData = currentSurface->GetVtkPolyData();

    vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();

    vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();

    existingPolys->InitTraversal();

    vtkIdType* cell (NULL);
    vtkIdType cellSize (0);

    //The array that contains all the vertex normals of the current polygon
    vtkSmartPointer<vtkDoubleArray> normals = vtkSmartPointer<vtkDoubleArray>::New();
    normals->SetNumberOfComponents(3);
    normals->SetNumberOfTuples(polyData->GetNumberOfPoints());

    //If the current contour is an inner contour then the direction is -1
    //A contour lies inside another one if the pixel values in the direction of the normal is 1
    m_NegativeNormalCounter = 0;
    m_PositiveNormalCounter = 0;

    //Iterating over each polygon
    for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
    {
      if(cellSize < 3)continue;

      //First we calculate the current polygon's normal
      double polygonNormal[3] = {0.0};

      double p1[3];
      double p2[3];

      double v1[3];
      double v2[3];

      existingPoints->GetPoint(cell[0], p1);
      unsigned int index = cellSize*0.5;
      existingPoints->GetPoint(cell[index], p2);

      v1[0] = p2[0]-p1[0];
      v1[1] = p2[1]-p1[1];
      v1[2] = p2[2]-p1[2];

      for (unsigned int k = 2; k < cellSize; k++)
      {
        index = cellSize*0.25;
        existingPoints->GetPoint(cell[index], p1);
        index = cellSize*0.75;
        existingPoints->GetPoint(cell[index], p2);

        v2[0] = p2[0]-p1[0];
        v2[1] = p2[1]-p1[1];
        v2[2] = p2[2]-p1[2];

        vtkMath::Cross(v1,v2,polygonNormal);
        if (vtkMath::Norm(polygonNormal) != 0)
          break;
      }

      vtkMath::Normalize(polygonNormal);

      //Now we start computing the normal for each vertex

      double vertexNormalTemp[3];
      existingPoints->GetPoint(cell[0], p1);
      existingPoints->GetPoint(cell[1], p2);

      v1[0] = p2[0]-p1[0];
      v1[1] = p2[1]-p1[1];
      v1[2] = p2[2]-p1[2];

      vtkMath::Cross(v1,polygonNormal,vertexNormalTemp);

      vtkMath::Normalize(vertexNormalTemp);

      double vertexNormal[3];

      for (unsigned j = 0; j < cellSize-2; j++)
      {
        existingPoints->GetPoint(cell[j+1], p1);
        existingPoints->GetPoint(cell[j+2], p2);

        v1[0] = p2[0]-p1[0];
        v1[1] = p2[1]-p1[1];
        v1[2] = p2[2]-p1[2];

        vtkMath::Cross(v1,polygonNormal,vertexNormal);

        vtkMath::Normalize(vertexNormal);

        double finalNormal[3];

        finalNormal[0] = (vertexNormal[0] + vertexNormalTemp[0])*0.5;
        finalNormal[1] = (vertexNormal[1] + vertexNormalTemp[1])*0.5;
        finalNormal[2] = (vertexNormal[2] + vertexNormalTemp[2])*0.5;

        //Here we determine the direction of the normal
        if (j == 0 && m_SegmentationBinaryImage)
        {
          Point3D worldCoord;
          worldCoord[0] = p1[0]+finalNormal[0]*m_MaxSpacing;
          worldCoord[1] = p1[1]+finalNormal[1]*m_MaxSpacing;
          worldCoord[2] = p1[2]+finalNormal[2]*m_MaxSpacing;

          double val = 0.0;
          mitk::ImagePixelReadAccessor<unsigned char> readAccess(m_SegmentationBinaryImage);
          mitk::Index3D idx;
          m_SegmentationBinaryImage->GetGeometry()->WorldToIndex(worldCoord, idx);
          val = readAccess.GetPixelByIndexSafe(idx);

          if (val == 1.0)
          {
              ++m_PositiveNormalCounter;
          }
          else
          {
              ++m_NegativeNormalCounter;
          }
        }

        vertexNormalTemp[0] = vertexNormal[0];
        vertexNormalTemp[1] = vertexNormal[1];
        vertexNormalTemp[2] = vertexNormal[2];

        vtkIdType id = cell[j+1];
        normals->SetTuple(id,finalNormal);
      }

      existingPoints->GetPoint(cell[0], p1);
      existingPoints->GetPoint(cell[1], p2);

      v1[0] = p2[0]-p1[0];
      v1[1] = p2[1]-p1[1];
      v1[2] = p2[2]-p1[2];

      vtkMath::Cross(v1,polygonNormal,vertexNormal);

      vtkMath::Normalize(vertexNormal);

      vertexNormal[0] = (vertexNormal[0] + vertexNormalTemp[0])*0.5;
      vertexNormal[1] = (vertexNormal[1] + vertexNormalTemp[1])*0.5;
      vertexNormal[2] = (vertexNormal[2] + vertexNormalTemp[2])*0.5;

      vtkIdType id = cell[0];
      normals->SetTuple(id,vertexNormal);
      id = cell[cellSize-1];
      normals->SetTuple(id,vertexNormal);

      int normalDirection(-1);

      if(m_NegativeNormalCounter < m_PositiveNormalCounter)
      {
          normalDirection = 1;
      }

      for(unsigned int n = 0; n < normals->GetNumberOfTuples(); n++)
      {
          double normal[3];
          normals->GetTuple(n,normal);
          normal[0] = normalDirection*normal[0];
          normal[1] = normalDirection*normal[1];
          normal[2] = normalDirection*normal[2];
      }


    }//end for all cells

    Surface::Pointer surface = this->GetOutput(i);
    surface->GetVtkPolyData()->GetCellData()->SetNormals(normals);
  }//end for all inputs

  //Setting progressbar
  if (this->m_UseProgressBar)
    mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize);
}
Example #10
0
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::ReduceContourSetFilter::GenerateData()
{
  unsigned int numberOfInputs = this->GetNumberOfInputs();
  unsigned int numberOfOutputs (0);

  vtkSmartPointer<vtkPolyData> newPolyData;
  vtkSmartPointer<vtkCellArray> newPolygons;
  vtkSmartPointer<vtkPoints> newPoints;

  //For the purpose of evaluation
//  unsigned int numberOfPointsBefore (0);
  m_NumberOfPointsAfterReduction=0;

  for(unsigned int i = 0; i < numberOfInputs; i++)
  {
    mitk::Surface* currentSurface = const_cast<mitk::Surface*>( this->GetInput(i) );
    vtkSmartPointer<vtkPolyData> polyData = currentSurface->GetVtkPolyData();

    newPolyData = vtkPolyData::New();
    newPolygons = vtkCellArray::New();
    newPoints = vtkPoints::New();

    vtkSmartPointer<vtkCellArray> existingPolys = polyData->GetPolys();

    vtkSmartPointer<vtkPoints> existingPoints = polyData->GetPoints();

    existingPolys->InitTraversal();

    vtkIdType* cell (NULL);
    vtkIdType cellSize (0);

    for( existingPolys->InitTraversal(); existingPolys->GetNextCell(cellSize, cell);)
    {
      bool incorporatePolygon = this->CheckForIntersection(cell,cellSize,existingPoints, /*numberOfIntersections, intersectionPoints, */i);
      if ( !incorporatePolygon ) continue;

      vtkSmartPointer<vtkPolygon> newPolygon = vtkSmartPointer<vtkPolygon>::New();

      if(m_ReductionType == NTH_POINT)
      {
        this->ReduceNumberOfPointsByNthPoint(cellSize, cell, existingPoints, newPolygon, newPoints);
        if (newPolygon->GetPointIds()->GetNumberOfIds() != 0)
        {
          newPolygons->InsertNextCell(newPolygon);
        }
      }
      else if (m_ReductionType == DOUGLAS_PEUCKER)
      {
        this->ReduceNumberOfPointsByDouglasPeucker(cellSize, cell, existingPoints, newPolygon, newPoints);
        if (newPolygon->GetPointIds()->GetNumberOfIds() > 3)
        {
          newPolygons->InsertNextCell(newPolygon);
        }
      }

      //Again for evaluation
//      numberOfPointsBefore += cellSize;
      m_NumberOfPointsAfterReduction += newPolygon->GetPointIds()->GetNumberOfIds();

    }

    if (newPolygons->GetNumberOfCells() != 0)
    {
      newPolyData->SetPolys(newPolygons);
      newPolyData->SetPoints(newPoints);
      newPolyData->BuildLinks();

      Surface::Pointer surface = this->GetOutput(numberOfOutputs);
      surface->SetVtkPolyData(newPolyData);
      numberOfOutputs++;
    }

  }
//  MITK_INFO<<"Points before: "<<numberOfPointsBefore<<" ##### Points after: "<<numberOfPointsAfter;
  this->SetNumberOfOutputs(numberOfOutputs);

  //Setting progressbar
  if (this->m_UseProgressBar)
    mitk::ProgressBar::GetInstance()->Progress(this->m_ProgressStepSize);
}