help on python SWIG C++ extension

R

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 said:
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 long> tmp;
tmp.clear();
if ((polygonIndex said:
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 long> getpolygonverticesindices(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
 
D

Diez B. Roggisch

RLC said:
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)

Try starting the program in gdb. This works using


$ gdb python
(gdb) set args myscript.py
(gdb) run

Then when the segfault hits, get a backtrace to see where the actual
problem occurs.

Diez
 
T

Tim Roberts

RLC said:
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.

That won't cause a segmentation fault. However, I notice that you are
using "malloc" and "free" to allocate and free your objects. "stl" will
use "new" and "delete", and it's not always healthy to mix them. If I were
you, I'd replace this:
Vertex *v;
v = (Vertex *)malloc(sizeof(Vertex));

with this, which is less typing:
Vertex * x = new Vertex;
 
R

RLC

Thanks a lot, Tim and Diez, Merci Beaucoup!!

I strongly suspect the error was caused by the memory operation. I
made some modifications only on PolygonMesh definition. And now I have
no annoying warnings.
PolygonMesh *new_PolygonMesh()
{
PolygonMesh *p = new PolygonMesh;
// 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);
}

when I run below script, it works well without any warning


#!/usr/local/bin/python

import tdimport

a = tdimport.PolygonMesh()

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

a.appendpolygon([0,3,2,1])
a.appendpolygon([0,1,5,4])
a.appendpolygon([1,2,6,5])
a.appendpolygon([2,3,7,6])
a.appendpolygon([0,4,7,3])
a.appendpolygon([4,5,6,7])

print a.getpolygonverticesindices(0)
print a.getpolygonverticesindices(1)
print a.getpolygonverticesindices(2)
print a.getpolygonverticesindices(3)
print a.getpolygonverticesindices(4)
print a.getpolygonverticesindices(5)

del a


Thanks again. Have a good day!!!

Regards
Roger
 
Joined
Oct 2, 2008
Messages
1
Reaction score
0
Hi RLC,

have you done anything more with your collada + cgkit?

I'm interested in using this too, so I'm interested in seeing any other work you've done on it. Do you have a project page somewhere? Like on google code or something?


cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top