Exemple #1
0
bool AdaptiveGridTest::init()
{
	float gz = 128.f;
	setColorScale(.43f / gz);
	setNodeDrawSize(gz * .008f);
	m_msh.fillBox(BoundingBox(-250.f, -50.f, -250.f,
								 250.f,  50.f,  250.f), gz);
	
	m_distFunc.addSphere(Vector3F(    9.f, 17.f, -1.f), 27.f );
	m_distFunc.addSphere(Vector3F(-54.f, -13.f, -1.f), 64.f );
	m_distFunc.addSphere(Vector3F(38.f, -10.f, -22.f), 21.1f );
	m_distFunc.addSphere(Vector3F(-100.f, -3420.1f, -100.f), 3400.f );
	
#define MAX_BUILD_LEVEL 5
#define MAX_BUILD_ERROR .5f
	m_msh.adaptiveBuild<BDistanceFunction>(&m_distFunc, MAX_BUILD_LEVEL, MAX_BUILD_ERROR);
	std::cout<<"\n triangulating"<<std::endl;
	m_msh.triangulateFront();
	
#if 0
	checkTetraVolumeExt<DistanceNode, ITetrahedron>(m_msh.nodes(), m_msh.numTetrahedrons(),
						m_msh.tetrahedrons() );
#endif

	std::cout.flush();
	return true;
}
bool FlyingCamera::onSimCameraQuery(SimCameraQuery *query)
{
   SimObjectTransformQuery tquery;

   query->cameraInfo.fov       = g_rDefaultFOV;
   query->cameraInfo.nearPlane = DEFAULT_NEAR_PLANE;
   query->cameraInfo.farPlane  = getFarPlane();

   if (objFollow && objFollow->processQuery(&tquery))
   {
      Point3F  objPos = tquery.tmat.p;
      Vector3F x, y, z;
      RMat3F   rmat(EulerF(rotation.x - M_PI / 2, rotation.y, -rotation.z));

      tquery.tmat.p   += m_mul(Vector3F(0.0f, rDistance, 0.0f), rmat, &y);
      tquery.tmat.p.z += 2.0f;

      y.neg();
      y.normalize();
      m_cross(y, Vector3F(0.0f, 0.0f, 1.0f), &x);
      x.normalize();
      m_cross(x, y, &z);

      tquery.tmat.setRow(0, x);
      tquery.tmat.setRow(1, y);
      tquery.tmat.setRow(2, z);

      // Set our position
      findLOSPosition(tquery.tmat, objPos);
   }

   query->cameraInfo.tmat = getTransform();
   return (true);
}
LinearSpline::LinearSpline()
{
	addNode();
	addNode();
	mNodes[0]->position = mNodes[0]->position.value() + Vector3F(-0.5, 0.0, 0.0);
	mNodes[1]->position = mNodes[1]->position.value() + Vector3F(+0.5, 0.0, 0.0);
	new RenderLinearSpline(getID());
}
Exemple #4
0
float MlRachis::bouncing(const Vector3F & a, const Vector3F & b, const Vector3F & c)
{
	float alpha = Vector3F(a, b).normal().dot(Vector3F(a, c).normal());
	if(alpha < 0.f) return 0.f;
	float lac = Vector3F(a, c).length() * alpha - Vector3F(a, b).length();
	float beta = asin(lac / Vector3F(a, c).length());
	return 2.f - beta - alpha;
}
Exemple #5
0
/////////////////////////////////////////////////////////////
/// Construit le quaternion à partir de 3 angles d'Euler
///
/// \param X : Angle autour de X
/// \param Y : Angle autour de Y
/// \param Z : Angle autour de Z
///
////////////////////////////////////////////////////////////
void Quaternion::FromEulerAngles(float X, float Y, float Z)
{
    Quaternion Qx(Vector3F(1, 0, 0), X);
    Quaternion Qy(Vector3F(0, 1, 0), Y);
    Quaternion Qz(Vector3F(0, 0, 1), Z);

    *this = Qx * Qy * Qz;
}
Exemple #6
0
void BaseView::frameAll()
{
    m_centerOfInterest.setZero();
    m_space.setIdentity();
	m_space.setTranslation(Vector3F(0.f, 0.f, 100.f) );
	m_invSpace.setIdentity();
	m_invSpace.setTranslation(Vector3F(0.f, 0.f, -100.f) );
}
Exemple #7
0
float MlRachis::distanceFactor(const Vector3F & a, const Vector3F & b, const Vector3F & c)
{
	float facing = Vector3F(a, b).normal().dot(Vector3F(a, c).normal());
	float lac = Vector3F(a, c).length() * facing;
	float lab = Vector3F(a, b).length();
	if(lac > lab) return 0.f;
	float ang = 1.f - lac / lab * (lac / lab);
	return ang * 3;
}
Exemple #8
0
Vector3F Vector3F::Normalize()
{
	double mag = sqrt(x*x + y*y + z*z); 
	if (mag == 0) return Vector3F(0, 0, 0);
	//Assert(mag != 0, "Vector3F::Normalize vector of magnitude 0 was requested to be normalized.");
	
	mag = 1.0/mag;
	return Vector3F(x*mag, y*mag, z*mag);
}
Exemple #9
0
BaseView::BaseView() 
{
	m_centerOfInterest.set(0.f, 0.f, 0.f);
	m_space.setIdentity();
	m_space.setTranslation(Vector3F(0.f, 0.f, 100.f) );
	m_invSpace.setIdentity();
	m_invSpace.setTranslation(Vector3F(0.f, 0.f, -100.f) );
	
/// 35mm Academy
	std::cout<<"\n angle of view "<<180.f/3.14f*2.f * atan(21.9456f/2.f/35.f)<<" deg";
	setFrustum(.864f, .63f, 35.f, -1.f, -20000.f);
	
}
Exemple #10
0
const Vector3F BoundingBox::corner(const int & i) const
{
    const int iz = i / 4;
    const int iy = (i - iz * 4) / 2;
    const int ix = i - iy * 2 - iz * 4;
    return Vector3F(m_data[3 * ix], m_data[1 + 3 * iy], m_data[2 + 3 * iz]);
}
Exemple #11
0
Vector3F operator*(Matrix4x4F & A, Vector3F & v)
{
	return Vector3F(
		A.m[0][0]*v.x + A.m[0][1]*v.y + A.m[0][2]*v.z + A.m[0][3],
		A.m[1][0]*v.x + A.m[1][1]*v.y + A.m[1][2]*v.z + A.m[1][3],
		A.m[2][0]*v.x + A.m[2][1]*v.y + A.m[2][2]*v.z + A.m[2][3]);
}
Exemple #12
0
void QuatJulia::generate()
{
/// eval at uniform grid
	int i, j, k;
	const float grid = 1.f / (float)m_numGrid;
	const Vector3F origin(-.5f+grid * .5f, 
							-.5f+grid * .5f, 
							-.5f+grid * .5f);
	int n = 0;
	for(k=0; k<m_numGrid; ++k ) {
		for(j=0; j<m_numGrid; ++j ) {
			for(i=0; i<m_numGrid; ++i ) {
				Vector3F sample = origin + Vector3F(grid * i, grid * j, grid * k);
				if( evalAt( sample*3.2f ) > 0.f ) {
					n++;
					cvx::Sphere sp;
					sample *= m_scaling;
					sp.set(sample, .001f);
					m_tree->insert((const float *)&sample, sp);
				}
			}
		}
	}
	m_tree->finishInsert();
}
Exemple #13
0
void UniformGrid::refine(KdTree * tree)
{    
	int level1;
	float hh;
    Vector3F sample, subs;
	int u;
	unsigned k;
	BoundingBox box;
	m_cellsToRefine->begin();
	while (!m_cellsToRefine->end()) {
		sdb::CellValue * parentCell = m_cellsToRefine->value();
		if(parentCell->visited > 0) {
        
			k = m_cellsToRefine->key();
			
			level1 = parentCell->level + 1;
			hh = cellSizeAtLevel(level1) * .5f;
			sample = cellCenter(k);
			removeCell(k);
			for(u = 0; u < 8; u++) {
				subs = sample + Vector3F(hh * Cell8ChildOffset[u][0], 
				hh * Cell8ChildOffset[u][1], 
				hh * Cell8ChildOffset[u][2]);
				box.setMin(subs.x - hh, subs.y - hh, subs.z - hh);
                box.setMax(subs.x + hh, subs.y + hh, subs.z + hh);
				if(tree->intersectBox(box)) 
					addCell(subs, level1);
			}
		}
		
		m_cellsToRefine->next();
    }
}
Exemple #14
0
void BccLattice::add24Tetrahedron(const Vector3F & center, float h)
{
    const unsigned ccenter = mortonEncode(center);
    unsigned cgreen;
	Vector3F corner;
	unsigned vOctahedron[6];
	int i;
	for(i=0; i < 6; i++) {
        corner = center + Vector3F(h * HexHeighborOffset[i][0], 
        h * HexHeighborOffset[i][1], 
        h * HexHeighborOffset[i][2]);
        
        cgreen = mortonEncode(corner);
        
		sdb::EdgeValue * edge = m_greenEdges->findEdge(ccenter, cgreen);
		if(!edge) {
		    // std::cout<<" edge "<<i<<" connected to "<<center<<" doesn't exist!\n";
		    continue;
		}
		if(edge->visited == 0) {
		    encodeOctahedronVertices(center, h, i, vOctahedron);
		    addTetrahedronsAllNodeVisited(vOctahedron);
		    edge->visited = 1;
		}
    }
}
Exemple #15
0
Vector3F operator*(Vector3F & v, Matrix4x4F & A)
{
	return Vector3F(
		v.x*A.m[0][0] + v.y*A.m[1][0] + v.z*A.m[2][0] + A.m[3][0],
		v.x*A.m[0][1] + v.y*A.m[1][1] + v.z*A.m[2][1] + A.m[3][1],
		v.x*A.m[0][2] + v.y*A.m[1][2] + v.z*A.m[2][2] + A.m[3][2]);
}
Exemple #16
0
IFloatBuffer* NormalsUtils::createTriangleSmoothNormals(const IFloatBuffer* vertices,
                                                        const IShortBuffer* indices) {

  const int verticesSize = vertices->size();
  IFloatBuffer* normals = IFactory::instance()->createFloatBuffer(verticesSize);
  for (int i = 0; i < verticesSize; i++) {
    normals->rawPut(i, 0);
  }

  const int indicesSize = indices->size();
  for (int i = 0; i < indicesSize; i += 3) {
    const short index0 = indices->get(i);
    const short index1 = indices->get(i + 1);
    const short index2 = indices->get(i + 2);

    const Vector3F normal = calculateNormal(vertices, index0, index1, index2);
    addNormal(normals, index0, normal);
    addNormal(normals, index1, normal);
    addNormal(normals, index2, normal);
  }

  for (int i = 0; i < verticesSize; i += 3) {
    const float x = normals->get(i);
    const float y = normals->get(i + 1);
    const float z = normals->get(i + 2);

    const Vector3F normal = Vector3F(x, y, z).normalized();
    normals->rawPut(i    , normal._x);
    normals->rawPut(i + 1, normal._y);
    normals->rawPut(i + 2, normal._z);
  }

  return normals;
}
Exemple #17
0
Vector3F operator^(Matrix4x4F & A, Vector3F & v)
{
	return Vector3F(
		A.m[0][0]*v.x + A.m[0][1]*v.y + A.m[0][2]*v.z,
		A.m[1][0]*v.x + A.m[1][1]*v.y + A.m[1][2]*v.z,
		A.m[2][0]*v.x + A.m[2][1]*v.y + A.m[2][2]*v.z);
}
Exemple #18
0
void Base3DView::frameAll()
{
    Vector3F coi = sceneCenter();
    Vector3F eye = coi + Vector3F(0.f, 0.f, 100.f);
    
    getCamera()->lookFromTo(eye, coi);
}
Exemple #19
0
void BccWorld::createTestCurveGeometry()
{
	std::cout<<" gen 1 test curve";
	m_curves->create(1, 9);
	m_curves->counts()[0] = 9;
	
	Vector3F * cvs = m_curves->points();
	cvs[0].set(8.f + RandomFn11(), 1.f + RandomFn11(), 4.1f);
    cvs[1].set(2.f + RandomFn11(), 9.4f + RandomFn11(), 1.11f);
    cvs[2].set(14.f + RandomFn11(), 8.4f + RandomFn11(), -3.13f);
    cvs[3].set(12.f + RandomFn11(), 1.4f + RandomFn11(), 1.14f);
    cvs[4].set(19.f + RandomFn11(), 2.4f + RandomFn11(), 2.16f);
    cvs[5].set(20.f + RandomFn11(), 3.4f + RandomFn11(), 5.17f);
    cvs[6].set(18.f + RandomFn11(), 12.2f + RandomFn11(), 3.18f);
    cvs[7].set(12.f + RandomFn11(), 12.2f + RandomFn11(), 2.19f);
    cvs[8].set(13.f + RandomFn11(), 8.2f + RandomFn11(), -2.18f);
    
    for(unsigned i=0; i<9;i++) {
        cvs[i] -= Vector3F(12.f, 0.f, 0.f);
        cvs[i] *= 3.f;
    }
	
	m_allGeo = new GeometryArray;
	m_allGeo->create(1);
	
	CurveBuilder cb;
	
	unsigned i;
	for(i=0; i< 9; i++)
		cb.addVertex(cvs[i]);
	
	BezierCurve * c = new BezierCurve;
	cb.finishBuild(c);
	m_allGeo->setGeometry(c, 0);
}
Exemple #20
0
Vector3F Matrix44F::transform(const Vector3F& p) const
{
	float tx = p.x * M(0, 0) + p.y * M(1, 0) + p.z * M(2, 0)  + M(3, 0);
	float ty = p.x* M(0, 1) + p.y* M(1, 1) + p.z* M(2, 1) + M(3, 1);
	float tz = p.x* M(0, 2) + p.y* M(1, 2) + p.z* M(2, 2) + M(3, 2);
		
	return Vector3F(tx, ty, tz);
}
Exemple #21
0
Vector3F Matrix44F::transformAsNormal(const Vector3F& p)
{
	float tx = p.x* *m(0, 0) + p.y* *m(1, 0) + p.z* *m(2, 0);
	float ty = p.x* *m(0, 1) + p.y* *m(1, 1) + p.z* *m(2, 1);
	float tz = p.x* *m(0, 2) + p.y* *m(1, 2) + p.z* *m(2, 2);
		
	return Vector3F(tx, ty, tz);
}
	AABB AABB::CreateAABBfromCone(const Cone& c)
	{
		// Construct AABB for cone base
		Vector3F baseX = Vector3F(1.f - c.mDir.x * c.mDir.x, c.mDir.x * c.mDir.y, c.mDir.x * c.mDir.z).GetNormalized() * c.mBaseRadius;
		Vector3F baseY = Vector3F(c.mDir.y * c.mDir.x, 1.f - c.mDir.y * c.mDir.y, c.mDir.y * c.mDir.z).GetNormalized() * c.mBaseRadius;
		Vector3F baseZ = Vector3F(c.mDir.z * c.mDir.x, c.mDir.z * c.mDir.y, 1.f - c.mDir.z * c.mDir.z).GetNormalized() * c.mBaseRadius;

		Vector3F aabbMax = Vector3F(baseX.x, baseY.y, baseZ.z).Abs();
		Vector3F aabbMin = -aabbMax;

		AABB result(aabbMin, aabbMax);
		result.Move(c.mBase);

		// add tip
		result.Add(c.mTip);
		return result;
	}
