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 WORDINVALIDVALU E ULONG_MAX
#define FLOATINVALIDVAL UE FLT_MAX
typedef unsigned long WORD;
typedef struct
{
double x,y,z;
} Vertex;
extern Vertex *new_Vertex(dou ble x, double y, double z);
extern void delete_Vertex(V ertex *v);
extern double Vertex_length(V ertex *v);
static const Vertex UNDEFINEDVERTEX = {FLT_MAX,FLT_MA X,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_MA X};
typedef struct
{
double red,green,blue, alpha;
} Color;
extern Color *new_Color(doub le red, double green, double blue, double
alpha);
extern void delete_Color(Co lor *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<Ver tex vertices;
std::vector<uns igned long polygonNbVertic es;
std::vector<uns igned long polygonStartVer texIndex;
std::vector<uns igned long polygonVertices Indices;
std::vector<UV uvs;
std::vector<uns igned long polygonNbUVs;
std::vector<uns igned long polygonStartUVI ndex;
std::vector<uns igned long polygonUVsIndic es;
Material material;
} PolygonMesh;
extern PolygonMesh *new_PolygonMes h();
extern void delete_PolygonM esh(PolygonMesh *p);
extern unsigned long PolygonMesh_cou ntvertices(Poly gonMesh *p);
extern unsigned long PolygonMesh_cou ntpolygons(Poly gonMesh *p);
extern void PolygonMesh_app endvertex(Polyg onMesh *p, Vertex *vertex);
extern Vertex PolygonMesh_get vertex(PolygonM esh *p, unsigned long
vertexIndex);
extern void PolygonMesh_app endpolygon(Poly gonMesh *p, const
std::vector<uns igned long>& verticesIndices );
extern long PolygonMesh_get polygonvertices count(PolygonMe sh *p,
unsigned long polygonIndex);
extern std::vector<uns igned long>
PolygonMesh_get polygonvertices indices(Polygon Mesh *p, unsigned long
polygonIndex);
#endif
//////////////////////////
//// implementation
//////////////////////////
#include "tdimport.h "
Vertex *new_Vertex(dou ble 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(V ertex *v)
{
free(v);
}
double Vertex_length(V ertex *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(doub le 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(Co lor *color)
{
free(color);
}
PolygonMesh *new_PolygonMes h()
{
PolygonMesh *p;
p = (PolygonMesh *)malloc(sizeof (PolygonMesh));
p->vertices.clear ();
p->polygonNbVerti ces.clear();
p->polygonStartVe rtexIndex.clear ();
p->polygonVertice sIndices.clear( );
p->uvs.clear();
p->polygonNbUVs.c lear();
p->polygonStartUV Index.clear();
p->polygonUVsIndi ces.clear();
return p;
}
void delete_PolygonM esh(PolygonMesh *p)
{
free(p);
}
unsigned long PolygonMesh_cou ntvertices(Poly gonMesh *p)
{
return (unsigned long)p->vertices.size( );
}
unsigned long PolygonMesh_cou ntpolygons(Poly gonMesh *p)
{
return (unsigned long)p->polygonNbVerti ces.size();
}
void PolygonMesh_app endvertex(Polyg onMesh *p, Vertex *vertex)
{
p->vertices.push_ back(*vertex);
}
void PolygonMesh_app endpolygon(Poly gonMesh *p, const
std::vector<uns igned long>& verticesIndices )
{
unsigned int i;
for ( i = 0 ; i < verticesIndices .size() ; i++ )
p->polygonVertice sIndices.push_b ack(verticesInd ices.at(i));
p->polygonStartVe rtexIndex.push_ back(p-
>polygonVertice sIndices.size()-verticesIndices .size());p->polygonNbVerti ces.push_back(v erticesIndices. size());
}
Vertex PolygonMesh_get vertex(PolygonM esh *p, unsigned long
vertexIndex)
{
if (vertexIndex < 0 || vertexIndex>=p->vertices.size( ) )
{
return UNDEFINEDVERTEX ;
}
else
{
return p->vertices.at(ve rtexIndex);
}
}
long PolygonMesh_get polygonvertices count(PolygonMe sh *p, unsigned long
polygonIndex)
{
if ((polygonIndex < 0) || (polygonIndex >= p-
>polygonStartVe rtexIndex.size( ))){
return (long)-1;
}
else
{
return (long)p->polygonNbVerti ces.at(polygonI ndex);
}
}
std::vector<uns igned long>
PolygonMesh_get polygonvertices indices(Polygon Mesh *p, unsigned long
polygonIndex)
{
std::vector<uns igned longtmp;
tmp.clear();
if ((polygonIndex < 0) || (polygonIndex >= p-
>polygonStartVe rtexIndex.size( ))){
return tmp;
}
else
{
unsigned long count = p->polygonNbVerti ces.at(polygonI ndex);
unsigned long start = p->polygonStartVe rtexIndex.at(po lygonIndex);
for (unsigned long i=0; i<count; i++)
tmp.push_back(p->polygonVertice sIndices.at(i+s tart));
return tmp;
}
}
/////////////////////////
////SWIG interface
/////////////////////////
%module tdimport
%{
#include "tdimport.h "
%}
%include "std_string .i"
%include "std_vector .i"
namespace std {
%template(IntVe ctor) vector<int>;
%template(UIVec tor) vector<unsigned long>;
%template(Verte xVector) vector<Vertex>;
%template(UVVec tor) 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<Ver tex vertices;
std::vector<uns igned long polygonNbVertic es;
std::vector<uns igned long polygonStartVer texIndex;
std::vector<uns igned long polygonVertices Indices;
std::vector<UV uvs;
std::vector<uns igned long polygonNbUVs;
std::vector<uns igned long polygonStartUVI ndex;
std::vector<uns igned long polygonUVsIndic es;
Material material;
%extend
{
PolygonMesh();
~PolygonMesh();
unsigned long countvertices() ;
unsigned long countpolygons() ;
void appendvertex(Ve rtex*);
Vertex getvertex (unsigned long) ;
void appendpolygon(c onst std::vector<uns igned long>&);
long getpolygonverti cescount(unsign ed long);
std::vector<uns igned longgetpolygonv erticesindices( unsigned
long);
}
} PolygonMesh;
/////////////////////////
////python file
/////////////////////////
#!/usr/local/bin/python
import tdimport
a = tdimport.Polygo nMesh()
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.getpolygonver ticescount(0)
print b
del a
////////////////////////////
///compile command
////////////////////////////
swig -c++ -python tdimport.i
g++ -c tdimport.cpp
g++ -c tdimport_wrap.c xx -I/usr/local/include/python2.5
g++ -shared tdimport.o tdimport_wrap.o -o _tdimport.so