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

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

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

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

  crossline.SetDirection( direction );

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

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

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

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

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

  return true;
}
double mitk::TimeGeometry::GetDiagonalLength2InWorld() const
{
  Vector3D diagonalvector = GetCornerPointInWorld()-GetCornerPointInWorld(false, false, false);
  return diagonalvector.GetSquaredNorm();
}
  void SliceNavigationController::SelectSliceByPoint(const Point3D &point)
  {
    if (m_CreatedWorldGeometry.IsNull())
    {
      return;
    }

    //@todo add time to PositionEvent and use here!!
    SlicedGeometry3D *slicedWorldGeometry = dynamic_cast<SlicedGeometry3D *>(
      m_CreatedWorldGeometry->GetGeometryForTimeStep(this->GetTime()->GetPos()).GetPointer());

    if (slicedWorldGeometry)
    {
      int bestSlice = -1;
      double bestDistance = itk::NumericTraits<double>::max();

      int s, slices;
      slices = slicedWorldGeometry->GetSlices();
      if (slicedWorldGeometry->GetEvenlySpaced())
      {
        mitk::PlaneGeometry *plane = slicedWorldGeometry->GetPlaneGeometry(0);

        const Vector3D &direction = slicedWorldGeometry->GetDirectionVector();

        Point3D projectedPoint;
        plane->Project(point, projectedPoint);

        // Check whether the point is somewhere within the slice stack volume;
        // otherwise, the default slice (0) will be selected
        if (direction[0] * (point[0] - projectedPoint[0]) + direction[1] * (point[1] - projectedPoint[1]) +
              direction[2] * (point[2] - projectedPoint[2]) >=
            0)
        {
          bestSlice = (int)(plane->Distance(point) / slicedWorldGeometry->GetSpacing()[2] + 0.5);
        }
      }
      else
      {
        Point3D projectedPoint;
        for (s = 0; s < slices; ++s)
        {
          slicedWorldGeometry->GetPlaneGeometry(s)->Project(point, projectedPoint);
          const Vector3D distance = projectedPoint - point;
          ScalarType currentDistance = distance.GetSquaredNorm();

          if (currentDistance < bestDistance)
          {
            bestDistance = currentDistance;
            bestSlice = s;
          }
        }
      }
      if (bestSlice >= 0)
      {
        this->GetSlice()->SetPos(bestSlice);
      }
      else
      {
        this->GetSlice()->SetPos(0);
      }
      this->SendCreatedWorldGeometryUpdate();
    }
  }
Example #4
0
void mitk::MeshMapper2D::Paint(mitk::BaseRenderer *renderer)
{
  bool visible = true;

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

  if (!visible)
    return;

  //  @FIXME: Logik fuer update
  bool updateNeccesary = true;

  if (updateNeccesary)
  {
    // aus GenerateData
    mitk::Mesh::Pointer input = const_cast<mitk::Mesh *>(this->GetInput());

    // Get the TimeGeometry of the input object
    const TimeGeometry *inputTimeGeometry = input->GetTimeGeometry();
    if ((inputTimeGeometry == nullptr) || (inputTimeGeometry->CountTimeSteps() == 0))
    {
      return;
    }

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

    //
    // convert the world time in time steps of the input object
    //
    int timeStep = 0;
    if (time > itk::NumericTraits<mitk::ScalarType>::NonpositiveMin())
      timeStep = inputTimeGeometry->TimePointToTimeStep(time);
    if (inputTimeGeometry->IsValidTimeStep(timeStep) == false)
    {
      return;
    }

    mitk::Mesh::MeshType::Pointer itkMesh = input->GetMesh(timeStep);

    if (itkMesh.GetPointer() == nullptr)
    {
      return;
    }

    const PlaneGeometry *worldplanegeometry = (renderer->GetCurrentWorldPlaneGeometry());

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

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

    // List of the Points
    Mesh::DataType::PointsContainerConstIterator it, end;
    it = itkMesh->GetPoints()->Begin();
    end = itkMesh->GetPoints()->End();

    // iterator on the additional data of each point
    Mesh::PointDataIterator dataIt; //, dataEnd;
    dataIt = itkMesh->GetPointData()->Begin();

    // for switching back to old color after using selected color
    float unselectedColor[4];
    glGetFloatv(GL_CURRENT_COLOR, unselectedColor);

    while (it != end)
    {
      mitk::Point3D p, projected_p;
      float vtkp[3];

      itk2vtk(it->Value(), vtkp);
      transform->TransformPoint(vtkp, vtkp);
      vtk2itk(vtkp, p);

      renderer->GetCurrentWorldPlaneGeometry()->Project(p, projected_p);
      Vector3D diff = p - projected_p;
      if (diff.GetSquaredNorm() < 4.0)
      {
        Point2D pt2d, tmp;
        renderer->WorldToDisplay(p, pt2d);

        Vector2D horz, vert;
        horz[0] = 5;
        horz[1] = 0;
        vert[0] = 0;
        vert[1] = 5;

        // check if the point is to be marked as selected
        if (dataIt->Value().selected)
        {
          horz[0] = 8;
          vert[1] = 8;
          glColor3f(selectedColor[0], selectedColor[1], selectedColor[2]); // red

          switch (dataIt->Value().pointSpec)
          {
            case PTSTART:
              // a quad
              glBegin(GL_LINE_LOOP);
              tmp = pt2d - horz + vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz + vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz - vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d - horz - vert;
              glVertex2dv(&tmp[0]);
              glEnd();
              break;
            case PTUNDEFINED:
              // a diamond around the point
              glBegin(GL_LINE_LOOP);
              tmp = pt2d - horz;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz;
              glVertex2dv(&tmp[0]);
              tmp = pt2d - vert;
              glVertex2dv(&tmp[0]);
              glEnd();
              break;
            default:
              break;
          } // switch

          // the actual point
          glBegin(GL_POINTS);
          tmp = pt2d;
          glVertex2dv(&tmp[0]);
          glEnd();
        }
        else // if not selected
        {
          glColor3f(unselectedColor[0], unselectedColor[1], unselectedColor[2]);
          switch (dataIt->Value().pointSpec)
          {
            case PTSTART:
              // a quad
              glBegin(GL_LINE_LOOP);
              tmp = pt2d - horz + vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz + vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz - vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d - horz - vert;
              glVertex2dv(&tmp[0]);
              glEnd();
              break;
            case PTUNDEFINED:
              // drawing crosses
              glBegin(GL_LINES);
              tmp = pt2d - horz;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + horz;
              glVertex2dv(&tmp[0]);
              tmp = pt2d - vert;
              glVertex2dv(&tmp[0]);
              tmp = pt2d + vert;
              glVertex2dv(&tmp[0]);
              glEnd();
              break;
            default:
            {
              break;
            }
          } // switch
        }   // else
      }
      ++it;
      ++dataIt;
    }

    // now connect the lines inbetween
    mitk::Mesh::PointType thisPoint;
    thisPoint.Fill(0);
    Point2D *firstOfCell = nullptr;
    Point2D *lastPoint = nullptr;
    unsigned int lastPointId = 0;
    bool lineSelected = false;

    Point3D firstOfCell3D;
    Point3D lastPoint3D;
    bool first;
    mitk::Line<mitk::ScalarType> line;
    std::vector<mitk::Point3D> intersectionPoints;
    double t;

    // iterate through all cells and then iterate through all indexes of points in that cell
    Mesh::CellIterator cellIt, cellEnd;
    Mesh::CellDataIterator cellDataIt; //, cellDataEnd;
    Mesh::PointIdIterator cellIdIt, cellIdEnd;

    cellIt = itkMesh->GetCells()->Begin();
    cellEnd = itkMesh->GetCells()->End();
    cellDataIt = itkMesh->GetCellData()->Begin();

    while (cellIt != cellEnd)
    {
      unsigned int numOfPointsInCell = cellIt->Value()->GetNumberOfPoints();
      if (numOfPointsInCell > 1)
      {
        // iterate through all id's in the cell
        cellIdIt = cellIt->Value()->PointIdsBegin();
        cellIdEnd = cellIt->Value()->PointIdsEnd();

        firstOfCell3D = input->GetPoint(*cellIdIt, timeStep);

        intersectionPoints.clear();
        intersectionPoints.reserve(numOfPointsInCell);

        first = true;

        while (cellIdIt != cellIdEnd)
        {
          lastPoint3D = thisPoint;

          thisPoint = input->GetPoint(*cellIdIt, timeStep);

          // search in data (vector<> selectedLines) if the index of the point is set. if so, then the line is selected.
          lineSelected = false;
          Mesh::SelectedLinesType selectedLines = cellDataIt->Value().selectedLines;

          // a line between 1(lastPoint) and 2(pt2d) has the Id 1, so look for the Id of lastPoint
          // since we only start, if we have more than one point in the cell, lastPointId is initiated with 0
          Mesh::SelectedLinesIter position = std::find(selectedLines.begin(), selectedLines.end(), lastPointId);
          if (position != selectedLines.end())
          {
            lineSelected = true;
          }

          mitk::Point3D p, projected_p;
          float vtkp[3];
          itk2vtk(thisPoint, vtkp);
          transform->TransformPoint(vtkp, vtkp);
          vtk2itk(vtkp, p);
          renderer->GetCurrentWorldPlaneGeometry()->Project(p, projected_p);
          Vector3D diff = p - projected_p;
          if (diff.GetSquaredNorm() < 4.0)
          {
            Point2D pt2d, tmp;
            renderer->WorldToDisplay(p, pt2d);

            if (lastPoint == nullptr)
            {
              // set the first point in the cell. This point in needed to close the polygon
              firstOfCell = new Point2D;
              *firstOfCell = pt2d;
              lastPoint = new Point2D;
              *lastPoint = pt2d;
              lastPointId = *cellIdIt;
            }
            else
            {
              if (lineSelected)
              {
                glColor3f(selectedColor[0], selectedColor[1], selectedColor[2]); // red
                // a line from lastPoint to thisPoint
                glBegin(GL_LINES);
                glVertex2dv(&(*lastPoint)[0]);
                glVertex2dv(&pt2d[0]);
                glEnd();
              }
              else // if not selected
              {
                glColor3f(unselectedColor[0], unselectedColor[1], unselectedColor[2]);
                // drawing crosses
                glBegin(GL_LINES);
                glVertex2dv(&(*lastPoint)[0]);
                glVertex2dv(&pt2d[0]);
                glEnd();
              }
              // to draw the line to the next in iteration step
              *lastPoint = pt2d;
              // and to search for the selection state of the line
              lastPointId = *cellIdIt;
            } // if..else
          }   // if <4.0

          // fill off-plane polygon part 1
          if ((!first) && (worldplanegeometry != nullptr))
          {
            line.SetPoints(lastPoint3D, thisPoint);
            if (worldplanegeometry->IntersectionPointParam(line, t) && ((t >= 0) && (t <= 1)))
            {
              intersectionPoints.push_back(line.GetPoint(t));
            }
          }
          ++cellIdIt;
          first = false;
        } // while cellIdIter

        // closed polygon?
        if (cellDataIt->Value().closed)
        {
          // close the polygon if needed
          if (firstOfCell != nullptr)
          {
            lineSelected = false;
            Mesh::SelectedLinesType selectedLines = cellDataIt->Value().selectedLines;
            Mesh::SelectedLinesIter position = std::find(selectedLines.begin(), selectedLines.end(), lastPointId);
            if (position != selectedLines.end()) // found the index
            {
              glColor3f(selectedColor[0], selectedColor[1], selectedColor[2]); // red
              // a line from lastPoint to firstPoint
              glBegin(GL_LINES);
              glVertex2dv(&(*lastPoint)[0]);
              glVertex2dv(&(*firstOfCell)[0]);
              glEnd();
            }
            else
            {
              glColor3f(unselectedColor[0], unselectedColor[1], unselectedColor[2]);
              glBegin(GL_LINES);
              glVertex2dv(&(*lastPoint)[0]);
              glVertex2dv(&(*firstOfCell)[0]);
              glEnd();
            }
          }
        } // if closed

        // Axis-aligned bounding box(AABB) around the cell if selected and set in Property
        bool showBoundingBox;
        if (dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("showBoundingBox")) == nullptr)
          showBoundingBox = false;
        else
          showBoundingBox =
            dynamic_cast<mitk::BoolProperty *>(this->GetDataNode()->GetProperty("showBoundingBox"))->GetValue();

        if (showBoundingBox)
        {
          if (cellDataIt->Value().selected)
          {
            mitk::Mesh::DataType::BoundingBoxPointer aABB = input->GetBoundingBoxFromCell(cellIt->Index());
            if (aABB.IsNotNull())
            {
              mitk::Mesh::PointType min, max;
              min = aABB->GetMinimum();
              max = aABB->GetMaximum();

              // project to the displayed geometry
              Point2D min2D, max2D;
              Point3D p, projected_p;
              float vtkp[3];
              itk2vtk(min, vtkp);
              transform->TransformPoint(vtkp, vtkp);
              vtk2itk(vtkp, p);
              renderer->WorldToDisplay(p, min2D);

              itk2vtk(max, vtkp);
              transform->TransformPoint(vtkp, vtkp);
              vtk2itk(vtkp, p);
              renderer->GetCurrentWorldPlaneGeometry()->Project(p, projected_p);
              Vector3D diff = p - projected_p;
              if (diff.GetSquaredNorm() < 4.0)
              {
                renderer->WorldToDisplay(p, max2D);

                // draw the BoundingBox
                glColor3f(selectedColor[0], selectedColor[1], selectedColor[2]); // red
                // a line from lastPoint to firstPoint
                glBegin(GL_LINE_LOOP);
                glVertex2f(min2D[0], min2D[1]);
                glVertex2f(min2D[0], max2D[1]);
                glVertex2f(max2D[0], max2D[1]);
                glVertex2f(max2D[0], min2D[1]);
                glEnd();
              } // draw bounding-box
            }   // bounding-box exists
          }     // cell selected
        }       // show bounding-box

        // fill off-plane polygon part 2
        if (worldplanegeometry != nullptr)
        {
          // consider line from last to first
          line.SetPoints(thisPoint, firstOfCell3D);
          if (worldplanegeometry->IntersectionPointParam(line, t) && ((t >= 0) && (t <= 1)))
          {
            intersectionPoints.push_back(line.GetPoint(t));
          }
          std::sort(intersectionPoints.begin(), intersectionPoints.end(), point3DSmaller);
          std::vector<mitk::Point3D>::iterator it, end;
          end = intersectionPoints.end();
          if ((intersectionPoints.size() % 2) != 0)
          {
            --end; // ensure even number of intersection-points
          }
          Point2D pt2d;
          for (it = intersectionPoints.begin(); it != end; ++it)
          {
            glBegin(GL_LINES);
            renderer->WorldToDisplay(*it, pt2d);
            glVertex2dv(pt2d.GetDataPointer());
            ++it;
            renderer->WorldToDisplay(*it, pt2d);
            glVertex2dv(pt2d.GetDataPointer());
            glEnd();
          }
          if (it != intersectionPoints.end())
          {
            glBegin(GL_LINES);
            renderer->WorldToDisplay(*it, pt2d);
            glVertex2dv(pt2d.GetDataPointer());
            glVertex2dv(pt2d.GetDataPointer());
            glEnd();
          }
        } // fill off-plane polygon part 2
      }   // if numOfPointsInCell>1
      delete firstOfCell;
      delete lastPoint;
      lastPoint = nullptr;
      firstOfCell = nullptr;
      lastPointId = 0;
      ++cellIt;
      ++cellDataIt;
    }
  }
}