By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,272 Members | 1,420 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,272 IT Pros & Developers. It's quick & easy.

help on python SWIG C++ extension

P: n/a
RLC
Hello

I am new to python SWIG. Recently I wrote a small program trying to
import collada files(using colladadom) into python so I could use
python cgkit to render them. However, during the progressing, I got
some problems. Every time I quit from Python, I get a segmentation
fault, although the main program runs well. I suspect it is because I
wrapped std::vector objects in C struct and I did not release the
memory properly. Below is the code. I am working on FreeBSD 7.0, GCC
4.2.1. I will be very appreciated if you could help me. Thanks a lot.

the error I have got
Segmentation fault: 11 (core dumped)
////////////////////////
///Header file
////////////////////////

#ifndef TDIMPORT_H
#define TDIMPORT_H
#include <string>
#include <vector>
#include "math.h"
#include "float.h"

#define WORDINVALIDVALUE ULONG_MAX
#define FLOATINVALIDVALUE FLT_MAX

typedef unsigned long WORD;

typedef struct
{
double x,y,z;
} Vertex;

extern Vertex *new_Vertex(double x, double y, double z);
extern void delete_Vertex(Vertex *v);
extern double Vertex_length(Vertex *v);

static const Vertex UNDEFINEDVERTEX = {FLT_MAX,FLT_MAX,FLT_MAX};

typedef struct
{
double u,v;
} UV;

extern UV *new_UV(double u, double v);
extern void delete_UV(UV *uv);

static const UV UNDEFINEDUV = {FLT_MAX,FLT_MAX};

typedef struct
{
double red,green,blue,alpha;
} Color;

extern Color *new_Color(double red, double green, double blue, double
alpha);
extern void delete_Color(Color *color);

static const Color BLACK = {0.0, 0.0, 0.0, 1.0};
static const Color WHITE = {1.0, 1.0, 1.0, 1.0};

typedef struct
{
int type;
Color color;
std::string texture;
} Material;

typedef struct
{
std::vector<Vertex vertices;

std::vector<unsigned long polygonNbVertices;

std::vector<unsigned long polygonStartVertexIndex;

std::vector<unsigned long polygonVerticesIndices;

std::vector<UV uvs;

std::vector<unsigned long polygonNbUVs;

std::vector<unsigned long polygonStartUVIndex;

std::vector<unsigned long polygonUVsIndices;

Material material;
} PolygonMesh;

extern PolygonMesh *new_PolygonMesh();
extern void delete_PolygonMesh(PolygonMesh *p);
extern unsigned long PolygonMesh_countvertices(PolygonMesh *p);
extern unsigned long PolygonMesh_countpolygons(PolygonMesh *p);
extern void PolygonMesh_appendvertex(PolygonMesh *p, Vertex *vertex);
extern Vertex PolygonMesh_getvertex(PolygonMesh *p, unsigned long
vertexIndex);
extern void PolygonMesh_appendpolygon(PolygonMesh *p, const
std::vector<unsigned long>& verticesIndices);
extern long PolygonMesh_getpolygonverticescount(PolygonMesh *p,
unsigned long polygonIndex);
extern std::vector<unsigned long>
PolygonMesh_getpolygonverticesindices(PolygonMesh *p, unsigned long
polygonIndex);

#endif
//////////////////////////
//// implementation
//////////////////////////

#include "tdimport.h"

Vertex *new_Vertex(double x, double y, double z)
{
Vertex *v;
v = (Vertex *)malloc(sizeof(Vertex));
v->x = x;
v->y = y;
v->z = z;
return v;
}

void delete_Vertex(Vertex *v)
{
free(v);
}

double Vertex_length(Vertex *v)
{
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}

UV *new_UV(double u, double v)
{
UV *uv;
uv = (UV *)malloc(sizeof(UV));
uv->u = u;
uv->v = v;
return uv;
}

void delete_UV(UV *uv)
{
free(uv);
}

Color *new_Color(double r, double g, double b, double a)
{
Color *color;
color = (Color *)malloc(sizeof(Color));
color->red = r;
color->green = g;
color->blue = b;
color->alpha = a;
return color;
}

void delete_Color(Color *color)
{
free(color);
}

PolygonMesh *new_PolygonMesh()
{
PolygonMesh *p;
p = (PolygonMesh *)malloc(sizeof(PolygonMesh));
p->vertices.clear();
p->polygonNbVertices.clear();
p->polygonStartVertexIndex.clear();
p->polygonVerticesIndices.clear();
p->uvs.clear();
p->polygonNbUVs.clear();
p->polygonStartUVIndex.clear();
p->polygonUVsIndices.clear();
return p;
}

