Skip to content
Snippets Groups Projects
Commit ac219c32 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

first version of the c api

parent f380a68b
No related branches found
No related tags found
No related merge requests found
class arg : class arg:
def __init__(self, name, value=None) : def __init__(self, name, value=None):
self.name = name self.name = name
self.value = value self.value = value
@property @property
def cpp_value(self) : def cpp_value(self):
if self.value is None : if self.value is None:
return "" return ""
return " = "+self.value return " = "+self.value
@property @property
def cpp(self) : def cpp(self):
n = self.type_cpp n = self.type_cpp
if n[-1] != "&" : if n[-1] != "&":
n += " " n += " "
n += self.name n += self.name
n += self.cpp_value n += self.cpp_value
return n return n
@property @property
def c(self): def c_cpp_arg(self):
return "" return self.name
class simplearg(arg) :
def __init__(self,cpptype,ctype,out,name,value):
self.type_cpp = cpptype
self.type_c = ctype
arg.__init__(self,name,value)
@property @property
def c_cpp_pre(self):
return ""
@property
def c_cpp_post(self):
return ""
@property
def c(self): def c(self):
return self.type_c + " " + self.name return self.type_c + " " + self.name
class vectorarg(arg) : class simplearg(arg):
def __init__(self,cpptype,ctype,out,name,value): def __init__(self,cpptype,ctype,out,name,value):
self.type_cpp = cpptype self.type_cpp = cpptype
self.type_c = ctype self.type_c = ctype
vectorarg.__init__(self,name,value) arg.__init__(self,name,value)
class iint(simplearg): class iint(simplearg):
def __init__(self,name,value=None): def __init__(self,name,value=None):
simplearg.__init__(self,"const int","const int",False,name,value) simplearg.__init__(self,"const int","const int",False,name,value)
class oint(simplearg): class oint(simplearg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
simplearg.__init__(self,"int &","int *",True,name,value) simplearg.__init__(self,"int &","int*",True,name,value)
rtype_cpp = "int"
rtype_c = "int"
@property
def c_cpp_arg(self):
return "*"+self.name
class istring(simplearg) : class istring(simplearg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
simplearg.__init__(self,"const std::string &", "const char*",False,name,value) simplearg.__init__(self,"const std::string &", "const char*",False,name,value)
@property @property
def cpp_value(self) : def cpp_value(self):
if self.value is None : if self.value is None:
return "" return ""
return " = \""+self.value+"\"" return " = \""+self.value+"\""
class ostring(simplearg) : class ostring(simplearg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
simplearg.__init__(self,"std::string &","char**",True,name,value) simplearg.__init__(self,"std::string &","char**",True,name,value)
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " std::string "+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " *"+self.name+" = strdup("+self.c_cpp_arg+".c_str());\n"
class idouble(simplearg) : class idouble(simplearg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
simplearg.__init__(self,"const double","const double",False,name,value) simplearg.__init__(self,"const double","const double",False,name,value)
class odouble(simplearg) : class odouble(simplearg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
simplearg.__init__(self,"double &","double *",True,name,value) simplearg.__init__(self,"double &","double*",True,name,value)
@property
def c_cpp_arg(self):
return "*"+self.name
class ovectorpair(arg) : class ovectorpair(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "vector_pair &" type_cpp = "vector_pair &"
type_c = "int**"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " vector_pair "+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " pairvector2intptr("+self.c_cpp_arg+", " + self.name + ", "+self.name+"Size);\n"
@property
def c (self):
return "int** "+self.name+", size_t* "+self.name+"Size"
class ivectorpair(arg) : class ivectorpair(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "const vector_pair &" type_cpp = "const vector_pair &"
type_c = "const int*"
@property
def c_cpp_arg(self):
return "intptr2pairvector("+self.name+","+self.name+"Size)"
@property
def c (self):
return "int* "+self.name+", size_t "+self.name+"Size"
class ibool(arg) :
def __init__(self,name,value=None) : class ibool(arg):
def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "const bool" type_cpp = "const bool"
type_c = "const int"
class obool(arg) : class obool(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "bool &" type_cpp = "bool &"
type_c = "int*"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " bool "+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " *"+self.name+" = (int)"+self.c_cpp_arg+";\n"
class ivectorint(arg) : class ivectorint(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "const std::vector<int> &" type_cpp = "const std::vector<int> &"
type_c = "const int*"
@property
def c_cpp_arg(self):
return "ptr2vector("+self.name+", "+self.name+"Size)"
@property
def c (self):
return "int* "+self.name+", size_t "+self.name+"Size"
class ovectorint(arg) : class ovectorint(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "std::vector<int> &" type_cpp = "std::vector<int> &"
type_c = "int**"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " std::vector<int> "+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " vector2ptr("+self.c_cpp_arg+", " + self.name + ", "+self.name+"Size);\n"
@property
def c (self):
return "int** "+self.name+", size_t* "+self.name+"Size"
class ovectorvectorint(arg) : class ovectorvectorint(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "std::vector<std::vector<int> > &" type_cpp = "std::vector<std::vector<int> > &"
type_c = "int**"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " std::vector<std::vector<int> >"+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " vectorvector2ptrptr("+self.c_cpp_arg+", " + self.name + ", "+self.name+"Size, "+self.name+"SizeSize);\n"
@property
def c (self):
return "int*** "+self.name+", size_t** "+self.name+"Size"+", size_t *"+self.name+"SizeSize"
class ovectorvectorpair(arg) : class ovectorvectorpair(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "std::vector<vector_pair> &" type_cpp = "std::vector<vector_pair> &"
type_c = "int**"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " std::vector<vector_pair >"+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " pairvectorvector2intptrptr("+self.c_cpp_arg+", " + self.name + ", "+self.name+"Size, "+self.name+"SizeSize);\n"
@property
def c (self):
return "int*** "+self.name+", size_t** "+self.name+"Size"+", size_t *"+self.name+"SizeSize"
class ivectordouble(arg) : class ivectordouble(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "const std::vector<double> &" type_cpp = "const std::vector<double> &"
type_c = "double**"
@property
def c_cpp_arg(self):
return "ptr2vector("+self.name+", "+self.name+"Size)"
@property
def c (self):
return "double* "+self.name+", size_t "+self.name+"Size"
class ovectordouble(arg) : class ovectordouble(arg):
def __init__(self,name,value=None) : def __init__(self,name,value=None):
arg.__init__(self,name,value) arg.__init__(self,name,value)
type_cpp = "std::vector<double> &" type_cpp = "std::vector<double> &"
type_c = "double*"
@property
def c_cpp_arg(self):
return "api_"+self.name+"_"
@property
def c_cpp_pre(self):
return " std::vector<double> "+self.c_cpp_arg +";\n"
@property
def c_cpp_post(self):
return " vector2ptr("+self.c_cpp_arg+", " + self.name + ", "+self.name+"Size);\n"
@property
def c (self):
return "double** "+self.name+", size_t* "+self.name+"Size"
class Module:
class Module : def __init__(self, name):
def __init__(self, name) :
self.name = name self.name = name
self.fs = [] self.fs = []
def add(self,name, *args) : def add(self,rtype, name, *args):
self.fs.append((name,args)) self.fs.append((rtype,name,args))
cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle
// //
...@@ -138,7 +253,7 @@ cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle ...@@ -138,7 +253,7 @@ cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle
// This is the embryo of what will become the Gmsh API. // This is the embryo of what will become the Gmsh API.
// //
// Don't use it yet, it's not ready :-) We plan to release a first version in // Don't use it yet, it's not ready:-) We plan to release a first version in
// Gmsh 3.1, and something more complete in Gmsh 4.0. // Gmsh 3.1, and something more complete in Gmsh 4.0.
// //
// Your input is welcome: please contribute your ideas on // Your input is welcome: please contribute your ideas on
...@@ -156,12 +271,14 @@ cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle ...@@ -156,12 +271,14 @@ cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle
#include <string> #include <string>
#if defined(WIN32) #if defined(WIN32)
#define GMSH_API __declspec(dllexport) std::vector<int> #define GMSH_API __declspec(dllexport)
#else #else
#define GMSH_API std::vector<int> #define GMSH_API
#endif #endif
typedef std::vector<std::pair<int, int> > vector_pair; typedef std::vector<std::pair<int, int> > vector_pair;
GMSH_API void gmshInitialize(int argc, char **argv);
""" """
cpp_footer=""" cpp_footer="""
...@@ -170,15 +287,113 @@ cpp_footer=""" ...@@ -170,15 +287,113 @@ cpp_footer="""
#endif #endif
""" """
c_header=""" c_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to the public mailing list <gmsh@onelab.info>.
#ifndef _GMSHC_H_
#define _GMSHC_H_
// This is the embryo of what will become the Gmsh API.
//
// Don't use it yet, it's not ready:-) We plan to release a first version in
// Gmsh 3.1, and something more complete in Gmsh 4.0.
//
// Your input is welcome: please contribute your ideas on
// https://gitlab.onelab.info/gmsh/gmsh/issues/188
//
// By design, the API is purely functional, and only uses elementary C++ types
// from the standard library. This design should not and will not change.
// All functions return 0 as the first entry of the returned vector on
// successful completion. Additional integer results can be appends to this
// returned value, depending on context.
#if defined(WIN32)
#define GMSH_API __declspec(dllexport)
#else
#define GMSH_API
#endif
#include <stdlib.h>
GMSH_API void gmshcInitialize(char argc, char **argv);
""" """
c_footer=""" c_footer="""
#undef GMSH_API
#endif
"""
c_cpp_header="""// Gmsh - Copyright (C) 1997-2017 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to the public mailing list <gmsh@onelab.info>.
extern \"C\" {
#include "gmshc.h"
}
#include "gmsh.h"
#include <cstring>
template<typename t>
std::vector<t> ptr2vector(const t *p, size_t size) {
return std::vector<t>(p,p+size);
}
template<typename t>
void vector2ptr(const std::vector<t>&v, t **p, size_t *size) {
*p = (t*)malloc(sizeof(t)*(v.size()));
for (size_t i = 0; i < v.size(); ++i){
(*p)[i] = v[i];
}
*size = v.size();
}
void pairvector2intptr(const vector_pair &v, int **p, size_t *size) {
*p = (int*)malloc(sizeof(int)*(v.size()*2));
for (size_t i = 0; i < v.size(); ++i){
(*p)[i*2+0] = v[i].first;
(*p)[i*2+1] = v[i].second;
}
*size = v.size()*2;
}
vector_pair intptr2pairvector(const int *p, size_t size){
vector_pair v(size);
for (size_t i = 0; i < size; ++i) {
v[i].first = p[i*2+0];
v[i].second = p[i*2+1];
}
return v;
}
template<typename t>
void vectorvector2ptrptr(const std::vector<std::vector<t> > &v, t ***p, size_t **size, size_t *sizeSize) {
*p = (t**)malloc(sizeof(t*)*v.size());
*size = (size_t*)malloc(sizeof(size_t)*v.size());
for (size_t i = 0; i < v.size(); ++i)
vector2ptr(v[i], &((*p)[i]), &((*size)[i]));
*sizeSize = v.size();
}
int** pairvectorvector2intptrptr(const std::vector<vector_pair > &v, int ***p, size_t **size, size_t *sizeSize) {
*p = (int**)malloc(sizeof(int*)*v.size());
for (size_t i = 0; i < v.size(); ++i)
pairvector2intptr(v[i],p[i],size[i]);
*sizeSize = v.size();
}
void gmshcInitialize(char argc, char **argv){
gmshInitialize(argc, argv);
}
""" """
class API : class API:
def __init__(self) : def __init__(self):
self.modules = [] self.modules = []
def add_module(self, name): def add_module(self, name):
...@@ -187,23 +402,52 @@ class API : ...@@ -187,23 +402,52 @@ class API :
return module return module
def write_cpp(self, filename): def write_cpp(self, filename):
with open(filename+".h","w") as f : with open(filename+".h","w") as f:
f.write(cpp_header) f.write(cpp_header)
for module in self.modules : for module in self.modules:
f.write("\n") f.write("\n")
f.write("// gmsh"+module.name+"\n") f.write("// gmsh"+module.name+"\n")
for name, args in module.fs : for rtype, name, args in module.fs:
f.write("GMSH_API gmsh" + module.name+name+"("+", ".join( rt = rtype.rtype_cpp if rtype else "void"
f.write("GMSH_API " + rt + " gmsh" + module.name+name+"("+", ".join(
list((a.cpp for a in args)))+");\n") list((a.cpp for a in args)))+");\n")
f.write(cpp_footer) f.write(cpp_footer)
def write_c(self,filename) : def write_c(self,filename):
with open(filename+".h","w") as f : with open(filename+".h","w") as f:
f.write(c_header) f.write(c_header)
for module in self.modules : for module in self.modules:
f.write("\n") f.write("\n")
f.write("// gmsh"+module.name+"\n") f.write("/* gmsh"+module.name+" */\n")
for name, args in module.fs : for rtype, name, args in module.fs:
f.write("GMSH_API gmsh" + module.name+name+"("+", ".join( f.write("GMSH_API int gmshc" + module.name+name+"("+", ".join(
list((a.c for a in args)))+");\n") list((a.c for a in args))) +
((", "+rtype.rtype_c + " *result") if rtype else "") +
");\n")
f.write(c_footer) f.write(c_footer)
with open(filename+".cc","w") as f:
f.write(c_cpp_header)
for module in self.modules:
f.write("\n")
f.write("/* gmsh"+module.name+" */\n")
for rtype, name, args in module.fs:
#rt = rtype.rtype_c if rtype else "void"
f.write("int gmshc" + module.name+name+"("+", ".join(
list((a.c for a in args)))+
((", "+rtype.rtype_c + " *result") if rtype else "") +
"){\n"
)
f.write(" try {\n");
f.write("".join((a.c_cpp_pre for a in args)))
if rtype:
f.write(rtype.rtype_c + " result_api_ = ")
f.write(" gmsh" + module.name+name+"("+", ".join(
list((a.c_cpp_arg for a in args)))+
");\n")
if rtype:
f.write("if(result) *result = result_api_;\n")
f.write("".join((a.c_cpp_post for a in args)))
f.write(" } catch(int api_ierr_) {return api_ierr_;}\n");
f.write(" return 0;\n");
f.write("}\n\n")
all :
python gen.py
g++ -c gmshc.cc -shared -o libgmshc.so
gcc main.c -L. -L../build -Wl,-rpath=../build -lstdc++ -lgmsh -lgmshc -lgmsh -o main
This diff is collapsed.
#include <stdio.h>
#include "gmshc.h"
#define chk(ierr) if (ierr != 0) {fprintf(stderr, "ERROR on line %i in function '%s': gmsh function return non-zero error code: %i\n",__LINE__, __FUNCTION__,ierr); gmshcFinalize(); exit(ierr);}
void genGeometry() {
int ierr;
ierr = gmshcModelCreate("square");
ierr = gmshcModelGeoAddPoint(0,0,0,0.1,1,NULL);chk(ierr);
ierr = gmshcModelGeoAddPoint(1,0,0,0.1,2,NULL);chk(ierr);
ierr = gmshcModelGeoAddPoint(1,1,0,0.1,3,NULL);chk(ierr);
ierr = gmshcModelGeoAddPoint(0,1,0,0.1,4,NULL);chk(ierr);
ierr = gmshcModelGeoAddLine(1,2,1,NULL); chk(ierr);
ierr = gmshcModelGeoAddLine(2,3,2,NULL); chk(ierr);
ierr = gmshcModelGeoAddLine(3,4,3,NULL); chk(ierr);
// try automatic assignement of tag
int line4;
ierr = gmshcModelGeoAddLine(4,1,-1,&line4); chk(ierr);
printf("line4 received tag %i\n\n", line4);
int ll[] = {1,2,3,line4};
ierr = gmshcModelGeoAddLineLoop(ll,4,1,NULL); chk(ierr);
int s[] = {1};
ierr = gmshcModelGeoAddPlaneSurface(ll,1,6,NULL); chk(ierr);
ierr = gmshcModelGeoSynchronize(); chk(ierr);
}
void printMesh() {
int ierr;
int *dimTags;
size_t ndimTags;
ierr = gmshcModelGetEntities(&dimTags, &ndimTags, -1); chk(ierr);
for (size_t ie = 0; ie < ndimTags/2; ++ie) {
int *types, **elementTags, **vertexTags;
size_t ntypes, *nelementTags, nnelementTags, *nvertexTags, nnvertexTags;
ierr = gmshcModelGetMeshElements(dimTags[ie*2+0], dimTags[ie*2+1], &types, &ntypes, &elementTags, &nelementTags, &nnelementTags, &vertexTags, &nvertexTags, &nnvertexTags); chk(ierr);
printf("entity %i of dim %i\n", dimTags[ie*2+1], dimTags[ie*2+0]);
for (size_t i = 0; i < nnelementTags; ++i) {
printf(" %lu elements of type %i : ", nelementTags[i], types[i]);
size_t nnodesbyel = nvertexTags[i]/nelementTags[i];
for (size_t j = 0; j < nelementTags[i] && j < 3; ++j) {
printf("%i ( ", elementTags[i][j]);
for (size_t k = 0; k < nnodesbyel; ++k)
printf("%i ", vertexTags[i][j*nnodesbyel+k]);
printf(") ");
}
if (nelementTags[i] > 3)
printf("...");
printf("\n");
}
free(types);
for (size_t i = 0; i < nnelementTags; ++i)
free(elementTags[i]);
for (size_t i = 0; i < nnvertexTags; ++i)
free(vertexTags[i]);
free(nelementTags);
free(nvertexTags);
}
free(dimTags);
}
void genError() {
int ierr;
printf("\n** generate an error **\n");
ierr = gmshcModelGetMeshElements(999, 999, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); chk(ierr);
}
int main(int argc, char **argv) {
int ierr;
gmshcInitialize(argc, argv);
genGeometry();
ierr = gmshcModelMesh(2); chk(ierr);
ierr = gmshcExport("square.msh"); chk(ierr);
printMesh();
genError();
ierr = gmshcFinalize(); chk(ierr);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment