[vtkusers] Using VTK through mex (MATLAB) on 64 bit Mac OSX 10.7

Kevlon aquino.km at gmail.com
Wed Jul 11 20:47:48 EDT 2012


Hi All,

I am having trouble with a mex file that uses VTK, I seem to be pointing to
invalid memory when i am using vtkSmoothPolyDataFilter. This code works on
other operating systems including a 64bit build on ubuntu, and OSX 10.5
(32bit).

I have placed the code at the end of this post. By debugging this code, I
find that the error happens in the method Smooth, specifically when i apply
the smoothing filter i.e. in the line:

		pSmooth->Update();

Do I have to invoke anything new in either the installation of VTK or in the
declaration of variables in this code to make this program work?

Any help or directions would be appreciated

extra information:
- VTK works on my system, at least i have tested some example codes
- I am running VTK 5.4
- Im running MAC OSX 10.7.4
- I have compiled this mex code by linking the following libraries

vtkRendering 
vtkGraphics 
vtkImaging 
vtkFiltering 
vtkCommon 
vtksys 


\\ --- Code: newSmooth.cpp ----- 

#include "mex.h"
#include "matrix.h"

#pragma comment(linker, "/NODEFAULTLIB:msvcrt.lib")

#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "user32.lib")

#pragma comment(lib,"VTK_Libs/vtkCommon.lib")
#pragma comment(lib,"VTK_Libs/vtkFiltering.lib")
#pragma comment(lib,"VTK_Libs/vtkGraphics.lib")

#include "vtkMarchingCubes.h"
#include "vtkStructuredPoints.h"
#include "vtkUnsignedCharArray.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkCellArray.h"
#include "vtkDoubleArray.h"
#include "vtkDataSetAttributes.h"
#include "vtkPolyDataNormals.h"
#include "vtkSmoothPolyDataFilter.h"

#define ASSERT(a) {if(!(a)) {int q=1,b=0,c=q/b;}}
#include "helpers.cpp"
#include "doublearray.cpp"
#include "color.h"
#include "vector.h"



Vertex* CreateVerticesFromMxArray(mxArray* mxVertices, mxArray* mxColors,
mxArray* mxNormals)
{

	if (mxGetM(mxVertices) != 3)
		mexErrMsgTxt("The field vertices must have 3 rows");

	int nVertices = mxGetN(mxVertices);
	Vertex* pVertices = new Vertex[nVertices];

	double* pV = mxGetPr(mxVertices);

	for (int iV = 0; iV<nVertices; iV++) {
		pVertices[iV].vCoord.x = pV[0];
		pVertices[iV].vCoord.y = pV[1];
		pVertices[iV].vCoord.z = pV[2];
		pV += 3;
	}


	if (mxNormals) {

		if ((mxGetM(mxNormals) != 3) || (mxGetN(mxNormals) != nVertices))
			mexErrMsgTxt(&quot;The dimensions of the fields vertices and normals must
be the same&quot;);

		double *pN = mxGetPr(mxNormals);
		for (int iV = 0; iV &lt; nVertices; iV++)
		{
			pVertices[iV].vNormal.x = pN[0];
			pVertices[iV].vNormal.y = pN[1];
			pVertices[iV].vNormal.z = pN[2];
			pN += 3;
		}

	}
	else {
		for (int iV = 0; iV &lt; nVertices; iV++)
		{
			pVertices[iV].vNormal.x = 0;
			pVertices[iV].vNormal.y = 0;
			pVertices[iV].vNormal.z = 0;
		}
	}

	return pVertices;

}

Triangle* CreateTrianglesFromMxArray(mxArray* mxTriangles)
{

	if (mxGetM(mxTriangles) != 3)
		mexErrMsgTxt(&quot;The field triangles must have 3 rows&quot;);

	int nTriangles = mxGetN(mxTriangles);
	Triangle* pTriangles = new Triangle[nTriangles];

	double* pT = mxGetPr(mxTriangles);

	for (int iT = 0; iT&lt;nTriangles; iT++) {
		pTriangles[iT].v[0] = (int) pT[0];
		pTriangles[iT].v[1] = (int) pT[1];
		pTriangles[iT].v[2] = (int) pT[2];
		pT += 3;
	}

	return pTriangles;

}