void delete_PolygonMesh(PolygonMesh *p)
{
free(p);
}

unsigned long PolygonMesh_countvertices(PolygonMesh *p)
{
return (unsigned long)p->vertices.size();
}

unsigned long PolygonMesh_countpolygons(PolygonMesh *p)
{
return (unsigned long)p->polygonNbVertices.size();
}

void PolygonMesh_appendvertex(PolygonMesh *p, Vertex *vertex)
{
p->vertices.push_back(*vertex);
}

void PolygonMesh_appendpolygon(PolygonMesh *p, const
std::vector<unsigned long>& verticesIndices)
{
unsigned int i;
for ( i = 0 ; i < verticesIndices.size() ; i++ )
p->polygonVerticesIndices.push_back(verticesIndices. at(i));
p->polygonStartVertexIndex.push_back(p-
>polygonVerticesIndices.size()-verticesIndices.size());
p->polygonNbVertices.push_back(verticesIndices.size( ));
}

Vertex PolygonMesh_getvertex(PolygonMesh *p, unsigned long
vertexIndex)
{
if (vertexIndex < 0 || vertexIndex>=p->vertices.size() )
{
return UNDEFINEDVERTEX;
}
else
{
return p->vertices.at(vertexIndex);
}
}

long PolygonMesh_getpolygonverticescount(PolygonMesh *p, unsigned long
polygonIndex)
{
if ((polygonIndex < 0) || (polygonIndex >= p-
>polygonStartVertexIndex.size()))
{
return (long)-1;
}
else
{
return (long)p->polygonNbVertices.at(polygonIndex);
}
}

std::vector<unsigned long>
PolygonMesh_getpolygonverticesindices(PolygonMesh *p, unsigned long
polygonIndex)
{
std::vector<unsigned longtmp;
tmp.clear();
if ((polygonIndex < 0) || (polygonIndex >= p-
>polygonStartVertexIndex.size()))
{
return tmp;
}
else
{
unsigned long count = p->polygonNbVertices.at(polygonIndex);
unsigned long start = p->polygonStartVertexIndex.at(polygonIndex);
for (unsigned long i=0; i<count; i++)
tmp.push_back(p->polygonVerticesIndices.at(i+start));
return tmp;
}
}

/////////////////////////
////SWIG interface
/////////////////////////
%module tdimport
%{
#include "tdimport.h"
%}
%include "std_string.i"
%include "std_vector.i"

namespace std {
%template(IntVector) vector<int>;
%template(UIVector) vector<unsigned long>;
%template(VertexVector) vector<Vertex>;
%template(UVVector) vector<UV>;
}

using namespace std;

typedef struct
{
double x,y,z;
%extend
{
Vertex (double,double,double);
~Vertex();
double length();
}
} Vertex;

typedef struct
{
double u,v;
%extend
{
UV (double,double);
~UV();
}
} UV;

typedef struct
{
double red,green,blue,alpha;
%extend
{
Color (double,double,double,double);
~Color();
}
} Color;

%apply const std::string& {std::string* texture};

typedef struct
{
int type;
Color color;
std::string texture;
} Material;

typedef struct
{

std::vector<Vertex vertices;

std::vector<unsigned long polygonNbVertices;

std::vector<unsigned long polygonStartVertexIndex;

std::vector<unsigned long polygonVerticesIndices;

std::vector<UV uvs;

std::vector<unsigned long polygonNbUVs;

std::vector<unsigned long polygonStartUVIndex;

std::vector<unsigned long polygonUVsIndices;

Material material;

%extend
{
PolygonMesh();
~PolygonMesh();
unsigned long countvertices();
unsigned long countpolygons();
void appendvertex(Vertex*);
Vertex getvertex (unsigned long) ;
void appendpolygon(const std::vector<unsigned long>&);
long getpolygonverticescount(unsigned long);
std::vector<unsigned longgetpolygonverticesindices(unsigned
long);
}
} PolygonMesh;
/////////////////////////
////python file
/////////////////////////
#!/usr/local/bin/python

import tdimport

a = tdimport.PolygonMesh()

a.appendvertex(tdimport.Vertex(1.0,0.0,0.0))
a.appendvertex(tdimport.Vertex(1.0,1.0,0.0))
a.appendvertex(tdimport.Vertex(1.0,1.0,1.0))

a.appendpolygon([1,2,3])

b = a.getpolygonverticescount(0)

print b

del a

////////////////////////////
///compile command
////////////////////////////
swig -c++ -python tdimport.i
g++ -c tdimport.cpp
g++ -c tdimport_wrap.cxx -I/usr/local/include/python2.5
g++ -shared tdimport.o tdimport_wrap.o -o _tdimport.so


Sep 16 '08 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.