int mitk::PlanarFigureInteractor::IsPositionOverFigure(
  const InteractionPositionEvent *positionEvent,
  PlanarFigure *planarFigure,
  const PlaneGeometry *planarFigureGeometry,
  const PlaneGeometry *rendererGeometry,
  const DisplayGeometry *displayGeometry,
  Point2D& pointProjectedOntoLine ) const
{
  mitk::Point2D displayPosition = positionEvent->GetPointerPositionOnScreen();

  // Iterate over all polylines of planar figure, and check if
  // any one is close to the current display position
  typedef mitk::PlanarFigure::PolyLineType VertexContainerType;

  Point2D polyLinePoint;
  Point2D firstPolyLinePoint;
  Point2D previousPolyLinePoint;

  for ( unsigned short loop=0; loop<planarFigure->GetPolyLinesSize(); ++loop )
  {
    const VertexContainerType polyLine = planarFigure->GetPolyLine( loop );

    bool firstPoint( true );
    for ( VertexContainerType::const_iterator it = polyLine.begin(); it != polyLine.end(); ++it )
    {
      // Get plane coordinates of this point of polyline (if possible)
      if ( !this->TransformObjectToDisplay( *it,
                                            polyLinePoint,
                                            planarFigureGeometry,
                                            rendererGeometry,
                                            displayGeometry )
                                           )
      {
        break; // Poly line invalid (not on current 2D plane) --> skip it
      }

      if ( firstPoint )
      {
        firstPolyLinePoint = polyLinePoint;
        firstPoint = false;
      }
      else if ( this->IsPointNearLine( displayPosition, previousPolyLinePoint, polyLinePoint, pointProjectedOntoLine ) )
      {
        // Point is close enough to line segment --> Return index of the segment
        return std::distance(polyLine.begin(), it);
      }
      previousPolyLinePoint = polyLinePoint;
    }

    // For closed figures, also check last line segment
    if ( planarFigure->IsClosed()
      && this->IsPointNearLine( displayPosition, polyLinePoint, firstPolyLinePoint, pointProjectedOntoLine ) )
    {
      return 0; // Return index of first control point
    }
  }
  return -1;
}
Ejemplo n.º 2
0
void QmitkVtkLineProfileWidget::CreatePathFromPlanarFigure()
{
  m_ParametricPath->Initialize();

  if ( m_PlanarFigure.IsNull() )
  {
    throw std::invalid_argument("QmitkVtkLineProfileWidget: PlanarFigure not set!" );
  }

  if ( m_Image.IsNull() )
  {
    throw std::invalid_argument("QmitkVtkLineProfileWidget: Image not set -- needed to calculate path from PlanarFigure!" );
  }

  // Get 2D geometry frame of PlanarFigure
  mitk::Geometry2D *planarFigureGeometry2D = 
    dynamic_cast< mitk::Geometry2D * >( m_PlanarFigure->GetGeometry( 0 ) );
  if ( planarFigureGeometry2D == NULL )
  {
    throw std::invalid_argument("QmitkVtkLineProfileWidget: PlanarFigure has no valid geometry!" );
  }

  // Get 3D geometry from Image (needed for conversion of point to index)
  mitk::Geometry3D *imageGeometry = m_Image->GetGeometry( 0 );
  if ( imageGeometry == NULL )
  {
    throw std::invalid_argument("QmitkVtkLineProfileWidget: Image has no valid geometry!" );
  }

  // Get first poly-line of PlanarFigure (other possible poly-lines in PlanarFigure
  // are not supported)
  typedef mitk::PlanarFigure::PolyLineType VertexContainerType;
  const VertexContainerType vertexContainer = m_PlanarFigure->GetPolyLine( 0 );

  MITK_INFO << "WorldToIndex:";

  VertexContainerType::const_iterator it;
  for ( it = vertexContainer.begin(); it != vertexContainer.end(); ++it )
  {
    // Map PlanarFigure 2D point to 3D point
    mitk::Point3D point3D;
    planarFigureGeometry2D->Map( it->Point, point3D );

    // Convert world to index coordinates
    mitk::Point3D indexPoint3D;
    imageGeometry->WorldToIndex( point3D, indexPoint3D );

    ParametricPathType::OutputType index;
    index[0] = indexPoint3D[0];
    index[1] = indexPoint3D[1];
    index[2] = indexPoint3D[2];

    MITK_INFO << point3D << " / " << index;

    // Add index to parametric path
    m_ParametricPath->AddVertex( index );
  }

}
int main()
{
  typedef viennagrid::triangular_2d_mesh                                                  DomainType;
  typedef viennagrid::result_of::segmentation<DomainType>::type                           SegmentationType;
  typedef SegmentationType::iterator                                                      SegmentationIteratorType;
  typedef viennagrid::result_of::segment_handle<SegmentationType>::type                   SegmentType;
  typedef viennagrid::result_of::cell_tag<DomainType>::type                               CellTagType;
  typedef viennagrid::result_of::element<DomainType, viennagrid::vertex_tag>::type        VertexType;
  typedef viennagrid::result_of::element<DomainType, CellTagType>::type                   CellType;

  typedef viennagrid::result_of::element_range<DomainType, viennagrid::vertex_tag>::type  VertexContainerType;
  typedef viennagrid::result_of::iterator<VertexContainerType>::type                      VertexIteratorType;
  typedef viennagrid::result_of::element_range<SegmentType, CellTagType>::type            CellOnSegmentContainerType;
  typedef viennagrid::result_of::iterator<CellOnSegmentContainerType>::type               CellOnSegmentIteratorType;

  typedef boost::numeric::ublas::compressed_matrix<viennafem::numeric_type>  MatrixType;
  typedef boost::numeric::ublas::vector<viennafem::numeric_type>             VectorType;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;

  //
  // Create a domain from file
  //
  DomainType my_domain;
  SegmentationType segments(my_domain);

  //
  // Create a storage object
  //
  typedef viennadata::storage<> StorageType;
  StorageType   storage;

  try
  {
    viennagrid::io::netgen_reader my_netgen_reader;
    my_netgen_reader(my_domain, segments, "../examples/data/square224.mesh");
  }
  catch (...)
  {
    std::cerr << "File-Reader failed. Aborting program..." << std::endl;
    return EXIT_FAILURE;
  }


  //
  // Specify Poisson equation with inhomogeneous permittivity:
  //
  FunctionSymbol u(0, viennamath::unknown_tag<>());   //an unknown function used for PDE specification
  FunctionSymbol v(0, viennamath::test_tag<>());   //an unknown function used for PDE specification
  viennafem::cell_quan<CellType, viennamath::expr::interface_type>  permittivity; permittivity.wrap_constant( storage, permittivity_key() );

  //the strong form (not yet functional because of ViennaMath limitations)
  //Equation poisson_equ = viennamath::make_equation( viennamath::div(permittivity * viennamath::grad(u)), 0);

  //the weak form:
  Equation poisson_equ = viennamath::make_equation(
                          viennamath::integral(viennamath::symbolic_interval(),
                                               permittivity * (viennamath::grad(u) * viennamath::grad(v)) ),
                          0);

  MatrixType system_matrix;
  VectorType load_vector;

  //
  // Setting boundary information on domain (this should come from device specification)
  //
  //setting some boundary flags:
  VertexContainerType vertices = viennagrid::elements<VertexType>(my_domain);
  for (VertexIteratorType vit = vertices.begin();
      vit != vertices.end();
      ++vit)
  {
    // Boundary condition: 0 at left boundary, 1 at right boundary
    if ( viennagrid::point(my_domain, *vit)[0] == 0.0)
      viennafem::set_dirichlet_boundary(storage, *vit, 0.0);
    else if ( viennagrid::point(my_domain, *vit)[0] == 1.0)
      viennafem::set_dirichlet_boundary(storage, *vit, 1.0);

  }


  //
  // Create PDE solver functors: (discussion about proper interface required)
  //
  viennafem::pde_assembler<StorageType> fem_assembler(storage);


  //
  // Solve system and write solution vector to pde_result:
  // (discussion about proper interface required. Introduce a pde_result class?)
  //
  std::size_t si = 0;
  for(SegmentationIteratorType sit = segments.begin(); sit != segments.end(); sit++)
  {
    //set permittivity:
    CellOnSegmentContainerType cells = viennagrid::elements<CellType>(*sit);
    for (CellOnSegmentIteratorType cit  = cells.begin();
                                   cit != cells.end();
                                 ++cit)
    {
      if (si == 0) //Si
        viennadata::access<permittivity_key, double>(storage, permittivity_key(), *cit) = 3.9;
      else //SiO2
        viennadata::access<permittivity_key, double>(storage, permittivity_key(), *cit) = 11.9;
    }


    fem_assembler(viennafem::make_linear_pde_system(poisson_equ,
                                                    u,
                                                    viennafem::make_linear_pde_options(0,
                                                                                       viennafem::lagrange_tag<1>(),
                                                                                       viennafem::lagrange_tag<1>())
                                                  ),
                  *sit,
                  system_matrix,
                  load_vector
                );
  }

  VectorType pde_result = viennacl::linalg::solve(system_matrix, load_vector, viennacl::linalg::cg_tag());
  std::cout << "* solve(): Residual: " << norm_2(prod(system_matrix, pde_result) - load_vector) << std::endl;

  //
  // Writing solution back to domain (discussion about proper way of returning a solution required...)
  //
  viennafem::io::write_solution_to_VTK_file(pde_result, "poisson_cellquan_2d", my_domain, segments, storage, 0);

  std::cout << "*****************************************" << std::endl;
  std::cout << "* Poisson solver finished successfully! *" << std::endl;
  std::cout << "*****************************************" << std::endl;
  return EXIT_SUCCESS;
}
Ejemplo n.º 4
0
void QmitkHistogramJSWidget::ComputeIntensityProfile(unsigned int timeStep)
{
  this->ClearData();
  m_ParametricPath->Initialize();

  if (m_PlanarFigure.IsNull())
  {
    mitkThrow() << "PlanarFigure not set!";
  }

  if (m_Image.IsNull())
  {
    mitkThrow() << "Image not set!";
  }

  // Get 2D geometry frame of PlanarFigure
  mitk::Geometry2D* planarFigureGeometry2D = dynamic_cast<mitk::Geometry2D*>(m_PlanarFigure->GetGeometry(0));
  if (planarFigureGeometry2D == NULL)
  {
    mitkThrow() << "PlanarFigure has no valid geometry!";
  }

  // Get 3D geometry from Image (needed for conversion of point to index)
  mitk::Geometry3D* imageGeometry = m_Image->GetGeometry(0);
  if (imageGeometry == NULL)
  {
    mitkThrow() << "Image has no valid geometry!";
  }

  // Get first poly-line of PlanarFigure (other possible poly-lines in PlanarFigure
  // are not supported)
  const VertexContainerType vertexContainer = m_PlanarFigure->GetPolyLine(0);

  VertexContainerType::const_iterator it;
  for (it = vertexContainer.begin(); it != vertexContainer.end(); ++it)
  {
    // Map PlanarFigure 2D point to 3D point
    mitk::Point3D point3D;
    planarFigureGeometry2D->Map(it->Point, point3D);

    // Convert world to index coordinates
    mitk::Point3D indexPoint3D;
    imageGeometry->WorldToIndex(point3D, indexPoint3D);

    ParametricPathType::OutputType index;
    index[0] = indexPoint3D[0];
    index[1] = indexPoint3D[1];
    index[2] = indexPoint3D[2];

    // Add index to parametric path
    m_ParametricPath->AddVertex(index);
  }

  m_DerivedPath = m_ParametricPath;

  if (m_DerivedPath.IsNull())
  {
    mitkThrow() << "No path set!";
  }

  // Fill item model with line profile data
  double distance = 0.0;
  mitk::Point3D currentWorldPoint;

  double t;
  unsigned int i = 0;
  for (i = 0, t = m_DerivedPath->StartOfInput(); ;++i)
  {
    const PathType::OutputType &continousIndex = m_DerivedPath->Evaluate(t);

    mitk::Point3D worldPoint;
    imageGeometry->IndexToWorld(continousIndex, worldPoint);

    if (i == 0)
    {
      currentWorldPoint = worldPoint;
    }


    distance += currentWorldPoint.EuclideanDistanceTo(worldPoint);
    mitk::Index3D indexPoint;
    imageGeometry->WorldToIndex(worldPoint, indexPoint);
    const mitk::PixelType ptype = m_Image->GetPixelType();
    double intensity = 0.0;
    if (m_Image->GetDimension() == 4)
    {
      mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
      timeSelector->SetInput(m_Image);
      timeSelector->SetTimeNr(timeStep);
      timeSelector->Update();
      mitk::Image::Pointer image = timeSelector->GetOutput();
      mitkPixelTypeMultiplex3( ReadPixel, ptype, image, indexPoint, intensity);
    }
    else
    {
      mitkPixelTypeMultiplex3( ReadPixel, ptype, m_Image, indexPoint, intensity);
    }

    m_Measurement.insert(i, distance);
    m_Frequency.insert(i, intensity);

    // Go to next index; when iteration offset reaches zero, iteration is finished
    PathType::OffsetType offset = m_DerivedPath->IncrementInput(t);
    if (!(offset[0] || offset[1] || offset[2]))
    {
      break;
    }

    currentWorldPoint = worldPoint;
  }

  m_IntensityProfile = true;
  m_UseLineGraph = true;
  this->SignalDataChanged();
}