vtkPolyData* BuildVtkPolyDataTriangles(int nVertices, int nTriangles, Vertex
*pVertices, Triangle *pTriangles)
{
	vtkPolyData		*pPD		= NULL;
	vtkPoints		*pPoints	= NULL;
	vtkCellArray	*pPolys		= NULL;
	vtkDoubleArray	*pNormals	= NULL;
	vtkUnsignedCharArray	*pColors = NULL;

	pPD			= vtkPolyData::New();
	pPoints		= vtkPoints::New();
	pPolys		= vtkCellArray::New();
	pNormals	= vtkDoubleArray::New();
	pColors		= vtkUnsignedCharArray::New();

	pPoints->SetDataType(VTK_DOUBLE);
	pPoints->SetNumberOfPoints(nVertices);
	
	pNormals->SetNumberOfComponents(3);
	pNormals->SetNumberOfTuples(nVertices);
	pNormals->Allocate(3*nVertices);

	pColors->SetNumberOfComponents(3);
	pColors->SetNumberOfTuples(nVertices);
	pColors->Allocate(3*nVertices);

	pPolys->EstimateSize(nTriangles, 3);

	for (int iV = 0; iV < nVertices; iV++)
	{
		pPoints->SetPoint(iV, pVertices[iV].vCoord);
		pNormals->SetTuple(iV, pVertices[iV].vNormal);

		for (int iC=0; iC<3; iC++)
			pColors->InsertComponent(iV, iC, pVertices[iV].cColor[iC]);
	}
	for (int iT = 0; iT < nTriangles; iT++)
	{
		//pPolys->InsertNextCell(3, pTriangles[iT].v);
        pPolys->InsertNextCell((vtkIdType) 3, (vtkIdType*)
pTriangles[iT].v);        
	}
	
	pPD->SetPoints(pPoints);
	pPD->GetPointData()->SetNormals(pNormals);
	pPD->GetPointData()->SetScalars(pColors);
	pPD->SetPolys(pPolys);

	return pPD;
}


bool Smooth(vtkPolyData* &pPD)
{      
		vtkSmoothPolyDataFilter	*pSmooth = vtkSmoothPolyDataFilter::New();
		if (!pSmooth)
			return false;        

		vtkPolyData	*pOut = vtkPolyData::New();
		if (!pOut){
			pSmooth->Delete();
			return false;
		}
        
        
    
        int smooth_iterations = 20;
        double smooth_relaxation = 0.1;
        double smooth_feature_angle = 45;
        double smooth_edge_angle = 15;
        bool smooth_boundary = true;
        bool smooth_feature_angle_smoothing = false;

         
		pSmooth->SetNumberOfIterations(smooth_iterations);
		pSmooth->SetRelaxationFactor(smooth_relaxation);
		pSmooth->SetFeatureAngle(smooth_feature_angle);
		pSmooth->SetEdgeAngle(smooth_edge_angle);
		pSmooth->SetBoundarySmoothing(smooth_boundary);
		pSmooth->SetFeatureEdgeSmoothing(smooth_feature_angle_smoothing);

        
		pSmooth->SetInput(pPD);
        
		pSmooth->Update();
        
		pOut->ShallowCopy(pSmooth->GetOutput());
        
		pSmooth->Delete();
       
		pPD->Delete();       
		pPD = pOut;
        
	
	return true;
}



void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  
    // Parsing arguments
    if (nrhs < 1) 
		mexErrMsgTxt("This function should take at least one argument");

    if (!mxIsStruct(prhs[0])) 
		mexErrMsgTxt("The first argument should be a structure");

	mxArray* mxVertices = mxGetField(prhs[0], 0, "vertices");
	if (!mxVertices)
		mexErrMsgTxt("The first argument should have a field named vertices");

	mxArray* mxTriangles = mxGetField(prhs[0], 0, "triangles");
	if (!mxTriangles)
		mexErrMsgTxt("The first argument should have a field named triangles");

	mxArray* mxColors = mxGetField(prhs[0], 0, "colors");
	mxArray* mxNormals = mxGetField(prhs[0], 0, "normals");
	
	Vertex* pVertices = CreateVerticesFromMxArray(mxVertices, mxColors,
mxNormals); 
	int nVertices = mxGetN(mxVertices);

	Triangle* pTriangles = CreateTrianglesFromMxArray(mxTriangles);
	int nTriangles = mxGetN(mxTriangles);
	
	vtkPolyData *pVTKMesh = BuildVtkPolyDataTriangles(nVertices, nTriangles,
pVertices, pTriangles);
    
    if(!Smooth(pVTKMesh))
        mexErrMsgTxt("Error when smoothing the mesh");


    
        
    const char *fields[] = {"triangles","normals",
                                    "vertices","colors"};
    
    plhs[0] = mxCreateStructMatrix(1, 1, 4, fields);    

}


--
View this message in context: http://vtk.1045678.n5.nabble.com/Using-VTK-through-mex-MATLAB-on-64-bit-Mac-OSX-10-7-tp5714652.html
Sent from the VTK - Users mailing list archive at Nabble.com.



More information about the vtkusers mailing list