Beispiel #1
0
mitk::Mesh::DataType::BoundingBoxPointer
mitk::Mesh::GetBoundingBoxFromCell( unsigned long cellId, int t )
{
  // itk::CellInterface has also a GetBoundingBox, but it
  // returns CoordRepType [PointDimension *2]
  DataType::BoundingBoxPointer bBoxPointer = nullptr;
  CellAutoPointer cellAutoPointer;
  if ( m_PointSetSeries[t]->GetCell(cellId, cellAutoPointer))
  {
    DataType::PointsContainerPointer pointsContainer = DataType::PointsContainer::New();
    PointIdIterator bbIt = cellAutoPointer.GetPointer()->PointIdsBegin();
    PointIdIterator bbEnd = cellAutoPointer.GetPointer()->PointIdsEnd();
    while(bbIt != bbEnd)
    {
      mitk::PointSet::PointType point;
      bool pointOk = m_PointSetSeries[t]->GetPoint((*bbIt), &point);
      if (pointOk)
        pointsContainer->SetElement((*bbIt), point);
      ++bbIt;
    }
    bBoxPointer = DataType::BoundingBoxType::New();
    bBoxPointer->SetPoints(pointsContainer);
    bBoxPointer->ComputeBoundingBox();
  }
  return bBoxPointer;
}
Beispiel #2
0
// get the cell; then iterate through the Ids times lineId. Then IdA ist the
// one, IdB ist ne next.don't forget the last closing line if the cell is
// closed
bool mitk::Mesh::GetPointIds( unsigned long cellId, unsigned long lineId,
  int &idA, int &idB, int t )
{
  bool ok = false;
  bool found = false;
  CellAutoPointer cellAutoPointer;
  ok = m_PointSetSeries[t]->GetCell(cellId, cellAutoPointer);
  if (ok)
  {

    CellType * cell = cellAutoPointer.GetPointer();

    //Get the cellData to also check the closing line
    CellDataType cellData;
    m_PointSetSeries[t]->GetCellData(cellId, &cellData);
    bool closed = cellData.closed;

    PointIdIterator pointIdIt = cell->PointIdsBegin();
    PointIdIterator pointIdEnd = cell->PointIdsEnd();
    unsigned int counter = 0;
    while (pointIdIt != pointIdEnd)
    {
      if(counter == lineId)
      {
        idA = (*pointIdIt);
        ++pointIdIt;
        found = true;
        break;
      }
      ++counter;
      ++pointIdIt;
    }
    if(found)
    {
      //if in the middle
      if (pointIdIt != pointIdEnd)
      {
        idB = (*pointIdIt);
      }
      // if found but on the end, then it is the closing connection, so the
      // last and the first point
      else if (closed)
      {
        pointIdIt = cell->PointIdsBegin();
        idB = (*pointIdIt);
      }
    }
    else
      ok = false;
  }
  return ok;
}
Beispiel #3
0
void mitk::Mesh::ExecuteOperation(Operation* operation)
{
  //adding only the operations, that aren't implemented by the pointset.
  switch (operation->GetOperationType())
  {
  case OpNOTHING:
    break;

  case OpNEWCELL:
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);

      // if no lineoperation, then call superclass pointSet
      if (lineOp == nullptr)
      {
        Superclass::ExecuteOperation(operation);
      }

      bool ok;
      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);

      // if it doesn't already exist
      if (!ok)
      {
        cellAutoPointer.TakeOwnership( new PolygonType );
        m_PointSetSeries[0]->SetCell(cellId, cellAutoPointer);
        CellDataType cellData;
        cellData.selected = true;
        cellData.selectedLines.clear();
        cellData.closed = false;
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpDELETECELL:
    {
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }
      m_PointSetSeries[0]->GetCells()->DeleteIndex((unsigned)lineOp->GetCellId());
      m_PointSetSeries[0]->GetCellData()->DeleteIndex((unsigned)lineOp->GetCellId());
    }
    break;

  case OpCLOSECELL:
    //sets the bolean flag closed from a specified cell to true.
    {
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        //then search the selected cell!//TODO
        Superclass::ExecuteOperation(operation);
      }
      bool ok;
      int cellId = lineOp->GetCellId();
      if (cellId<0)//cellId isn't set
      {
        cellId = this->SearchSelectedCell( 0 );
        if (cellId < 0 )//still not found
          return;
      }
      CellAutoPointer cellAutoPointer;

      //get directly the celldata!TODO
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        cellData.closed = true;
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpOPENCELL:
    {
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }
      bool ok;
      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        cellData.closed = false;;
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpADDLINE:
    // inserts the ID of the selected point into the indexes of lines in the
    // selected cell afterwars the added line is selected
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);

      int cellId = -1;
      int pId = -1;

      if (lineOp == nullptr)
      {
        cellId = this->SearchSelectedCell( 0 );
        if (cellId == -1)
          return;

        pId = this->SearchSelectedPoint( 0 );
        if (pId == -1)
          return;
      }
      else
      {
        cellId = lineOp->GetCellId();
        if (cellId == -1)
          return;
        pId = lineOp->GetPIdA();
        if (pId == -1)
          return;
      }

      bool ok;
      CellAutoPointer cellAutoPointer;
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellType * cell = cellAutoPointer.GetPointer();
        if( cell->GetType() == CellType::POLYGON_CELL )
        {
          PolygonType * polygon = static_cast<PolygonType *>( cell );
          // add the pointId to the Cell. filling the empty cell with
          // one id doesn't mean to add a line, it means, that the
          // initilal PointId is set. The next addition of a pointId adds
          // a line
          polygon->AddPointId(pId);

          // select the line, if we really added a line, so now have more than
          // 1 pointID in the cell
          CellDataType cellData;
          ok = m_PointSetSeries[0]->GetCellData(cellId, &cellData);
          if (ok)
          {
            // A line between point 0 and 1 has the Id 0. A line between
            // 1 and 2 has a Id = 1. So we add getnumberofpoints-2.
            if (polygon->GetNumberOfPoints()>1)
              cellData.selectedLines.push_back(polygon->GetNumberOfPoints()-2);
          }
          m_PointSetSeries[0]->SetCellData(cellId, cellData);
          m_PointSetSeries[0]->SetCell(cellId, cellAutoPointer);
        }
      }
    }
    break;

  case OpDELETELINE:
    {
      // deleted the last line through removing the index PIdA
      // (if set to -1, use the last point) in the given cellId
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      int cellId = -1;
      int pId = -1;

      if (lineOp == nullptr)
      {
        cellId = this->SearchSelectedCell( 0 );
        if (cellId == -1)
          return;
        pId = this->SearchSelectedPoint( 0 );
      }
      else
      {
        cellId = lineOp->GetCellId();
        if (cellId == -1)
          return;
        pId = lineOp->GetPIdA();
      }

      bool ok;
      CellAutoPointer cellAutoPointer;
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellType * cell = cellAutoPointer.GetPointer();
        if( cell->GetType() == CellType::POLYGON_CELL )
        {
          PolygonType * oldPolygon = static_cast<PolygonType *>( cell );

          auto   newPolygonCell = new PolygonType;
          CellAutoPointer newCell;
          newCell.TakeOwnership( newPolygonCell );

          PointIdConstIterator it, oldend;
          oldend = oldPolygon->PointIdsEnd();
          if(pId >= 0)
          {
            for(it = oldPolygon->PointIdsBegin(); it != oldend; ++it)
            {
              if((*it) != (MeshType::PointIdentifier)pId)
              {
                newPolygonCell->AddPointId(*it);
              }
            }
          }
          else
          {
            --oldend;
            for(it = oldPolygon->PointIdsBegin(); it != oldend; ++it)
              newPolygonCell->AddPointId(*it);
          }
          oldPolygon->SetPointIds(0, newPolygonCell->GetNumberOfPoints(),
            newPolygonCell->PointIdsBegin());
        }
      }
    }
    break;

  case OpREMOVELINE:
    //Remove the given Index in the given cell through copying everything
    // into a new cell accept the one that has to be deleted.
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }

      bool ok;
      CellAutoPointer cellAutoPointer;
      int cellId = lineOp->GetCellId();
      ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (!ok)
        return;

      CellType * cell = cellAutoPointer.GetPointer();
      CellAutoPointer newCellAutoPointer;
      newCellAutoPointer.TakeOwnership( new PolygonType );
      PolygonType * newPolygon = static_cast<PolygonType *>( cell );

      PointIdIterator it = cell->PointIdsBegin();
      PointIdIterator end = cell->PointIdsEnd();
      int pointId = lineOp->GetPIdA();
      if (pointId<0)//if not initialized!!
        return;

      while (it!=end)
      {
        if ((*it)==(unsigned int)pointId)
        {
          break;
        }
        else
        {
          newPolygon ->AddPointId(*it);
        }
        ++it;
      }
      while (it!=end)
      {
        newPolygon ->AddPointId(*it);
        it++;
      }
      m_PointSetSeries[0]->SetCell(cellId, newCellAutoPointer);
    }
    break;

  case OpINSERTLINE:
    //  //insert line between two other points.
    ////before A--B   after  A--C--B
    //  //the points A, B and C have to be in the pointset.
    //  //needed: CellId, Id of C , Id A and Id B
    ////the cell has to exist!
    //{
    //mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
    //  if (lineOp == NULL)//if no lineoperation, then call superclass pointSet
    // {
    //    Superclass::ExecuteOperation(operation);
    //  }
    //    int cellId = lineOp->GetCellId();
    //    int pIdC = lineOp->GetPIdC();
    //  int pIdA = lineOp->GetPIdA();
    //    int pIdB = lineOp->GetPIdB();

    //    //the points of the given PointIds have to exist in the PointSet
    //    bool ok;
    //    ok = m_PointSetSeries[0]->GetPoints()->IndexExists(pIdA);
    //    if (!ok)
    //      return;
    //    ok = m_PointSetSeries[0]->GetPoints()->IndexExists(pIdB);
    //    if (!ok)
    //      return;
    //  ok = m_PointSetSeries[0]->GetPoints()->IndexExists(pIdC);
    //    if (!ok)
    //      return;

    //    // so the points do exist. So now check, if there is already a cell
    //    // with the given Id
    //    DataType::CellAutoPointer cell;
    //    ok = m_PointSetSeries[0]->GetCell(cellId, cell);
    //  if (!ok)
    //    return;

    //  //pIdA and pIdB should exist in the cell
    //
    //  PointIdIterator pit = cell->PointIdsBegin();
    //    PointIdIterator end = cell->PointIdsEnd();
    //
    //  //now arrange the new Ids in the cell like desired; pIdC between
    //  // pIdA and pIdB
    //  unsigned int nuPoints = cell->GetNumberOfPoints();

    //  std::vector<unsigned int> newPoints;
    //  pit = cell->PointIdsBegin();
    //    end = cell->PointIdsEnd();
    //    int i = 0;
    //    while( pit != end )
    //    {
    //      if ((*pit) = pIdA)
    //      {
    //        //now we have found the place to add pIdC after
    //        newPoints[i] = (*pit);
    //        i++;
    //        newPoints[i] = pIdC;
    //      }
    //      else
    //        newPoints[i] = (*pit);
    //      pit++;
    //    }

    //  //now we have the Ids, that existed before combined with the new ones
    //  //so delete the old cell
    //  //doesn't seem to be necessary!
    //  //cell->ClearPoints();
    //  pit = cell->PointIdsBegin();
    //  cell->SetPointIds(pit);
    //}
    break;

  case OpMOVELINE://(moves two points)
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);

      if (lineOp == nullptr)
      {
        mitk::StatusBar::GetInstance()->DisplayText(
          "Message from mitkMesh: Recieved wrong type of operation! See mitkMeshInteractor.cpp", 10000);
        return;
      }

      //create two operations out of the one operation and call superclass
      //through the transmitted pointIds get the koordinates of the points.
      //then add the transmitted vestor to them
      //create two operations and send them to superclass
      Point3D pointA, pointB;
      pointA.Fill(0.0);
      pointB.Fill(0.0);
      m_PointSetSeries[0]->GetPoint(lineOp->GetPIdA(), &pointA);
      m_PointSetSeries[0]->GetPoint(lineOp->GetPIdB(), &pointB);

      pointA[0] += lineOp->GetVector()[0];
      pointA[1] += lineOp->GetVector()[1];
      pointA[2] += lineOp->GetVector()[2];
      pointB[0] += lineOp->GetVector()[0];
      pointB[1] += lineOp->GetVector()[1];
      pointB[2] += lineOp->GetVector()[2];

      auto   operationA =
        new mitk::PointOperation(OpMOVE, pointA, lineOp->GetPIdA());
      auto   operationB =
        new mitk::PointOperation(OpMOVE, pointB, lineOp->GetPIdB());

      Superclass::ExecuteOperation(operationA);
      Superclass::ExecuteOperation(operationB);
    }
    break;

  case OpSELECTLINE://(select the given line)
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }
      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;
      bool ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        SelectedLinesType *selectedLines = &(cellData.selectedLines);
        auto position = std::find(selectedLines->begin(),
          selectedLines->end(), (unsigned int) lineOp->GetId());

        if (position == selectedLines->end())//if not alsready selected
        {
          cellData.selectedLines.push_back(lineOp->GetId());
        }
        m_PointSetSeries[0]->SetCellData(lineOp->GetCellId(), cellData);
      }
    }
    break;

  case OpDESELECTLINE://(deselect the given line)
    {
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)
      {
        Superclass::ExecuteOperation(operation);
      }
      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;
      bool ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        SelectedLinesType *selectedLines = &(cellData.selectedLines);
        auto position = std::find(selectedLines->begin(),
          selectedLines->end(), (unsigned int) lineOp->GetId());

        if (position != selectedLines->end())//if found
        {
          selectedLines->erase(position);
        }
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpSELECTCELL://(select the given cell)
    {
      mitk::LineOperation *lineOp =
        dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }

      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;

      //directly get the data!//TODO
      bool ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        cellData.selected = true;
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpDESELECTCELL://(deselect the given cell)
    {
      mitk::LineOperation *lineOp = dynamic_cast<mitk::LineOperation *>(operation);
      if (lineOp == nullptr)//if no lineoperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }
      int cellId = lineOp->GetCellId();
      CellAutoPointer cellAutoPointer;
      bool ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (ok)
      {
        CellDataType cellData;
        m_PointSetSeries[0]->GetCellData(cellId, &cellData);
        cellData.selected = false;
        m_PointSetSeries[0]->SetCellData(cellId, cellData);
      }
    }
    break;

  case OpMOVECELL:
    //moves all Points of one cell according to the given vector
    {
      mitk::CellOperation *lineOp = dynamic_cast<mitk::CellOperation *>(operation);
      if (lineOp == nullptr)//if no celloperation, then call superclass pointSet
      {
        Superclass::ExecuteOperation(operation);
      }

      int cellId = lineOp->GetCellId();
      Vector3D vector = lineOp->GetVector();

      //get the cell
      CellAutoPointer cellAutoPointer;
      bool ok = m_PointSetSeries[0]->GetCell(cellId, cellAutoPointer);
      if (!ok)
        return;

      CellDataType cellData;
      m_PointSetSeries[0]->GetCellData(cellId, &cellData);
      // iterate through the pointIds of the CellData and move those points in
      // the pointset
      PointIdIterator it = cellAutoPointer->PointIdsBegin();
      PointIdIterator end = cellAutoPointer->PointIdsEnd();
      while(it != end)
      {
        unsigned int position = (*it);
        PointType point;
        point.Fill(0);
        m_PointSetSeries[0]->GetPoint(position, &point);
        point = point + vector;
        m_PointSetSeries[0]->SetPoint(position, point);
        ++it;
      }

    }
    break;

  default:
    //if the operation couldn't be handled here, then send it to superclass
    Superclass::ExecuteOperation(operation);
    return;
  }
  //to tell the mappers, that the data is modifierd and has to be updated
  this->Modified();

  mitk::OperationEndEvent endevent(operation);
  ((const itk::Object*)this)->InvokeEvent(endevent);

  // As discussed lately, don't mess with rendering from inside data structures
  //*todo has to be done here, cause of update-pipeline not working yet
  //mitk::RenderingManager::GetInstance()->RequestUpdateAll();

}
/*
 * mexFunction(): entry point for the mex function
 */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

  // interface to deal with input arguments from Matlab
  enum InputIndexType {IN_TRI, IN_X, IN_RES, IN_SIZE, IN_ORIGIN, InputIndexType_MAX};
  MatlabImportFilter::Pointer matlabImport = MatlabImportFilter::New();
  matlabImport->ConnectToMatlabFunctionInput(nrhs, prhs);

  // check the number of input arguments
  matlabImport->CheckNumberOfArguments(2, InputIndexType_MAX);

  // register the inputs for this function at the import filter
  typedef MatlabImportFilter::MatlabInputPointer MatlabInputPointer;
  MatlabInputPointer inTRI = matlabImport->RegisterInput(IN_TRI, "TRI");
  MatlabInputPointer inX = matlabImport->RegisterInput(IN_X, "X"); // (x, y, z)
  MatlabInputPointer inRES = matlabImport->RegisterInput(IN_RES, "RES"); // (r, c, s)
  MatlabInputPointer inSIZE = matlabImport->RegisterInput(IN_SIZE, "SIZE"); // (r, c, s)
  MatlabInputPointer inORIGIN = matlabImport->RegisterInput(IN_ORIGIN, "ORIGIN"); // (x, y, z)

  // interface to deal with outputs to Matlab
  enum OutputIndexType {OUT_IM, OutputIndexType_MAX};
  MatlabExportFilter::Pointer matlabExport = MatlabExportFilter::New();
  matlabExport->ConnectToMatlabFunctionOutput(nlhs, plhs);
  
  // check that the number of outputs the user is asking for is valid
  matlabExport->CheckNumberOfArguments(0, OutputIndexType_MAX);

  // register the outputs for this function at the export filter
  typedef MatlabExportFilter::MatlabOutputPointer MatlabOutputPointer;
  MatlabOutputPointer outIM = matlabExport->RegisterOutput(OUT_IM, "IM");

  // if any input point set is empty, the outputs are empty too
  if (mxIsEmpty(inTRI->pm) || mxIsEmpty(inX->pm)) {
    matlabExport->CopyEmptyArrayToMatlab(outIM);
    return;
  }

  // get number of rows in inputs X and TRI
  mwSize nrowsX = mxGetM(inX->pm);
  mwSize nrowsTRI = mxGetM(inTRI->pm);

  // instantiate mesh
  MeshType::Pointer mesh = MeshType::New();

  // read vertices
  PointSetType::Pointer xDef = PointSetType::New(); // default: empty point set
  PointSetType::Pointer x = PointSetType::New();
  x->GetPoints()->CastToSTLContainer()
    = matlabImport->ReadVectorOfVectorsFromMatlab<PointType::CoordRepType, PointType>
    (inX, xDef->GetPoints()->CastToSTLContainer());

