Skip to content
Snippets Groups Projects
Commit 448c2175 authored by Ansgar Philippsen's avatar Ansgar Philippsen
Browse files

added mesh to primlist

parent d74333c0
No related branches found
No related tags found
No related merge requests found
......@@ -243,7 +243,7 @@ def _primlist_add_text(self,text,pos,color=None,point_size=None):
if not point_size:
point_size=1.0
self._add_text(text,pos,color,point_size)
PrimList.AddPoint=_primlist_add_point
PrimList.AddLine=_primlist_add_line
PrimList.AddSphere=_primlist_add_sphere
......
......@@ -25,8 +25,88 @@ using namespace boost::python;
using namespace ost;
using namespace ost::gfx;
#if OST_NUMPY_SUPPORT_ENABLED
#include <numpy/arrayobject.h>
#endif
namespace {
void add_mesh(PrimList& p, object ova, object ona, object oca, object oia)
{
#if OST_NUMPY_SUPPORT_ENABLED
if(!PyArray_Check(ova.ptr())) {
throw std::runtime_error("ova is not a numpy array");
}
PyArrayObject* va=reinterpret_cast<PyArrayObject*>(ova.ptr());
if(!PyArray_ISCONTIGUOUS(va)) {
throw std::runtime_error("expected vertex array to be contiguous");
}
if(!PyArray_TYPE(va)==NPY_FLOAT) {
throw std::runtime_error("expected vertex array to be of dtype=float32");
}
size_t v_size=PyArray_SIZE(va);
if(v_size%3!=0) {
throw std::runtime_error("expected vertex array size to be divisible by 3");
}
size_t v_count=v_size/3;
float* vp=reinterpret_cast<float*>(PyArray_DATA(va));
float* np=0;
float* cp=0;
if(ona!=object()) {
if(!PyArray_Check(ona.ptr())) {
throw std::runtime_error("ona is not a numpy array");
}
PyArrayObject* na=reinterpret_cast<PyArrayObject*>(ona.ptr());
if(!PyArray_ISCONTIGUOUS(na)) {
throw std::runtime_error("expected normal array to be contiguous");
}
if(!PyArray_TYPE(na)==NPY_FLOAT) {
throw std::runtime_error("expected normal array to be of dtype=float32");
}
if(PyArray_SIZE(na)!=v_size) {
throw std::runtime_error("expected normal array size to match vertex array size");
}
np=reinterpret_cast<float*>(PyArray_DATA(na));
}
if(oca!=object()) {
if(!PyArray_Check(oca.ptr())) {
throw std::runtime_error("oca is not a numpy array");
}
PyArrayObject* ca=reinterpret_cast<PyArrayObject*>(oca.ptr());
if(!PyArray_ISCONTIGUOUS(ca)) {
throw std::runtime_error("expected color array to be contiguous");
}
if(!PyArray_TYPE(ca)==NPY_FLOAT) {
throw std::runtime_error("expected color array to be of dtype=float32");
}
if(PyArray_SIZE(ca)!=v_count*4) {
throw std::runtime_error("expected color array size to equal vertex-count x 4");
}
cp=reinterpret_cast<float*>(PyArray_DATA(ca));
}
if(!PyArray_Check(oia.ptr())) {
throw std::runtime_error("oia is not a numpy array");
}
PyArrayObject* ia=reinterpret_cast<PyArrayObject*>(oia.ptr());
if(!PyArray_ISCONTIGUOUS(ia)) {
throw std::runtime_error("expected vertex array to be contiguous");
}
if(!PyArray_TYPE(ia)==NPY_UINT) {
throw std::runtime_error("expected vertex array to be of dtype=uint32");
}
size_t i_size=PyArray_SIZE(ia);
unsigned int* ip=reinterpret_cast<unsigned int*>(PyArray_DATA(ia));
p.AddMesh(vp,np,cp,v_count,ip,i_size/3);
#else
throw std::runtime_error("AddMesh requires compiled-in numpy support");
#endif
}
}
void export_primlist()
{
import_array(); // magic handshake for numpy module
class_<PrimList, bases<GfxObj>, boost::shared_ptr<PrimList>, boost::noncopyable>("PrimList", init<const String& >())
.def("Clear",&PrimList::Clear)
.def("_add_line",&PrimList::AddLine)
......@@ -34,6 +114,7 @@ void export_primlist()
.def("_add_sphere",&PrimList::AddSphere)
.def("_add_cyl",&PrimList::AddCyl)
.def("_add_text",&PrimList::AddText)
.def("AddMesh",add_mesh)
.def("SetColor",&PrimList::SetColor)
.def("SetDiameter",&PrimList::SetDiameter)
.def("SetRadius",&PrimList::SetRadius)
......
......@@ -38,7 +38,8 @@ PrimList::PrimList(const String& name):
texts_(),
sphere_detail_(4),
arc_detail_(4),
simple_va_()
simple_va_(),
vas_()
{}
void PrimList::Clear()
......@@ -48,13 +49,14 @@ void PrimList::Clear()
spheres_.clear();
cyls_.clear();
texts_.clear();
vas_.clear();
Scene::Instance().RequestRedraw();
this->FlagRebuild();
}
geom::AlignedCuboid PrimList::GetBoundingBox() const
{
if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty()) {
if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty() && texts_.empty() && vas_.empty()) {
return geom::AlignedCuboid(geom::Vec3(-1,-1,-1),geom::Vec3(1,1,1));
}
geom::Vec3 minc(std::numeric_limits<float>::max(),
......@@ -101,6 +103,11 @@ void PrimList::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc,
minc=geom::Min(minc,tpos);
maxc=geom::Max(maxc,tpos);
}
for(std::vector<IndexedVertexArray>::const_iterator it=vas_.begin();it!=vas_.end();++it) {
geom::AlignedCuboid bb=it->GetBoundingBox();
minc=geom::Min(minc,bb.GetMin());
maxc=geom::Max(maxc,bb.GetMax());
}
minc-=1.0;
maxc+=1.0;
}
......@@ -152,12 +159,15 @@ void PrimList::CustomRenderGL(RenderPass pass)
va_.RenderGL();
simple_va_.RenderGL();
render_text();
for(std::vector<IndexedVertexArray>::iterator it=vas_.begin();it!=vas_.end();++it) {
it->RenderGL();
}
}
}
void PrimList::CustomRenderPov(PovState& pov)
{
if(points_.empty() && lines_.empty()) return;
if(points_.empty() && lines_.empty() && spheres_.empty() && cyls_.empty()) return;
pov.write_merge_or_union(GetName());
for(SpherePrimList::const_iterator it=points_.begin();it!=points_.end();++it) {
......@@ -262,6 +272,42 @@ void PrimList::SetColor(const Color& c)
FlagRebuild();
}
void PrimList::AddMesh(float* v, float* n, float* c, size_t nv, unsigned int* i, size_t ni)
{
static float dummy_normal[]={0.0,0.0,1.0};
static float dummy_color[]={1.0,1.0,1.0,1.0};
vas_.push_back(IndexedVertexArray());
IndexedVertexArray& va=vas_.back();
va.SetLighting(true);
va.SetTwoSided(true);
va.SetColorMaterial(true);
va.SetCullFace(false);
float* vv=v;
float* nn=n;
if(!n) {
nn=dummy_normal;
va.SetLighting(false);
}
float* cc=c;
if(!c) {
cc=dummy_color;
}
for(size_t k=0;k<nv;++k) {
va.Add(geom::Vec3(vv[0],vv[1],vv[2]),
geom::Vec3(nn[0],nn[1],nn[2]),
Color(cc[0],cc[1],cc[2],cc[3]));
vv+=3;
if(n) nn+=3;
if(c) cc+=4;
}
unsigned int* ii=i;
for(size_t k=0;k<ni;++k) {
va.AddTri(ii[0],ii[1],ii[2]);
ii+=3;
}
Scene::Instance().RequestRedraw();
FlagRebuild();
}
////////////////////////////////
// private methods
......
......@@ -139,6 +139,24 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj
// TODO: add point and line pixel width
/*!
\brief add triangle mesh
v : pointer to nv*3 floats for the positions (mandatory)
n : pointer to nv*3 floats for the normals (may be NULL)
c : pointer to nv*4 floats for the colors (may be NULL)
nv: number of vertices, normals, and colors
i : pointer to ni*3 vertex indices
ni: number of index triplets
Python interface, using numpy arrays:
AddMesh(vertex_array, normal_array, color_array, index_array)
where normal_array and color_array may be None
*/
void AddMesh(float* v, float* n, float* c, size_t nv, unsigned int* i, size_t ni);
protected:
virtual void CustomPreRenderGL(bool flag);
......@@ -152,6 +170,8 @@ class DLLEXPORT_OST_GFX PrimList: public GfxObj
unsigned int arc_detail_;
IndexedVertexArray simple_va_;
std::vector<IndexedVertexArray> vas_;
void prep_simple_va();
void prep_va();
......
......@@ -9,6 +9,11 @@ import ost.mol as mol
import ost.gfx as gfx
import ost.geom as geom
has_numpy=True
import numpy
if not has_numpy:
has_numpy=False
def col_delta(c1,c2):
return geom.Distance(geom.Vec3(c1[0],c1[1],c1[2]),geom.Vec3(c2[0],c2[1],c2[2]))
......@@ -71,6 +76,16 @@ class TestGfx(unittest.TestCase):
pl.AddCyl(geom.Vec3(0,0,0),geom.Vec3(1,2,3),radius1=0.5,radius2=0.1,color1=gfx.BLUE,color2=gfx.GREEN)
pl.AddText("foo",[0,2,3])
pl.AddText("bar",[-2,0,0],color=gfx.WHITE,point_size=8)
if has_numpy:
pl.AddMesh(numpy.zeros((5,3),dtype=numpy.float32),
numpy.zeros((5,3),dtype=numpy.float32),
numpy.zeros((5,4),dtype=numpy.float32),
numpy.zeros((2,3),dtype=numpy.uint32))
pl.AddMesh(numpy.zeros((7,3),dtype=numpy.float32),
None,
None,
numpy.zeros((4,3),dtype=numpy.uint32))
if __name__== '__main__':
unittest.main()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment