#ifdef NG_PYTHON #include #include using namespace netgen; namespace bp = boost::python; ////////////////////////////////////////////////////////////////////// // Lambda to function pointer conversion template struct function_traits : public function_traits {}; template struct function_traits { typedef ReturnType (*pointer)(Args...); typedef ReturnType return_type; }; template typename function_traits::pointer FunctionPointer (const Function& lambda) { return static_cast::pointer>(lambda); } template inline string ToString (const T& t) { stringstream ss; ss << t; return ss.str(); } // a shadow solid tree using shared pointers. class SPSolid { shared_ptr s1, s2; Solid * solid; bool owner; public: enum optyp { TERM, SECTION, UNION, SUB }; SPSolid (Solid * as) : solid(as), owner(true), op(TERM) { ; } SPSolid (optyp aop, shared_ptr as1, shared_ptr as2) : s1(as1), s2(as2), owner(true), op(aop) { if (aop == UNION) solid = new Solid (Solid::UNION, s1->GetSolid(), s2->GetSolid()); else if (aop == SECTION) solid = new Solid (Solid::SECTION, s1->GetSolid(), s2->GetSolid()); } Solid * GetSolid() { return solid; } void GiveUpOwner() { owner = false; if (s1) s1 -> GiveUpOwner(); if (s2) s2 -> GiveUpOwner(); } void AddSurfaces(CSGeometry & geom) { if (op == TERM) geom.AddSurfaces (solid->GetPrimitive()); if (s1) s1 -> AddSurfaces (geom); if (s2) s2 -> AddSurfaces (geom); } private: optyp op; }; namespace netgen { extern CSGeometry * ParseCSG (istream & istr); } void ExportCSG() { std::string nested_name = "csg"; if( bp::scope() ) nested_name = bp::extract(bp::scope().attr("__name__") + ".csg"); bp::object module(bp::handle<>(bp::borrowed(PyImport_AddModule(nested_name.c_str())))); cout << "exporting csg " << nested_name << endl; bp::object parent = bp::scope() ? bp::scope() : bp::import("__main__"); parent.attr("csg") = module ; bp::scope local_scope(module); bp::class_> ("Point3d", bp::init()) .def(bp::self+Vec<3>()) ; bp::class_> ("Vec3d", bp::init()) .def(bp::self+bp::self) ; bp::class_, boost::noncopyable> ("Solid", bp::no_init) ; bp::def ("Sphere", FunctionPointer([](const Point<3> c, double r) { Sphere * sp = new Sphere (c, r); Solid * sol = new Solid (sp); return make_shared (sol); })); bp::def ("Plane", FunctionPointer([](const Point<3> p, Vec<3> n) { Plane * sp = new Plane (p,n); Solid * sol = new Solid (sp); return make_shared (sol); })); bp::def ("OrthoBrick", FunctionPointer([](const Point<3> p1, Point<3> p2) { OrthoBrick * brick = new OrthoBrick (p1,p2); Solid * sol = new Solid (brick); return make_shared (sol); })); bp::def ("Or", FunctionPointer([](shared_ptr s1, shared_ptr s2) { return make_shared (SPSolid::UNION, s1, s2); })); bp::def ("And", FunctionPointer([](shared_ptr s1, shared_ptr s2) { return make_shared (SPSolid::SECTION, s1, s2); })); bp::class_ ("CSGeometry") .def("__init__", bp::make_constructor (FunctionPointer ([](const string & filename) { cout << "load geometry"; ifstream ist(filename); shared_ptr geom(ParseCSG(ist)); geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize()); return geom; }))) .def("Add", FunctionPointer([] (CSGeometry & self, shared_ptr solid) { solid->AddSurfaces (self); solid->GiveUpOwner(); self.SetTopLevelObject (solid->GetSolid()); })) .add_property ("ntlo", &CSGeometry::GetNTopLevelObjects) ; bp::def("GenerateMesh", FunctionPointer ([](CSGeometry & geo, MeshingParameters & param) { Mesh * dummy = NULL; cout << "Genrate Mesh, params = "; // << param << endl; geo.FindIdenticSurfaces(1e-8 * geo.MaxSize()); geo.GenerateMesh (dummy, param, 0, 6); return shared_ptr (dummy); })); } BOOST_PYTHON_MODULE(libcsg) { ExportCSG(); } #endif