#ifdef DEBUG
  std::cout << "Number of X points read = " << x->GetNumberOfPoints() << std::endl;
#endif

  // assertion check
  if (nrowsX != x->GetNumberOfPoints()) {
    mexErrMsgTxt(("Input " + inX->name 
		  + ": Number of points read different from number of points provided by user").c_str()); 
  }

  // swap XY coordinates to make them compliant with ITK convention
  // (see important programming note at the help header above)
  matlabImport->SwapXYInVectorOfVectors<PointType::CoordRepType, std::vector<PointType> >
    (x->GetPoints()->CastToSTLContainer(), x->GetNumberOfPoints());

  // populate mesh with vertices
  mesh->SetPoints(x->GetPoints());

  // read triangles
  PointType triDef;
  triDef.Fill(mxGetNaN());
  for (mwIndex i = 0; i < nrowsTRI; ++i) {

    PointType triangle = matlabImport->ReadRowVectorFromMatlab<CoordType, PointType>(inTRI, i, triDef);

    // create a triangle cell to read the vertex indices of the current input triangle
    CellAutoPointer cell;
    cell.TakeOwnership(new TriangleType);

    // assign to the 0, 1, 2 elements in the triangle cell the vertex
    // indices that we have just read. Note that we have to substract
    // 1 to convert Matlab's index convention 1, 2, 3, ... to C++
    // convention 0, 1, 2, ...
    cell->SetPointId(0, triangle[0] - 1);
    cell->SetPointId(1, triangle[1] - 1);
    cell->SetPointId(2, triangle[2] - 1);

    // insert cell into the mesh
    mesh->SetCell(i, cell);
  }

