double DistanceTwoVertices(double* vertices, unsigned numVertices, vtkIdType* edgeEnds) { double x_diff = acces_2d(vertices, edgeEnds[0], 0, numVertices) - acces_2d(vertices, edgeEnds[1], 0, numVertices); double y_diff = acces_2d(vertices, edgeEnds[0], 1, numVertices) - acces_2d(vertices, edgeEnds[1], 1, numVertices); double dist = sqrt(x_diff*x_diff + y_diff*y_diff); return dist; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { double cellSurfaceAreaToVolumeRatio = mxGetScalar( mxGetField(prhs[0], 0, "cellSurfaceAreaToVolumeRatio") ); double cellMembraneCapacitance = mxGetScalar( mxGetField(prhs[0], 0, "cellMembraneCapacitance") ); double leftConductivity = mxGetScalar( mxGetField(prhs[0], 0, "leftConductivity") ); double pdeTimeStep = mxGetScalar( mxGetField(prhs[0], 0, "pdeTimeStep") ); double spaceStep = mxGetScalar( mxGetField(prhs[0], 0, "spaceStep") ); double rightConductivity = mxGetScalar( mxGetField(prhs[0], 0, "rightConductivity") ); unsigned numberCells = mxGetScalar( mxGetField(prhs[0], 0, "numberCells") ); double surfaceRatioTimesCapacitance = cellSurfaceAreaToVolumeRatio * cellMembraneCapacitance; double leftCondutivityTimesTimeStepOverSpaceStepSquared = leftConductivity * pdeTimeStep / (spaceStep*spaceStep); double rightCondutivityTimesTimeStepOverSpaceStepSquared = rightConductivity * pdeTimeStep / (spaceStep*spaceStep); // Create a dense matrix mxArray* denseMatrix = mxCreateDoubleMatrix(numberCells, numberCells, mxREAL); // Get a C pointer to the dense matrix double *systemMatrix = mxGetPr(denseMatrix); unsigned rowIndex; double condutivityTimesTimeStepOverSpaceStepSquared; // Fill in matrix row 0 acces_2d(systemMatrix,0,0,numberCells) = surfaceRatioTimesCapacitance + 2*leftCondutivityTimesTimeStepOverSpaceStepSquared; acces_2d(systemMatrix,0,1,numberCells) = -2*leftCondutivityTimesTimeStepOverSpaceStepSquared; // Fill in rows 1 to numberCells-2 for (rowIndex=1;rowIndex<numberCells-1;rowIndex++) { // Determine which conductivity to use (left half or right half) if (rowIndex < (numberCells)/2) { condutivityTimesTimeStepOverSpaceStepSquared = leftCondutivityTimesTimeStepOverSpaceStepSquared; } else { condutivityTimesTimeStepOverSpaceStepSquared = rightCondutivityTimesTimeStepOverSpaceStepSquared; } acces_2d(systemMatrix,rowIndex,rowIndex-1,numberCells) = -condutivityTimesTimeStepOverSpaceStepSquared; acces_2d(systemMatrix,rowIndex,rowIndex,numberCells) = surfaceRatioTimesCapacitance + 2*condutivityTimesTimeStepOverSpaceStepSquared; acces_2d(systemMatrix,rowIndex,rowIndex+1,numberCells) = -condutivityTimesTimeStepOverSpaceStepSquared; } // Fill in row numberCells-1 acces_2d(systemMatrix,numberCells-1,numberCells-2,numberCells) = -2*rightCondutivityTimesTimeStepOverSpaceStepSquared; acces_2d(systemMatrix,numberCells-1,numberCells-1,numberCells) = surfaceRatioTimesCapacitance + 2*rightCondutivityTimesTimeStepOverSpaceStepSquared; // Do the conversion from dense to sparse (the output goes into plhs, ready to be returned by the MEX function) mexCallMATLAB(1,&plhs[0],1,&denseMatrix,"sparse"); // We don't need the dense matrix anymore mxDestroyArray(denseMatrix); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { // Check for proper number of arguments if (nrhs!=6) { mexErrMsgTxt("Six input argument required."); } else if (nlhs>1) { mexErrMsgTxt("Too many output arguments provided."); } // Get access to MATLAB data through C data types double *vertices = mxGetPr(prhs[0]); unsigned num_vertices = mxGetM(prhs[0]); double *edges = mxGetPr(prhs[1]); unsigned num_edges = mxGetM(prhs[1]); double *radii = mxGetPr(prhs[2]); unsigned num_radii_values = mxGetM(prhs[2]); std::string dataset_name(mxArrayToString(prhs[3])); double pixel_to_um = mxGetScalar(prhs[4]); double radii_fudge_factor = mxGetScalar(prhs[5]); if (num_vertices != num_radii_values) { mexErrMsgTxt("Number of radii values provided differs from the number of vertices specified."); } // Create the output variable that will store the edge lengths and radii required for one of the histograms plhs[0] = mxCreateDoubleMatrix(num_edges, 2, mxREAL); double *edge_length_radii = mxGetPr(plhs[0]); // Create and fill a point container vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); for (unsigned vertex=0; vertex<num_vertices; vertex++) { points->InsertNextPoint(acces_2d(vertices, vertex, 0, num_vertices) * pixel_to_um, acces_2d(vertices, vertex, 1, num_vertices) * pixel_to_um, 0); } // Create a polydata object and add the points to it. vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); // Create the array containing edge lengths vtkSmartPointer<vtkDoubleArray> lengths_array = vtkSmartPointer<vtkDoubleArray>::New(); lengths_array->SetNumberOfComponents(1); lengths_array->SetName("EdgeLengths"); // Allocate memory and add the definition of edges to the polydata object polydata->Allocate(); vtkIdType edge_ends[2]; for (unsigned edge_id=0; edge_id<num_edges; edge_id++) { // The definition of edges comes from MATLAB and and the vertices are one-based indexed. Offset them. edge_ends[0] = acces_2d(edges, edge_id, 0, num_edges) - 1; edge_ends[1] = acces_2d(edges, edge_id, 1, num_edges) - 1; polydata->InsertNextCell(VTK_LINE, 2, edge_ends); double edge_length = DistanceTwoVertices(vertices, num_vertices, edge_ends) * pixel_to_um; lengths_array->InsertNextValue(edge_length); acces_2d(edge_length_radii, edge_id, 0, num_edges) = edge_length; acces_2d(edge_length_radii, edge_id, 1, num_edges) = radii_fudge_factor * pixel_to_um * (radii[edge_ends[0]] + radii[edge_ends[1]])/2; } //polydata->GetCellData()->AddArray(lengths_array); // Create and fill the array containing the plexus radii at each vertex. vtkSmartPointer<vtkDoubleArray> radii_array = vtkSmartPointer<vtkDoubleArray>::New(); radii_array->SetNumberOfComponents(1); radii_array->SetName("Radius"); for (unsigned vertex_id=0; vertex_id<num_vertices; vertex_id++) { radii_array->InsertNextValue(radii_fudge_factor * radii[vertex_id] * pixel_to_um); } polydata->GetPointData()->AddArray(radii_array); polydata->GetPointData()->SetActiveScalars("Radius"); WritePolyDataToDisk(polydata, dataset_name + ".vtp"); }