I am trying to build python wrapper for a function implemented in C++ that accepts 2d vector and returns 2d vector. I am trying to adapt the code from this to suit my needs.
Input matrix shape: (n*2)
Output matrix shape: (n*2)
I think there is an issue with code.i file but not really sure what exactly is the issue.
If there are any other libraries which can achieve this that works as well. I just need to call the c++ function from python.
Here is complete reproducible example: Google Colab
My files:
code.cpp:
#include <vector>
#include "geomutils.h"
#include "code.h"
using namespace std;
vector< vector<double> > computeConvexHull(vector< vector<double> > i_matrix){
Polygon custompts, customhull;
for (int r = 0; r < i_matrix.size(); r++){
custompts.push_back(Point(i_matrix[r][0], i_matrix[r][1]));
}
computeConvexHull(custompts, customhull);
vector< vector<double> > res;
for(int i = 0;i < customhull.size();i ++) {
res[i][0] = customhull[i].x;
res[i][1] = customhull[i].y;
}
return res;
}
geomutils.cpp:
#include "geomutils.h"
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
void computeConvexHull(Polygon &pts, Polygon &chull) {
chull.clear();
if(pts.size() == 1) {
chull.push_back(pts[0]);
chull.push_back(pts[0]);
return;
} else if(pts.size() == 2) {
chull.push_back(pts[0]);
chull.push_back(pts[1]);
chull.push_back(pts[0]);
return;
}
typedef boost::tuple<double, double> point;
typedef boost::geometry::model::multi_point<point> mpoints;
typedef boost::geometry::model::polygon<point> polygon;
mpoints mpts;
for(int i = 0;i < pts.size();i ++) {
boost::geometry::append(mpts,point(pts[i].x,pts[i].y));
}
polygon hull;
// Polygon is closed
boost::geometry::convex_hull(mpts, hull);
for(auto pt : hull.outer()) {
chull.push_back(Point(pt.get<0>(), pt.get<1>()));
}
}
geomutils.h:
#ifndef GEOMUTILS_H
#define GEOMUTILS_H
#include <vector>
struct Point {
double x,y;
Point(){}
Point(double x, double y):x(x),y(y){}
};
typedef std::vector<Point> Polygon;
void computeConvexHull(Polygon &pts, Polygon &chull);
#endif // GEOMUTILS_H
code.i:
%module code
%{
#include "code.h"
#include "geomutils.h"
%}
%include "std_vector.i"
namespace std {
/* On a side note, the names VecDouble and VecVecdouble can be changed, but the order of first the inner vector matters! */
%template(VecDouble) vector< vector<double> >;
%template(VecVecdouble) vector< vector<double> >;
}
%include "code.h"
The code uses one external library called boost. The way I am trying to generate the wrapper is as follows:
g++ -c -fPIC code.cpp geomutils.cpp
swig -c++ -python code.i
g++ -c -fPIC code_wrap.cxx -I/usr/include/python3.7 -I/usr/lib/python3.7
The first two commands run without giving any error but the third code gives me an error.
The Error is too long to post in the question. But the error can be reproduced using code link.
Update 1:
After trying the changes suggested in answer 1 and running the following commands the code compiles but nothing happens when I try to run the c++ code from python. The code is updated in the same link. "test.py" is a simple python code that calls the computeConvexHull
function.
Commands:
g++ -c -fPIC code.cpp geomutils.cpp
swig -c++ -python code.i
g++ -c -fPIC code_wrap.cxx -I/usr/include/python3.7 -I/usr/lib/python3.7
g++ -shared -Wl,-soname,_code.so -o _code.so code.o geomutils.o code_wrap.o
python test.py