/* * 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(); }
void mitk::SurfaceStampImageFilter::SurfaceStamp(int time) { mitk::Image::Pointer inputImage = this->GetInput(); const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry(); const mitk::TimeGeometry *imageTimeGeometry = inputImage->GetTimeGeometry(); // Convert time step from image time-frame to surface time-frame mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time); mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint); vtkPolyData *polydata = m_Surface->GetVtkPolyData(surfaceTimeStep); if (!polydata) mitkThrow() << "Polydata is null."; vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); transformFilter->SetInputData(polydata); // transformFilter->ReleaseDataFlagOn(); vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); BaseGeometry::Pointer geometry = surfaceTimeGeometry->GetGeometryForTimeStep(surfaceTimeStep); transform->PostMultiply(); transform->Concatenate(geometry->GetVtkTransform()->GetMatrix()); // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below. BaseGeometry::Pointer imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time); transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse()); transformFilter->SetTransform(transform); transformFilter->Update(); polydata = transformFilter->GetOutput(); if (!polydata || !polydata->GetNumberOfPoints()) mitkThrow() << "Polydata retrieved from transformation is null or has no points."; MeshType::Pointer mesh = MeshType::New(); mesh->SetCellsAllocationMethod(MeshType::CellsAllocatedDynamicallyCellByCell); unsigned int numberOfPoints = polydata->GetNumberOfPoints(); mesh->GetPoints()->Reserve(numberOfPoints); vtkPoints *points = polydata->GetPoints(); MeshType::PointType point; for (unsigned int i = 0; i < numberOfPoints; i++) { double *aux = points->GetPoint(i); point[0] = aux[0]; point[1] = aux[1]; point[2] = aux[2]; mesh->SetPoint(i, point); } // Load the polygons into the itk::Mesh typedef MeshType::CellAutoPointer CellAutoPointerType; typedef MeshType::CellType CellType; typedef itk::TriangleCell<CellType> TriangleCellType; typedef MeshType::PointIdentifier PointIdentifierType; typedef MeshType::CellIdentifier CellIdentifierType; // Read the number of polygons CellIdentifierType numberOfPolygons = 0; numberOfPolygons = polydata->GetNumberOfPolys(); PointIdentifierType numberOfCellPoints = 3; CellIdentifierType i = 0; for (i = 0; i < numberOfPolygons; i++) { vtkIdList *cellIds; vtkCell *vcell = polydata->GetCell(i); cellIds = vcell->GetPointIds(); CellAutoPointerType cell; auto *triangleCell = new TriangleCellType; PointIdentifierType k; for (k = 0; k < numberOfCellPoints; k++) { triangleCell->SetPointId(k, cellIds->GetId(k)); } cell.TakeOwnership(triangleCell); mesh->SetCell(i, cell); } if (!mesh->GetNumberOfPoints()) mitkThrow() << "Generated itk mesh is empty."; if (m_MakeOutputBinary) { this->SurfaceStampBinaryOutputProcessing(mesh); } else { AccessFixedDimensionByItk_1(inputImage, SurfaceStampProcessing, 3, mesh); } }