netgen/libsrc/csg/python_csg.cpp

345 lines
12 KiB
C++
Raw Normal View History

2014-08-31 19:05:24 +06:00
#ifdef NG_PYTHON
2014-08-30 06:15:59 +06:00
2014-10-08 20:09:03 +06:00
#include <../general/ngpython.hpp>
2014-08-30 06:15:59 +06:00
#include <csg.hpp>
using namespace netgen;
2014-09-25 16:50:48 +06:00
// a shadow solid tree using shared pointers.
class SPSolid
{
shared_ptr<SPSolid> s1, s2;
Solid * solid;
2014-10-01 02:36:02 +06:00
int bc = -1;
2014-10-18 20:41:20 +06:00
double maxh = -1;
2014-10-05 22:53:19 +06:00
string material;
2014-09-25 16:50:48 +06:00
bool owner;
2014-10-29 00:56:11 +05:00
double red, green, blue;
bool transp = false;
2014-09-25 16:50:48 +06:00
public:
enum optyp { TERM, SECTION, UNION, SUB };
SPSolid (Solid * as) : solid(as), owner(true), op(TERM) { ; }
2014-09-26 02:23:31 +06:00
~SPSolid ()
{
2014-10-01 02:36:02 +06:00
; // if (owner) delete solid;
2014-09-26 02:23:31 +06:00
}
2014-09-25 16:50:48 +06:00
SPSolid (optyp aop, shared_ptr<SPSolid> as1, shared_ptr<SPSolid> 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());
2014-09-25 20:42:36 +06:00
else if (aop == SUB)
2014-09-26 02:23:31 +06:00
solid = new Solid (Solid::SUB, s1->GetSolid()); // , s2->GetSolid());
2014-09-25 16:50:48 +06:00
}
Solid * GetSolid() { return solid; }
2014-10-01 18:07:09 +06:00
const Solid * GetSolid() const { return solid; }
2014-09-25 16:50:48 +06:00
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);
}
2014-10-05 22:53:19 +06:00
void SetMaterial (string mat) { material = mat; }
string GetMaterial ()
{
if (!material.empty()) return material;
if (s1)
{
string s1mat = s1->GetMaterial();
if (!s1mat.empty()) return s1mat;
}
if (s2)
{
string s2mat = s2->GetMaterial();
if (!s2mat.empty()) return s2mat;
}
return material;
}
2014-10-01 02:36:02 +06:00
void SetBC(int abc)
{
if (bc == -1)
{
bc = abc;
if (s1) s1 -> SetBC(bc);
if (s2) s2 -> SetBC(bc);
if (op == TERM)
{
Primitive * prim = solid -> GetPrimitive();
for (int i = 0; i < prim->GetNSurfaces(); i++)
prim->GetSurface(i).SetBCProperty (abc);
cout << "set " << prim->GetNSurfaces() << " surfaces to bc " << bc << endl;
}
}
}
2014-10-18 20:41:20 +06:00
2014-12-05 20:58:49 +05:00
void SetMaxH(double amaxh)
2014-10-18 20:41:20 +06:00
{
if (maxh == -1)
{
maxh = amaxh;
if (s1) s1 -> SetMaxH(maxh);
if (s2) s2 -> SetMaxH(maxh);
if (op == TERM)
{
Primitive * prim = solid -> GetPrimitive();
for (int i = 0; i < prim->GetNSurfaces(); i++)
prim->GetSurface(i).SetMaxH (maxh);
}
}
}
2014-10-29 00:56:11 +05:00
void SetColor(double ared, double agreen, double ablue)
{
red = ared;
green = agreen;
blue = ablue;
2014-10-29 00:56:11 +05:00
}
double GetRed() const { return red; }
double GetGreen() const { return green; }
double GetBlue() const { return blue; }
void SetTransparent() { transp = true; }
bool IsTransparent() { return transp; }
2014-10-18 20:41:20 +06:00
2014-09-25 16:50:48 +06:00
private:
optyp op;
};
2014-08-30 06:15:59 +06:00
2014-10-01 18:07:09 +06:00
inline ostream & operator<< (ostream & ost, const SPSolid & sol)
{
ost << *sol.GetSolid();
return ost;
}
2014-08-30 06:15:59 +06:00
namespace netgen
{
extern CSGeometry * ParseCSG (istream & istr);
}
void ExportCSG()
{
2014-10-08 21:48:48 +06:00
ModuleScope module("csg");
2014-08-30 06:15:59 +06:00
2014-09-25 20:42:36 +06:00
bp::class_<Point<2>> ("Point2d", bp::init<double,double>())
.def(bp::self+Vec<2>())
;
2014-09-25 17:30:38 +06:00
bp::class_<Point<3>> ("Point3d", bp::init<double,double,double>())
2014-09-26 02:23:31 +06:00
.def(bp::self-bp::self)
2014-09-25 17:30:38 +06:00
.def(bp::self+Vec<3>())
2014-09-26 02:23:31 +06:00
.def(bp::self-Vec<3>())
2014-09-25 17:30:38 +06:00
;
2014-09-25 20:42:36 +06:00
bp::def ("Pnt", FunctionPointer( [] (double x, double y, double z) { return Point<3>(x,y,z); } ) );
bp::def ("Pnt", FunctionPointer( [] (double x, double y) { return Point<2>(x,y); } ) );
bp::class_<Vec<2>> ("Vec2d", bp::init<double,double>())
.def(bp::self+bp::self)
// .def(bp::self*double())
.def(double()*bp::self)
2014-10-29 00:56:11 +05:00
.def("Norm", &Vec<2>::Length)
2014-09-25 20:42:36 +06:00
;
2014-09-25 17:30:38 +06:00
bp::class_<Vec<3>> ("Vec3d", bp::init<double,double,double>())
.def(bp::self+bp::self)
2014-09-25 20:42:36 +06:00
// .def(bp::self*double())
.def(double()*bp::self)
2014-10-29 00:56:11 +05:00
.def("Norm", &Vec<3>::Length)
2014-09-25 17:30:38 +06:00
;
2014-09-25 20:42:36 +06:00
bp::def ("Vec", FunctionPointer( [] (double x, double y, double z) { return Vec<3>(x,y,z); } ) );
bp::def ("Vec", FunctionPointer( [] (double x, double y) { return Vec<2>(x,y); } ) );
2014-09-25 16:50:48 +06:00
2014-09-25 20:42:36 +06:00
bp::class_<SPSolid, shared_ptr<SPSolid>, boost::noncopyable> ("Solid", bp::no_init)
2014-10-01 18:07:09 +06:00
.def ("__str__", &ToString<SPSolid>)
2014-09-25 20:42:36 +06:00
.def ("__add__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other ) { return make_shared<SPSolid> (SPSolid::UNION, self, other); } ) )
.def ("__mul__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other ) { return make_shared<SPSolid> (SPSolid::SECTION, self, other); } ) )
2014-09-26 02:23:31 +06:00
.def ("__sub__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other )
{ return make_shared<SPSolid> (SPSolid::SECTION, self, make_shared<SPSolid> (SPSolid::SUB, other, nullptr)); } ) )
2014-09-25 20:42:36 +06:00
// .def ("__neg__", FunctionPointer( [] ( shared_ptr<SPSolid> self ) { return make_shared<SPSolid> (SPSolid::SUB, self); } ) ) COMPLEMENT?
2014-10-01 18:07:09 +06:00
2014-10-01 02:36:02 +06:00
.def ("bc", FunctionPointer([](shared_ptr<SPSolid> & self, int nr) -> shared_ptr<SPSolid>
{ self->SetBC(nr); return self; }))
2014-10-18 20:41:20 +06:00
.def ("maxh", FunctionPointer([](shared_ptr<SPSolid> & self, double maxh) -> shared_ptr<SPSolid>
{ self->SetMaxH(maxh); return self; }))
2014-10-05 22:53:19 +06:00
.def ("mat", FunctionPointer([](shared_ptr<SPSolid> & self, string mat) -> shared_ptr<SPSolid>
{ self->SetMaterial(mat); return self; }))
.def ("mat", &SPSolid::GetMaterial)
2014-10-29 00:56:11 +05:00
.def("col", FunctionPointer([](shared_ptr<SPSolid> & self, bp::list rgb) -> shared_ptr<SPSolid>
{
bp::extract<double> red(rgb[0]);
bp::extract<double> green(rgb[1]);
bp::extract<double> blue(rgb[2]);
self->SetColor(red(),green(),blue());
return self; }))
.def("transp", FunctionPointer([](shared_ptr<SPSolid> & self)->shared_ptr < SPSolid > { self->SetTransparent(); return self; }))
2014-10-05 22:53:19 +06:00
;
2014-09-25 16:50:48 +06:00
2014-09-26 02:23:31 +06:00
bp::def ("Sphere", FunctionPointer([](Point<3> c, double r)
2014-09-25 16:50:48 +06:00
{
Sphere * sp = new Sphere (c, r);
Solid * sol = new Solid (sp);
return make_shared<SPSolid> (sol);
}));
2014-09-26 02:23:31 +06:00
bp::def ("Plane", FunctionPointer([](Point<3> p, Vec<3> n)
2014-09-25 16:50:48 +06:00
{
Plane * sp = new Plane (p,n);
Solid * sol = new Solid (sp);
return make_shared<SPSolid> (sol);
}));
2014-09-26 02:23:31 +06:00
bp::def ("Cylinder", FunctionPointer([](Point<3> a, Point<3> b, double r)
{
Cylinder * cyl = new Cylinder (a, b, r);
Solid * sol = new Solid (cyl);
return make_shared<SPSolid> (sol);
}));
bp::def ("OrthoBrick", FunctionPointer([](Point<3> p1, Point<3> p2)
2014-09-25 16:50:48 +06:00
{
OrthoBrick * brick = new OrthoBrick (p1,p2);
Solid * sol = new Solid (brick);
return make_shared<SPSolid> (sol);
}));
bp::def ("Or", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
{
return make_shared<SPSolid> (SPSolid::UNION, s1, s2);
}));
bp::def ("And", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
{
return make_shared<SPSolid> (SPSolid::SECTION, s1, s2);
}));
2014-08-30 06:15:59 +06:00
bp::class_<CSGeometry, boost::noncopyable> ("CSGeometry")
.def("__init__", bp::make_constructor (FunctionPointer
2014-09-25 16:50:48 +06:00
([](const string & filename)
{
cout << "load geometry";
ifstream ist(filename);
shared_ptr<CSGeometry> geom(ParseCSG(ist));
geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
return geom;
})))
2014-10-05 22:53:19 +06:00
.def("__init__", bp::make_constructor (FunctionPointer
([](const bp::list & solidlist)
{
cout << "csg from list";
auto geom = make_shared<CSGeometry>();
for (int i = 0; i < len(solidlist); i++)
{
bp::object obj = solidlist[i];
cout << "obj " << i << endl;
bp::extract<shared_ptr<SPSolid>> solid(solidlist[i]);
if(solid.check())
{
cout << "its a solid" << endl;
solid()->AddSurfaces (*geom);
solid()->GiveUpOwner();
int tlonr = geom->SetTopLevelObject (solid()->GetSolid());
geom->GetTopLevelObject(tlonr) -> SetMaterial(solid()->GetMaterial());
}
}
geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
return geom;
})))
2014-09-26 02:23:31 +06:00
.def("Save", FunctionPointer([] (CSGeometry & self, string filename)
{
cout << "save geometry to file " << filename << endl;
self.Save (filename);
}))
2014-10-05 22:53:19 +06:00
.def("Add", FunctionPointer
([] (CSGeometry & self, shared_ptr<SPSolid> solid)
{
solid->AddSurfaces (self);
solid->GiveUpOwner();
int tlonr = self.SetTopLevelObject (solid->GetSolid());
self.GetTopLevelObject(tlonr) -> SetMaterial(solid->GetMaterial());
2014-10-29 00:56:11 +05:00
self.GetTopLevelObject(tlonr) -> SetRGB(solid->GetRed(),solid->GetGreen(),solid->GetBlue());
self.GetTopLevelObject(tlonr)->SetTransparent(solid->IsTransparent());
2014-10-05 22:53:19 +06:00
}))
2014-09-25 16:50:48 +06:00
.def("CloseSurfaces", FunctionPointer
([] (CSGeometry & self, shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2, int reflevels)
{
Array<int> si1, si2;
s1->GetSolid()->GetSurfaceIndices (si1);
s2->GetSolid()->GetSurfaceIndices (si2);
cout << "surface ids1 = " << si1 << endl;
cout << "surface ids2 = " << si2 << endl;
Flags flags;
const TopLevelObject * domain = nullptr;
self.AddIdentification
(new CloseSurfaceIdentification
(self.GetNIdentifications()+1, self,
self.GetSurface (si1[0]), self.GetSurface (si2[0]),
domain,
flags));
}),
(bp::arg("self"), bp::arg("solid1"), bp::arg("solid2"), bp::arg("reflevels")=2)
)
2014-08-30 06:15:59 +06:00
.add_property ("ntlo", &CSGeometry::GetNTopLevelObjects)
;
bp::def("GenerateMesh", FunctionPointer
([](CSGeometry & geo, MeshingParameters & param)
{
2014-10-01 02:36:02 +06:00
// testout = new ofstream ("test.out");
2014-09-26 02:23:31 +06:00
shared_ptr<Mesh> dummy;
2014-10-01 02:36:02 +06:00
cout << "Genrate Mesh, params = " << param << endl;
cout << "geom, bbox = " << geo.BoundingBox() << endl;
2014-09-25 16:50:48 +06:00
geo.FindIdenticSurfaces(1e-8 * geo.MaxSize());
2014-08-30 06:15:59 +06:00
geo.GenerateMesh (dummy, param, 0, 6);
2014-09-26 02:23:31 +06:00
return dummy;
2014-10-01 02:36:02 +06:00
}))
;
bp::def("ZRefinement", FunctionPointer
([](Mesh & mesh, CSGeometry & geom)
{
ZRefinementOptions opt;
opt.minref = 5;
ZRefinement (mesh, &geom, opt);
}))
;
2014-08-30 06:15:59 +06:00
}
BOOST_PYTHON_MODULE(libcsg) {
ExportCSG();
}
2014-08-31 19:05:24 +06:00
#endif
2014-08-30 06:15:59 +06:00