help on python SWIG C++ extension

RLC rogeruclan at gmail.com
Tue Sep 16 12:44:35 CEST 2008


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 long> tmp;
  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 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







More information about the Python-list mailing list