Exemple #23
0
Vector3F Vector3F::NormalizeSq()
{
	double mag = x*x + y*y + z*z; 
	Assert(mag != 0, "Vector3F::Normalize vector of magnitude 0 was requested to be normalized.");
	
	mag = 1.0/mag;
	return Vector3F(x*x*mag, y*y*mag, z*z*mag);
}
void FEMTetrahedronMesh::generateBlocks(unsigned xdim, unsigned ydim, unsigned zdim, float width, float height, float depth)
{
    m_totalPoints = (xdim+1)*(ydim+1)*(zdim+1);
	m_X = new Vector3F[m_totalPoints];
	m_Xi= new Vector3F[m_totalPoints];
	m_mass = new float[m_totalPoints];
	
	int ind=0;
	float hzdim = zdim/2.0f;
	for(unsigned x = 0; x <= xdim; ++x) {
		for (unsigned y = 0; y <= ydim; ++y) {
			for (unsigned z = 0; z <= zdim; ++z) {			  
				m_X[ind] = Vector3F(width*x, height*z, depth*y);            
				m_Xi[ind] = m_X[ind];
				ind++;
			}
		}
	}
	//offset the m_tetrahedronl mesh by 0.5 units on y axis
	//and 0.5 of the depth in z axis
	for(unsigned i=0;i< m_totalPoints;i++) {
		m_X[i].y += 2.5;		
		m_X[i].z -= hzdim*depth; 
	}
	
	m_totalTetrahedrons = 5 * xdim * ydim * zdim;
	
	m_tetrahedron = new Tetrahedron[m_totalTetrahedrons];
	Tetrahedron * t = &m_tetrahedron[0];
	for (unsigned i = 0; i < xdim; ++i) {
		for (unsigned j = 0; j < ydim; ++j) {
			for (unsigned k = 0; k < zdim; ++k) {
				unsigned p0 = (i * (ydim + 1) + j) * (zdim + 1) + k;
				unsigned p1 = p0 + 1;
				unsigned p3 = ((i + 1) * (ydim + 1) + j) * (zdim + 1) + k;
				unsigned p2 = p3 + 1;
				unsigned p7 = ((i + 1) * (ydim + 1) + (j + 1)) * (zdim + 1) + k;
				unsigned p6 = p7 + 1;
				unsigned p4 = (i * (ydim + 1) + (j + 1)) * (zdim + 1) + k;
				unsigned p5 = p4 + 1;
				// Ensure that neighboring tetras are sharing faces
				if ((i + j + k) % 2 == 1) {
					addTetrahedron(t++, p1,p2,p6,p3);
					addTetrahedron(t++, p3,p6,p4,p7);
					addTetrahedron(t++, p1,p4,p6,p5);
					addTetrahedron(t++, p1,p3,p4,p0);
					addTetrahedron(t++, p1,p6,p4,p3); 
				} else {
					addTetrahedron(t++, p2,p0,p5,p1);
					addTetrahedron(t++, p2,p7,p0,p3);
					addTetrahedron(t++, p2,p5,p7,p6);
					addTetrahedron(t++, p0,p7,p5,p4);
					addTetrahedron(t++, p2,p0,p7,p5); 
				}
			}
		}
	}
}
Exemple #25
0
WireAttribute::Ptr WireAttribute::create(const std::string& name,
        WireAttribute::AttributeType type) {
    if (name == "vertex_min_angle") {
        return Ptr(new WireVertexMinAngleAttribute);
    } else if (name == "vertex_periodic_index") {
        return Ptr(new WireVertexPeriodicIndexAttribute);
    } else if (name == "vertex_symmetry_orbit") {
        return Ptr(new WireVertexSymmetryAttribute);
    } else if (name == "vertex_cubic_symmetry_orbit") {
        return Ptr(new WireVertexCubicSymmetryAttribute);
    } else if (name == "vertex_support_X") {
        Vector3F print_dir = Vector3F::UnitX();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_Y") {
        Vector3F print_dir = Vector3F::UnitY();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_Z") {
        Vector3F print_dir = Vector3F::UnitZ();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_XY") {
        Vector3F print_dir = Vector3F(1.0, 1.0, 0.0).normalized();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_YZ") {
        Vector3F print_dir = Vector3F(0.0, 1.0, 1.0).normalized();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_ZX") {
        Vector3F print_dir = Vector3F(1.0, 0.0, 1.0).normalized();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "vertex_support_XYZ") {
        Vector3F print_dir = Vector3F(1.0, 1.0, 1.0).normalized();
        return Ptr(new WireVertexSupportAttribute(print_dir));
    } else if (name == "edge_length") {
        return Ptr(new WireEdgeLengthAttribute);
    } else if (name == "edge_periodic_index") {
        return Ptr(new WireEdgePeriodicIndexAttribute);
    } else if (name == "edge_symmetry_orbit") {
        return Ptr(new WireEdgeSymmetryAttribute);
    } else if (name == "edge_cubic_symmetry_orbit") {
        return Ptr(new WireEdgeCubicSymmetryAttribute);
    } else {
        Ptr attr = Ptr(new WireAttribute);
        attr->set_attribute_type(type);
        return attr;
    }
}
Exemple #26
0
//! [0]
GLWidget::GLWidget(QWidget *parent) : Base3DView(parent)
{
	QTimer *timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(simulate()));
	timer->start(30);
	
	m_drawer = new KdTreeDrawer;
	
	rbf = new RadialBasisFunction;
	rbf->create(7);
	rbf->setXi(0, Vector3F(0,0,0));
	rbf->setXi(1, Vector3F(8,0,0));
	rbf->setXi(2, Vector3F(2.5,8.5,0));
	rbf->setXi(3, Vector3F(-8,0.2,1.0));
	rbf->setXi(4, Vector3F(-0.2,-8.2,-0.1));
	rbf->setXi(5, Vector3F(-0.1,-1.2, 7.1));
	rbf->setXi(6, Vector3F(9.0, 5.2, 2.1));
	
	rbf->setTau(16.0);
	rbf->computeWeights();
	
	m_anchor = new Anchor;
	Vector3F pa(-7.0, 5., 0.);
	m_anchor->placeAt(pa);
	
	rbf->solve(m_anchor->getCenter());
}
Exemple #27
0
Vector3F Vector3F::perpendicular() const
{
	Vector3F ref(0,1,0);
	Vector3F n = normal();
	if(n.y < -0.9f || n.y > 0.9f) ref = Vector3F(1,0,0);
	Vector3F per = cross(ref);
	per.normalize();
	return per;
}
Exemple #28
0
RandomMesh::RandomMesh(unsigned numFaces, const Vector3F & center, const float & size, int type) 
{
	createBuffer(numFaces * 4, numFaces * 4);
	
	Vector3F * p = points();
	unsigned * idx = indices();
	
	float rx, ry, rz, r, phi, theta;
	for(unsigned i = 0; i < numFaces; i++) {
		idx[i * 3] = i * 3;
		idx[i * 3 + 1] = i * 3 + 1;
		idx[i * 3 + 2] = i * 3 + 2;

		if(type == 0) {
			rx = (float(rand()%694) / 694.f - 0.5f) * 1.4f;
			ry = (float(rand()%594) / 594.f - 0.5f) * 1.4f;
			rz = (float(rand()%794) / 794.f - 0.5f) * 1.4f;
		}
		else {
			phi = ((float)(rand() % 25391)) / 25391.f * 2.f * 3.14f;
			theta = ((float)(rand() % 24331)) / 24331.f * 3.14f;
			r = ((float)(rand() % 24091)) / 24091.f * .1f + 0.9f;
			rx = sin(theta) * cos(phi);
			ry = sin(theta) * sin(phi);
			rz = cos(theta);
		}
		p[i * 3] = center + Vector3F(rx * size, ry * size, rz * size);	
		
		rx = float(rand()%294) / 294.f - 0.5f;
		ry = float(rand()%594) / 594.f - 0.5f;
		rz = float(rand()%794) / 794.f - 0.5f;
		
		p[i * 3 + 1] = p[i * 3] + Vector3F(rx, ry, rz);
		
		rx = float(rand()%394) / 394.f - 0.5f;
		ry = float(rand()%594) / 594.f - 0.5f;
		rz = float(rand()%794) / 794.f - 0.5f;
		
		p[i * 3 + 2] = p[i * 3] + Vector3F(rx, ry, rz);
	}
	
	setNumPoints(numFaces * 3);
	setNumIndices(numFaces * 3);
}
Exemple #29
0
void BccLattice::addNeighborTetrahedron(const Vector3F & center, float h)
{
    Vector3F corner;
    int i;
	for(i=0; i < 6; i++) {
        corner = center + Vector3F(h * HexHeighborOffset[i][0], 
        h * HexHeighborOffset[i][1], 
        h * HexHeighborOffset[i][2]);
        
        add24Tetrahedron(corner, h);
    }
}
Exemple #30
0
    void extract_mesh(const C3t3& c3t3,
            MatrixFr& vertices, MatrixIr& faces, MatrixIr& voxels) {
        const Tr& tr = c3t3.triangulation();
        size_t num_vertices = tr.number_of_vertices();
        size_t num_faces = c3t3.number_of_facets_in_complex();
        size_t num_voxels = c3t3.number_of_cells_in_complex();

        vertices.resize(num_vertices, 3);
        faces.resize(num_faces, 3);
        voxels.resize(num_voxels, 4);

        std::map<Tr::Vertex_handle, int> V;
        size_t inum = 0;
        for(auto vit = tr.finite_vertices_begin();
                vit != tr.finite_vertices_end(); ++vit) {
            V[vit] = inum;
            const auto& p = vit->point();
            vertices.row(inum) = Vector3F(p.x(), p.y(), p.z()).transpose();
            assert(inum < num_vertices);
            inum++;
        }
        assert(inum == num_vertices);

        size_t face_count = 0;
        for(auto fit = c3t3.facets_in_complex_begin();
                fit != c3t3.facets_in_complex_end(); ++fit) {
            assert(face_count < num_faces);
            for (int i=0; i<3; i++) {
                if (i != fit->second) {
                    const auto& vh = (*fit).first->vertex(i);
                    assert(V.find(vh) != V.end());
                    const int vid = V[vh];
                    faces(face_count, i) = vid;
                }
            }
            face_count++;
        }
        assert(face_count == num_faces);

        size_t voxel_count = 0;
        for(auto cit = c3t3.cells_in_complex_begin() ;
                cit != c3t3.cells_in_complex_end(); ++cit ) {
            assert(voxel_count < num_voxels);
            for (int i=0; i<4; i++) {
                assert(V.find(cit->vertex(i)) != V.end());
                const size_t vid = V[cit->vertex(i)];
                voxels(voxel_count, i) = vid;
            }
            voxel_count++;
        }
        assert(voxel_count == num_voxels);
    }