#ifdef DEBUG
  std::cout << "Number of triangles read = " << mesh->GetNumberOfCells() << std::endl;
#endif

  // assertion check
  if (nrowsTRI != mesh->GetNumberOfCells()) {
    mexErrMsgTxt(("Input " + inTRI->name 
		  + ": Number of triangles read different from number of triangles provided by user").c_str()); 
  }

  // get user input parameters for the output rasterization
  ImageType::SpacingType spacingDef;
  spacingDef.Fill(1.0);
  ImageType::SpacingType spacing = matlabImport->
    ReadRowVectorFromMatlab<ImageType::SpacingValueType, ImageType::SpacingType>(inRES, spacingDef);

  ImageType::SizeType sizeDef;
  sizeDef.Fill(10);
  ImageType::SizeType size = matlabImport->
    ReadRowVectorFromMatlab<ImageType::SizeValueType, ImageType::SizeType>(inSIZE, sizeDef);

  ImageType::PointType originDef;
  originDef.Fill(0.0);
  ImageType::PointType origin = matlabImport->
    ReadRowVectorFromMatlab<ImageType::PointType::ValueType, ImageType::PointType>(inORIGIN, originDef);
  // (see important programming note at the help header above)
  matlabImport->SwapXYInVector<ImageType::PointType::ValueType, ImageType::PointType>(origin);

  // instantiate rasterization filter
  MeshFilterType::Pointer meshFilter = MeshFilterType::New();

  // smallest voxel side length
  ImageType::SpacingValueType minSpacing = spacing[0];
  for (mwIndex i = 1; i < Dimension; ++i) {
    minSpacing = std::min(minSpacing, spacing[i]);
  }

  // pass input parameters to the filter
  meshFilter->SetInput(mesh);
  meshFilter->SetSpacing(spacing);
  meshFilter->SetSize(size);
  meshFilter->SetOrigin(origin);
  meshFilter->SetTolerance(minSpacing / 10.0);
  meshFilter->SetInsideValue(1);
  meshFilter->SetOutsideValue(0);

  ImageType::IndexType start;
  start.Fill(0);
  meshFilter->SetIndex(start);

  // convert image size from itk::Size format to std::vector<mwSize>
  // so that we can use it in GraftItkImageOntoMatlab
  std::vector<mwSize> sizeStdVector(Dimension);
  for (unsigned int i = 0; i < Dimension; ++i) {
    sizeStdVector[i] = size[i];
  }

  // graft ITK filter output onto Matlab output
  matlabExport->GraftItkImageOntoMatlab<PixelType, Dimension>
    (outIM, meshFilter->GetOutput(), sizeStdVector);

#ifdef DEBUG
  std::cout << "Resolution (spacing) = " << meshFilter->GetSpacing() << std::endl;
  std::cout << "Size = " << meshFilter->GetSize() << std::endl;
  std::cout << "Origin = " << meshFilter->GetOrigin() << std::endl;
#endif
  
  // run rasterization
  meshFilter->Update();

}