Ejemplo n.º 1
0
void setup_vertex_uv_buffer_object(void) {
	glGenBuffers(1, &vertex_uv_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_uv_buffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * trig.UVs().size(),
		         &trig.UVs()[0], GL_STATIC_DRAW);
}
Ejemplo n.º 2
0
Archivo: IO.cpp Proyecto: alexrj/Slic3r
bool
OBJ::write(const TriangleMesh& mesh, std::string output_file)
{
    mesh.WriteOBJFile(output_file);
    return true;
}
Ejemplo n.º 3
0
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroids[numObjects] = SimdVector3(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroids[numObjects] += vertex0;
							centroids[numObjects]+= vertex1;
							centroids[numObjects]+= vertex2;
							
						}
					}

					centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroids[numObjects];
							vertex1 -= centroids[numObjects];
							vertex2 -= centroids[numObjects];

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					shapeIndex[numObjects] = numObjects;
					shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
					
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}
void
makeBallScene()
{
	g_camera = new Camera;
	g_scene = new Scene;
	g_image = new Image;


	g_image->resize(512, 512);

	Material* lambert = new Lambert(Vector3(1.0f,0.5f,0.0f));
	Material* lambert_ground = new Lambert(Vector3(0.9f,0.9f,0.9f));
	Material* mirror = new Mirror(Vector3(0.6f));
	Material* glass = new Glass(Vector3(0.95f),1.5f);
	Material* brdf = new BPhong(Vector3(0.4f),Vector3(0.6f),200);

	// set up the camera
	g_camera->setBGColor(Vector3(0.0f, 0.0f, 0.0f));
	g_camera->setEye(Vector3( 10, 3, 10));
	g_camera->setLookAt(Vector3(0, 0, 0));
	g_camera->setUp(Vector3(0, 1, 0));
	g_camera->setFOV(45);

	// create and place a point light source
	PointLight * light = new PointLight;
	light->setPosition(Vector3(5, 15, 5));
	light->setColor(Vector3(1, 1, 1));
	light->setWattage(4.0 * PI * 700);

	g_scene->addLight(light);

	// create the floor triangle
	TriangleMesh * floor = new TriangleMesh;
	floor->createSingleTriangle();
	floor->setV1(Vector3(-100, 0, -100));
	floor->setV2(Vector3(0, 0, 100));
	floor->setV3(Vector3(100, 0, 0));
	floor->setN1(Vector3(0, 1, 0));
	floor->setN2(Vector3(0, 1, 0));
	floor->setN3(Vector3(0, 1, 0));


	TriangleMesh * right = new TriangleMesh;
	right->createSingleTriangle();
	right->setV1(Vector3(10, 0, -10));
	right->setV2(Vector3(0, 100, 0));
	right->setV3(Vector3(-10, 0, 10));
	right->setN1(Vector3(1, 0, 1));
	right->setN2(Vector3(1, 0, 1));
	right->setN3(Vector3(1, 0, 1));

	TriangleMesh * left = new TriangleMesh;
	left->createSingleTriangle();
	left->setV1(Vector3(0, 0, 0));
	left->setV2(Vector3(100, 0, 0));
	left->setV3(Vector3(0, 100, 0));
	left->setN1(Vector3(0, 0, 1));
	left->setN2(Vector3(0, 0, 1));
	left->setN3(Vector3(0, 0, 1));

	Triangle* t = new Triangle;
	t->setIndex(0);
	t->setMesh(floor);
	t->setMaterial(lambert_ground);

	Triangle* t2 = new Triangle;
	t2->setIndex(0);
	t2->setMesh(right);
	t2->setMaterial(lambert_ground);

	Triangle* t3 = new Triangle;
	t3->setIndex(0);
	t3->setMesh(left);
	t3->setMaterial(lambert_ground);
	

	g_scene->addObject(t);
	g_scene->addObject(t2);
	//g_scene->addObject(t3);

	//create two balls
	Sphere * sphere1 = new Sphere;
	sphere1->setCenter(Vector3(0.5, 1, 1));
	sphere1->setRadius(0.2);
	sphere1->setMaterial(lambert);
	Sphere * sphere2 = new Sphere;
	sphere2->setCenter(Vector3(1, 1, 0.5));
	sphere2->setRadius(0.2);
	sphere2->setMaterial(lambert);

	Sphere * sphere3= new Sphere;
	sphere3->setCenter(Vector3(4, 1, 2));
	sphere3->setRadius(1);
	sphere3->setMaterial(glass);

	Sphere * sphere4 = new Sphere;
	sphere4->setCenter(Vector3(2, 1, 4));
	sphere4->setRadius(1);
	sphere4->setMaterial(brdf);

	g_scene->addObject(sphere1);
	g_scene->addObject(sphere2);
	g_scene->addObject(sphere3);
	g_scene->addObject(sphere4);

	g_scene->preCalc();
}
void
makeTeapotScene()
{
	g_camera = new Camera;
	g_scene = new Scene;
	g_image = new Image;

	g_image->resize(512, 512);

	// set up the camera
	g_camera->setBGColor(Vector3(0.0f, 0.0f, 0.2f));
	g_camera->setEye(Vector3(0, 6, 2));
	g_camera->setLookAt(Vector3(0, 0, 0));
	g_camera->setUp(Vector3(0, 1, 0));
	g_camera->setFOV(45);

	// create and place a point light source
	PointLight * light = new PointLight;
	light->setPosition(Vector3(-2.5, 10, -2.5));
	light->setColor(Vector3(1, 1, 1));
	light->setWattage(4.0 * PI * 700);
	
	PointLight * light1 = new PointLight;
	light1->setPosition(Vector3(10, 15, 10));
	light1->setColor(Vector3(1, 1, 1));
	light1->setWattage(4.0 * PI * 700);
	
	g_scene->addLight(light);
	//g_scene->addLight(light1); //for test shadow

	Material* lambert = new Lambert(Vector3(1.0f));
	Material* mirror = new Mirror(Vector3(0.8f));
	Material* glass = new Glass(Vector3(0.95f), 1.5f);
	Material* brdf = new BPhong(Vector3(0.4f,0.4f,0.0f), Vector3(0.6f,0.6f,0.0f), 50);

	TriangleMesh * teapot = new TriangleMesh;
	Matrix4x4 xform;

	teapot->load("teapot.obj");
	addMeshTrianglesToScene(teapot, brdf);

	xform.setIdentity();
	xform *= translate(-5, 0, 0);
	teapot = new TriangleMesh;
	teapot->load("teapot.obj",xform);
	addMeshTrianglesToScene(teapot, lambert);

	xform.setIdentity();
	xform *= translate(-5, 0, -5);
	teapot = new TriangleMesh;
	teapot->load("teapot.obj", xform);
	addMeshTrianglesToScene(teapot, mirror);



	// create the floor triangle
	TriangleMesh * floor = new TriangleMesh;
	floor->createSingleTriangle();
	floor->setV1(Vector3(-100, 0, -100));
	floor->setV2(Vector3(  0, 0,  100));
	floor->setV3(Vector3( 100, 0, -100));
	floor->setN1(Vector3(0, 1, 0));
	floor->setN2(Vector3(0, 1, 0));
	floor->setN3(Vector3(0, 1, 0));
    
	Triangle* t = new Triangle;
	t->setIndex(0);
	t->setMesh(floor);
	t->setMaterial(lambert); 
	g_scene->addObject(t);




	// let objects do pre-calculations if needed
	g_scene->preCalc();
}
void
makeBunny20Scene()
{
	g_camera = new Camera;
	g_scene = new Scene;
	g_image = new Image;

	g_image->resize(512, 512);

	// set up the camera
	g_camera->setBGColor(Vector3(0.0f, 0.0f, 0.2f));
	g_camera->setEye(Vector3(0, 5, 15));
	g_camera->setLookAt(Vector3(0, 0, 0));
	g_camera->setUp(Vector3(0, 1, 0));
	g_camera->setFOV(45);

	// create and place a point light source
	PointLight * light = new PointLight;
	light->setPosition(Vector3(10, 20, 10));
	light->setColor(Vector3(1, 1, 1));
	light->setWattage(4.0 * PI * 1000);
	g_scene->addLight(light);

	TriangleMesh * mesh;
	Material* material = new Lambert(Vector3(1.0f));
	Matrix4x4 xform;
	Matrix4x4 xform2;
	xform2 *= rotate(110, 0, 1, 0);
	xform2 *= scale(.6, 1, 1.1);


	// bunny 1
	xform.setIdentity();
	xform *= scale(0.3, 2.0, 0.7);
	xform *= translate(-1, .4, .3);
	xform *= rotate(25, .3, .1, .6);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 2
	xform.setIdentity();
	xform *= scale(.6, 1.2, .9);
	xform *= translate(7.6, .8, .6);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 3
	xform.setIdentity();
	xform *= translate(.7, 0, -2);
	xform *= rotate(120, 0, .6, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 4
	xform.setIdentity();
	xform *= translate(3.6, 3, -1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 5
	xform.setIdentity();
	xform *= translate(-2.4, 2, 3);
	xform *= scale(1, .8, 2);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 6
	xform.setIdentity();
	xform *= translate(5.5, -.5, 1);
	xform *= scale(1, 2, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 7
	xform.setIdentity();
	xform *= rotate(15, 0, 0, 1);
	xform *= translate(-4, -.5, -6);
	xform *= scale(1, 2, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 8
	xform.setIdentity();
	xform *= rotate(60, 0, 1, 0);
	xform *= translate(5, .1, 3);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 9
	xform.setIdentity();
	xform *= translate(-3, .4, 6);
	xform *= rotate(-30, 0, 1, 0);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 10
	xform.setIdentity();
	xform *= translate(3, 0.5, -2);
	xform *= rotate(180, 0, 1, 0);
	xform *= scale(1.5, 1.5, 1.5);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 11
	xform = xform2;
	xform *= scale(0.3, 2.0, 0.7);
	xform *= translate(-1, .4, .3);
	xform *= rotate(25, .3, .1, .6);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 12
	xform = xform2;
	xform *= scale(.6, 1.2, .9);
	xform *= translate(7.6, .8, .6);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 13
	xform = xform2;
	xform *= translate(.7, 0, -2);
	xform *= rotate(120, 0, .6, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 14
	xform = xform2;
	xform *= translate(3.6, 3, -1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 15
	xform = xform2;
	xform *= translate(-2.4, 2, 3);
	xform *= scale(1, .8, 2);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 16
	xform = xform2;
	xform *= translate(5.5, -.5, 1);
	xform *= scale(1, 2, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 17
	xform = xform2;
	xform *= rotate(15, 0, 0, 1);
	xform *= translate(-4, -.5, -6);
	xform *= scale(1, 2, 1);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 18
	xform = xform2;
	xform *= rotate(60, 0, 1, 0);
	xform *= translate(5, .1, 3);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 19
	xform = xform2;
	xform *= translate(-3, .4, 6);
	xform *= rotate(-30, 0, 1, 0);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);

	// bunny 20
	xform = xform2;
	xform *= translate(3, 0.5, -2);
	xform *= rotate(180, 0, 1, 0);
	xform *= scale(1.5, 1.5, 1.5);
	mesh = new TriangleMesh;
	mesh->load("bunny.obj", xform);
	addMeshTrianglesToScene(mesh, material);


	// create the floor triangle
	mesh = new TriangleMesh;
	mesh->createSingleTriangle();
	mesh->setV1(Vector3(-100, 0, -100));
	mesh->setV2(Vector3(   0, 0,  100));
	mesh->setV3(Vector3( 100, 0, -100));
	mesh->setN1(Vector3(0, 1, 0));
	mesh->setN2(Vector3(0, 1, 0));
	mesh->setN3(Vector3(0, 1, 0));
    
	Triangle* t = new Triangle;
	t->setIndex(0);
	t->setMesh(mesh);
	t->setMaterial(material); 
	g_scene->addObject(t);
    
	// let objects do pre-calculations if needed
	g_scene->preCalc();
}
Ejemplo n.º 7
0
int main(int argc, const char * argv[])
{

  Electrostatics e;

  TriangleMesh *teststl = new TriangleMesh();
  teststl->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere5120.stl", MeshFileFormat::MFF_STL);
  teststl->write("/Users/phaedon/github/bem-laplace-simple/meshes/sphere5120.obj", MeshFileFormat::MFF_OBJ);
  
  TriangleMesh *s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h0cm_s3.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h10cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);

  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h30cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h50cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h80cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h90cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h95cm.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  
  s = new TriangleMesh();
  s->read("/Users/phaedon/github/bem-laplace-simple/meshes/sphere_5mm_h995mm_s3.obj", MeshFileFormat::MFF_OBJ);
  e.addBubble(s);
  
  TriangleMesh *plane = new TriangleMesh();
  plane->read("/Users/phaedon/github/bem-laplace-simple/meshes/plane_h1_s50mm_t128.obj", MeshFileFormat::MFF_OBJ);

  e.setSurface(plane);
  std::vector<double> caps;
  e.capacitance(caps);
  for (size_t i = 0; i < caps.size(); i++) {
    std::cout << "capacitance of " << i << "th bubble: " << caps[i] << std::endl;
  }
  
  std::cout << "Finished!" << std::endl;
  
  return 0;
}
void GenerateBezierPatch(const BezierPatchDescriptor& desc, TriangleMesh& mesh)
{
    auto idxOffset = mesh.vertices.size();

    const auto segsHorz = std::max(1u, desc.segments.x);
    const auto segsVert = std::max(1u, desc.segments.y);

    const auto invHorz  = Gs::Real(1) / static_cast<Gs::Real>(segsHorz);
    const auto invVert  = Gs::Real(1) / static_cast<Gs::Real>(segsVert);

    auto AddQuad = [&](unsigned int u, unsigned int v, VertexIndex i0, VertexIndex i1, VertexIndex i2, VertexIndex i3)
    {
        if (desc.backFacing)
            AddTriangulatedQuad(mesh, desc.alternateGrid, u, v, i1, i0, i3, i2, idxOffset);
        else
            AddTriangulatedQuad(mesh, desc.alternateGrid, u, v, i0, i1, i2, i3, idxOffset);
    };

    /* Generate vertices */
    static const Gs::Real delta = Gs::Real(0.01);

    Gs::Vector3 coord, normal;
    Gs::Vector2 texCoord;

    for (unsigned int i = 0; i <= segsVert; ++i)
    {
        for (unsigned int j = 0; j <= segsHorz; ++j)
        {
            /* Compute coordinate and texture-coordinate */
            texCoord.x = static_cast<Gs::Real>(j) * invHorz;
            texCoord.y = static_cast<Gs::Real>(i) * invVert;

            coord = desc.bezierPatch(texCoord.x, texCoord.y);
            
            /* Sample bezier patch to approximate normal */
            auto uOffset = (desc.bezierPatch(texCoord.x + delta, texCoord.y) - coord);
            auto vOffset = (desc.bezierPatch(texCoord.x, texCoord.y + delta) - coord);
            normal = Gs::Cross(uOffset, vOffset).Normalized();

            /* Add vertex */
            if (!desc.backFacing)
            {
                texCoord.y = Gs::Real(1) - texCoord.y;
                normal = -normal;
            }

            mesh.AddVertex(coord, normal, texCoord);
        }
    }

    /* Generate indices */
    const auto strideHorz = segsHorz + 1;

    for (unsigned int v = 0; v < segsVert; ++v)
    {
        for (unsigned int u = 0; u < segsHorz; ++u)
        {
            AddQuad(
                u, v,
                (  v   *strideHorz + u   ),
                ( (v+1)*strideHorz + u   ),
                ( (v+1)*strideHorz + u+1 ),
                (  v   *strideHorz + u+1 )
            );
        }
    }
}
Ejemplo n.º 9
0
/** Additional initialisation after loading of the model is finished.
 */
void PhysicalObject::init()
{
    // 1. Determine size of the object
    // -------------------------------
    Vec3 min, max;

    TrackObjectPresentationSceneNode* presentation =
        m_object->getPresentation<TrackObjectPresentationSceneNode>();

    if (presentation->getNode()->getType() == scene::ESNT_ANIMATED_MESH)
    {
        scene::IAnimatedMesh *mesh
            = ((scene::IAnimatedMeshSceneNode*)presentation->getNode())->getMesh();

        MeshTools::minMax3D(mesh, &min, &max);
    }
    else if (presentation->getNode()->getType()==scene::ESNT_MESH)
    {
        scene::IMesh *mesh
            = ((scene::IMeshSceneNode*)presentation->getNode())->getMesh();

        MeshTools::minMax3D(mesh, &min, &max);
    }
    else if (presentation->getNode()->getType()==scene::ESNT_LOD_NODE)
    {
        scene::ISceneNode* node =
            ((LODNode*)presentation->getNode())->getAllNodes()[0];
        if (node->getType() == scene::ESNT_ANIMATED_MESH)
        {
            scene::IAnimatedMesh *mesh
                = ((scene::IAnimatedMeshSceneNode*)node)->getMesh();

            MeshTools::minMax3D(mesh, &min, &max);
        }
        else if (node->getType()==scene::ESNT_MESH)
        {
            scene::IMesh *mesh
                = ((scene::IMeshSceneNode*)node)->getMesh();

            MeshTools::minMax3D(mesh, &min, &max);
        }
        else
        {
            Log::fatal("PhysicalObject", "Unknown node type");
        }
    }
    else if (dynamic_cast<TrackObjectPresentationInstancing*>(presentation) != NULL)
    {
        TrackObjectPresentationInstancing* instancing = dynamic_cast<TrackObjectPresentationInstancing*>(presentation);
        STKInstancedSceneNode* instancing_group = instancing->getInstancingGroup();
        if (instancing_group != NULL)
        {
            scene::IMesh* mesh = instancing_group->getMesh();
            MeshTools::minMax3D(mesh, &min, &max);
        }
    }
    else
    {
        Log::fatal("PhysicalObject", "Unknown node type");
    }
    Vec3 extend = max-min;
    // Adjust the mesth of the graphical object so that its center is where it
    // is in bullet (usually at (0,0,0)). It can be changed in the case clause
    // if this is not correct for a particular shape.
    m_graphical_offset = -0.5f*(max+min);
    switch (m_body_type)
    {
    case MP_CONE_Y:
    {
        if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
        m_shape = new btConeShape(m_radius, extend.getY());
        break;
    }
    case MP_CONE_X:
    {
        if (m_radius < 0)
            m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
                                 extend.getZ()*extend.getZ());
        m_shape = new btConeShapeX(m_radius, extend.getY());
        break;
    }
    case MP_CONE_Z:
    {
        if (m_radius < 0)
            m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
                                 extend.getY()*extend.getY());
        m_shape = new btConeShapeZ(m_radius, extend.getY());
        break;
    }
    case MP_CYLINDER_Y:
    {
        if (m_radius < 0) m_radius = 0.5f*extend.length_2d();
        m_shape = new btCylinderShape(0.5f*extend);
        break;
    }
    case MP_CYLINDER_X:
    {
        if (m_radius < 0)
            m_radius = 0.5f*sqrt(extend.getY()*extend.getY() +
                                 extend.getZ()*extend.getZ());
        m_shape = new btCylinderShapeX(0.5f*extend);
        break;
    }
    case MP_CYLINDER_Z:
    {
        if (m_radius < 0)
            m_radius = 0.5f*sqrt(extend.getX()*extend.getX() +
                                 extend.getY()*extend.getY());
        m_shape = new btCylinderShapeZ(0.5f*extend);
        break;
    }
    case MP_SPHERE:
    {
        if(m_radius<0)
        {
            m_radius =      std::max(extend.getX(), extend.getY());
            m_radius = 0.5f*std::max(m_radius,      extend.getZ());
        }
        m_shape = new btSphereShape(m_radius);
        break;
    }
    case MP_EXACT:
    {
        TriangleMesh* triangle_mesh = new TriangleMesh();

        // In case of readonly materials we have to get the material from
        // the mesh, otherwise from the node. This is esp. important for
        // water nodes, which only have the material defined in the node,
        // but not in the mesh at all!
        bool is_readonly_material = false;

        scene::IMesh* mesh = NULL;
        switch (presentation->getNode()->getType())
        {
            case scene::ESNT_MESH          :
            case scene::ESNT_WATER_SURFACE :
            case scene::ESNT_OCTREE        :
                {
                    scene::IMeshSceneNode *node =
                        (scene::IMeshSceneNode*)presentation->getNode();
                    mesh = node->getMesh();
                    is_readonly_material = node->isReadOnlyMaterials();
                    break;
                }
            case scene::ESNT_ANIMATED_MESH :
                {
                    // for now just use frame 0
                    scene::IAnimatedMeshSceneNode *node =
                      (scene::IAnimatedMeshSceneNode*)presentation->getNode();
                    mesh = node->getMesh()->getMesh(0);
                    is_readonly_material = node->isReadOnlyMaterials();
                    break;
                }
            default:
                Log::warn("PhysicalObject", "Unknown object type, "
                                        "cannot create exact collision body!");
                return;
        }   // switch node->getType()

        for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
        {
            scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
            // FIXME: take translation/rotation into account
            if (mb->getVertexType() != video::EVT_STANDARD &&
                mb->getVertexType() != video::EVT_2TCOORDS)
            {
                Log::warn("PhysicalObject",
                          "createPhysicsBody: Ignoring type '%d'!",
                          mb->getVertexType());
                continue;
            }

            // Handle readonly materials correctly: mb->getMaterial can return
            // NULL if the node is not using readonly materials. E.g. in case
            // of a water scene node, the mesh (which is the animated copy of
            // the original mesh) does not contain any material information,
            // the material is only available in the node.
            const video::SMaterial &irrMaterial =
                is_readonly_material ? mb->getMaterial()
                : presentation->getNode()->getMaterial(i);
            video::ITexture* t=irrMaterial.getTexture(0);

            const Material* material=0;
            TriangleMesh *tmesh = triangle_mesh;
            if(t)
            {
                std::string image =
                              std::string(core::stringc(t->getName()).c_str());
                material = material_manager
                         ->getMaterial(StringUtils::getBasename(image));
                if(material->isIgnore())
                    continue;
            }

            u16 *mbIndices = mb->getIndices();
            Vec3 vertices[3];
            Vec3 normals[3];

            if (mb->getVertexType() == video::EVT_STANDARD)
            {
                irr::video::S3DVertex* mbVertices =
                                          (video::S3DVertex*)mb->getVertices();
                for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
                {
                    for(unsigned int k=0; k<3; k++)
                    {
                        int indx=mbIndices[j+k];
                        core::vector3df v = mbVertices[indx].Pos;
                        //mat.transformVect(v);
                        vertices[k]=v;
                        normals[k]=mbVertices[indx].Normal;
                    }   // for k
                    if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
                                                 vertices[2], normals[0],
                                                 normals[1],  normals[2],
                                                 material                 );
                }   // for j
            }
            else
            {
                if (mb->getVertexType() == video::EVT_2TCOORDS)
                {
                    irr::video::S3DVertex2TCoords* mbVertices =
                        (video::S3DVertex2TCoords*)mb->getVertices();
                    for(unsigned int j=0; j<mb->getIndexCount(); j+=3)
                    {
                        for(unsigned int k=0; k<3; k++)
                        {
                            int indx=mbIndices[j+k];
                            core::vector3df v = mbVertices[indx].Pos;
                            //mat.transformVect(v);
                            vertices[k]=v;
                            normals[k]=mbVertices[indx].Normal;
                        }   // for k
                        if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
                                                     vertices[2], normals[0],
                                                     normals[1],  normals[2],
                                                     material                 );
                    }   // for j

                }
            }

        }   // for i<getMeshBufferCount
        triangle_mesh->createCollisionShape();
        m_shape = &triangle_mesh->getCollisionShape();
        m_triangle_mesh = triangle_mesh;

        break;
    }
    case MP_NONE:
    default:
        Log::warn("PhysicalObject", "Uninitialised moving shape");
        // intended fall-through
    case MP_BOX:
    {
        m_shape = new btBoxShape(0.5*extend);
        break;
    }
    }

    // 2. Create the rigid object
    // --------------------------
    // m_init_pos is the point on the track - add the offset
    m_init_pos.setOrigin(m_init_pos.getOrigin() +
                         btVector3(0,extend.getY()*0.5f, 0));
    m_motion_state = new btDefaultMotionState(m_init_pos);
    btVector3 inertia;
    if (m_body_type != MP_EXACT)
        m_shape->calculateLocalInertia(m_mass, inertia);
    btRigidBody::btRigidBodyConstructionInfo info(m_mass, m_motion_state,
                                                  m_shape, inertia);

    // Make sure that the cones stop rolling by defining angular friction != 0.
    info.m_angularDamping = 0.5f;
    m_body = new btRigidBody(info);
    m_user_pointer.set(this);
    m_body->setUserPointer(&m_user_pointer);

    if (!m_is_dynamic)
    {
        m_body->setCollisionFlags(   m_body->getCollisionFlags()
                                   | btCollisionObject::CF_KINEMATIC_OBJECT);
        m_body->setActivationState(DISABLE_DEACTIVATION);
    }

    World::getWorld()->getPhysics()->addBody(m_body);

}   // init
Ejemplo n.º 10
0
int main(int argc,char** argv)
{

	int i;
	for (i=0;i<numObjects;i++)
	{
		if (i>0)
		{
			shapePtr[i] = prebuildShapePtr[1];
			shapeIndex[i] = 1;//sphere
		}
		else
		{
			shapeIndex[i] = 0;
			shapePtr[i] = prebuildShapePtr[0];
		}
	}
	
	ConvexDecomposition::WavefrontObj wo;
	char* filename = "file.obj";
	tcount = wo.loadObj(filename);

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{
		public:

		MyConvexDecomposition (FILE* outputFile)
			:mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile)

		{
		}
		
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroids[numObjects] = SimdVector3(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroids[numObjects] += vertex0;
							centroids[numObjects]+= vertex1;
							centroids[numObjects]+= vertex2;
							
						}
					}

					centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroids[numObjects];
							vertex1 -= centroids[numObjects];
							vertex2 -= centroids[numObjects];

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					shapeIndex[numObjects] = numObjects;
					shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
					
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
  			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		numObjects = 1; //always have the ground object first
		
		TriangleMesh* trimesh = new TriangleMesh();

		SimdVector3 localScaling(6.f,6.f,6.f);
		
		for (int i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			SimdVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			SimdVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			SimdVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->AddTriangle(vertex0,vertex1,vertex2);
		}

		shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
	}
			

	if (tcount)
	{

		char outputFileName[512];
  		strcpy(outputFileName,filename);
  		char *dot = strstr(outputFileName,".");
  		if ( dot ) 
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
  		FILE* outputFile = fopen(outputFileName,"wb");
				
		unsigned int depth = 7;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.01;

		printf("WavefrontObj num triangles read %i",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       =	wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile);
		desc.mCallback = &convexDecomposition;
		
		

		//convexDecomposition.performConvexDecomposition(desc);

		ConvexBuilder cb(desc.mCallback);
		int ret = cb.process(desc);
		
		if (outputFile)
			fclose(outputFile);


	}

	CollisionDispatcher* dispatcher = new	CollisionDispatcher();


	SimdVector3 worldAabbMin(-10000,-10000,-10000);
	SimdVector3 worldAabbMax(10000,10000,10000);

	OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax);
	//OverlappingPairCache* broadphase = new SimpleBroadphase();

	physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
	physicsEnvironmentPtr->setDeactivationTime(2.f);

	physicsEnvironmentPtr->setGravity(0,-10,0);
	PHY_ShapeProps shapeProps;

	shapeProps.m_do_anisotropic = false;
	shapeProps.m_do_fh = false;
	shapeProps.m_do_rot_fh = false;
	shapeProps.m_friction_scaling[0] = 1.;
	shapeProps.m_friction_scaling[1] = 1.;
	shapeProps.m_friction_scaling[2] = 1.;

	shapeProps.m_inertia = 1.f;
	shapeProps.m_lin_drag = 0.2f;
	shapeProps.m_ang_drag = 0.1f;
	shapeProps.m_mass = 10.0f;

	PHY_MaterialProps materialProps;
	materialProps.m_friction = 10.5f;
	materialProps.m_restitution = 0.0f;

	CcdConstructionInfo ccdObjectCi;
	ccdObjectCi.m_friction = 0.5f;

	ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag;
	ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag;

	SimdTransform tr;
	tr.setIdentity();



	for (i=0;i<numObjects;i++)
	{
		shapeProps.m_shape = shapePtr[shapeIndex[i]];
		shapeProps.m_shape->SetMargin(0.05f);



		bool isDyna = i>0;
		//if (i==1)
		//	isDyna=false;

		if (0)//i==1)
		{
			SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI);
			ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
		}


		if (i>0)
		{

			switch (i)
			{
			case 1:
				{
					ms[i].setWorldPosition(0,10,0);
					//for testing, rotate the ground cube so the stack has to recover a bit

					break;
				}
			case 2:
				{
					ms[i].setWorldPosition(0,8,2);
					break;
				}
			default:
				ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0);
			}

			float quatIma0,quatIma1,quatIma2,quatReal;
			SimdQuaternion quat;
			SimdVector3 axis(0,0,1);
			SimdScalar angle=0.5f;

			quat.setRotation(axis,angle);

			ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]);



		} else
		{
			ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0);

		}

		ccdObjectCi.m_MotionState = &ms[i];
		ccdObjectCi.m_gravity = SimdVector3(0,0,0);
		ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0);
		if (!isDyna)
		{
			shapeProps.m_mass = 0.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
			ccdObjectCi.m_collisionFlags = CollisionObject::isStatic;
		}
		else
		{
			shapeProps.m_mass = 1.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
			ccdObjectCi.m_collisionFlags = 0;
		}


		SimdVector3 localInertia;
		if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE)
		{
			//take inertia from first shape
			shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		} else
		{
			shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		}
		ccdObjectCi.m_localInertiaTensor = localInertia;

		ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]];


		physObjects[i]= new CcdPhysicsController( ccdObjectCi);

		// Only do CCD if  motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS
		physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS;
		
		//Experimental: better estimation of CCD Time of Impact:
		//physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS;

		physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]);

		if (i==1)
		{
			//physObjects[i]->SetAngularVelocity(0,0,-2,true);
		}

		physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);

	}


	//create a constraint
	if (createConstraint)
	{
		//physObjects[i]->SetAngularVelocity(0,0,-2,true);
		int constraintId;

		float pivotX=CUBE_HALF_EXTENTS,
			pivotY=-CUBE_HALF_EXTENTS,
			pivotZ=CUBE_HALF_EXTENTS;

		float axisX=1,axisY=0,axisZ=0;



		HingeConstraint* hinge = 0;

		SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS);
		SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS);
		SimdVector3 axisInA(0,1,0);
		SimdVector3 axisInB(0,-1,0);

		RigidBody* rb0 = physObjects[1]->GetRigidBody();
		RigidBody* rb1 = physObjects[2]->GetRigidBody();

		hinge = new HingeConstraint(
			*rb0,
			*rb1,pivotInA,pivotInB,axisInA,axisInB);

		physicsEnvironmentPtr->m_constraints.push_back(hinge);

		hinge->SetUserConstraintId(100);
		hinge->SetUserConstraintType(PHY_LINEHINGE_CONSTRAINT);

	}




	clientResetScene();

	setCameraDistance(26.f);

	return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/");
}
void CorrespondTemplates::computeMappings(char * outfileMappingTet, char * outfileMappingSurf, g_Node * contactPoint)
{
	//Compute the mappings using barycentric coordinates
	findSurfaceNodes();
	maptet2surfID = surfaceNodes;
	// output tetmesh surface
	computeSurface( "tet_mesh_surf.wrl" );
	deformVolumetricMeshRigidly();

	int i, j, k, numNodesTet, numElemsTet, numNodesSurf, numElemsSurf;
	double dist, minDist, d, mind, distContactPoint, minDistContactPoint;
	numNodesTet = volumetricMeshNodes.numberOfItems();
	numElemsTet = trianglesOnSurface.size();
	numNodesSurf = rigidlyAlignedSurfaceTemplate->getNumberOfNodes();
	numElemsSurf = rigidlyAlignedSurfaceTemplate->getNumberOfTriangles();

	//First compute the mapping from the tetrahedral mesh to the surface mesh
	mappingIndicesTet.resize(3*numNodesTet);
	mappingWeightsTet.resize(3*numNodesTet);
	offsetsTet.resize(numNodesTet);

	for(i = 0; i < numNodesTet; i++)
	{
		if(surfaceNodes[i] == -1)
		{
			mappingIndicesTet[3*i] = mappingIndicesTet[3*i+1] = mappingIndicesTet[3*i+2] = -1;
			mappingWeightsTet[3*i] = mappingWeightsTet[3*i+1] = mappingWeightsTet[3*i+2] = -1;
		}
		else
		{
			for(j = 0; j < numElemsSurf; j++)
			{
			  // g_Vector closestPoint = computeClosestPoint(volumetricMeshNodes[i], rigidlyAlignedSurfaceTemplate->elements()[j]);
			  // dist = closestPoint.DistanceTo(volumetricMeshNodes[i]->coordinate());
		          g_Vector closestPoint;
			  dist = computeClosestPoint(*volumetricMeshNodes[i], *rigidlyAlignedSurfaceTemplate->elements()[j], closestPoint );
			  dist = sqrt(dist);

				if((j == 0) || (dist < minDist))
				{
					minDist = dist;
					
					mappingIndicesTet[3*i] = rigidlyAlignedSurfaceTemplate->elements()[j]->nodes()[0]->id()-1;
					mappingIndicesTet[3*i+1] = rigidlyAlignedSurfaceTemplate->elements()[j]->nodes()[1]->id()-1;
					mappingIndicesTet[3*i+2] = rigidlyAlignedSurfaceTemplate->elements()[j]->nodes()[2]->id()-1;

					//----------------------
					for(int n = 0; n < 3; n++){
						d = volumetricMeshNodes[i]->coordinate().DistanceTo(rigidlyAlignedSurfaceTemplate->elements()[j]->nodes()[n]->coordinate());
						if((n == 0) || (d < mind)){
							mind = d;
							maptet2surfID[i] = rigidlyAlignedSurfaceTemplate->elements()[j]->nodes()[n]->id()-1;
						}
					}
					//------------------------

					vector<double> barycentrics = computeBarycentrics(volumetricMeshNodes[i]->coordinate(), closestPoint, rigidlyAlignedSurfaceTemplate->elements()[j]);
					mappingWeightsTet[3*i] = barycentrics[0];
					mappingWeightsTet[3*i+1] = barycentrics[1];
					mappingWeightsTet[3*i+2] = barycentrics[2];
					offsetsTet[i] = barycentrics[3];
				}
			}
		}
	}

	//Export
	if(outfileMappingTet != NULL)
	{
#if 0
		FILE * fp = fopen(outfileMappingTet, "w");
		if(fp == NULL)
		{
			cout<<"Problem writing "<<outfileMappingTet<<endl;
			return;
		}
		for(i = 0; i < numNodesTet; i++)
			fprintf(fp, "%d %d %d %f %f %f %f\n", mappingIndicesTet[3*i], mappingIndicesTet[3*i+1], mappingIndicesTet[3*i+2], 
				mappingWeightsTet[3*i], mappingWeightsTet[3*i+1], mappingWeightsTet[3*i+2], offsetsTet[i]);
		fclose(fp);
#else
		// Make a surface mesh using the tetmesh surface plus the coordinates from the surface mesh
		computeSurface( outfileMappingTet, true );
#endif
	}

	//Second compute the mapping from the surface mesh to the tetrahedral mesh
	mappingIndicesSurf.resize(3*numNodesSurf);
	mappingWeightsSurf.resize(3*numNodesSurf);
	offsetsSurf.resize(numNodesSurf);
	contactTriangleId.resize(3);
	contactWeights.resize(3);
	contactoffset.resize(1);

	for(i = 0; i < numNodesSurf; i++)
	{
		for(j = 0; j < numElemsTet; j++)
		{
			g_Element elem;
			set<int>::iterator triangleIt;
			for(triangleIt = trianglesOnSurface[j].begin(); triangleIt != trianglesOnSurface[j].end(); triangleIt++)
				elem.node(volumetricMeshNodes[*triangleIt]);

			// g_Vector closestPoint = computeClosestPoint(rigidlyAlignedSurfaceTemplate->nodes()[i], &elem);
			// dist = closestPoint.DistanceTo(rigidlyAlignedSurfaceTemplate->nodes()[i]->coordinate());
		        g_Vector closestPoint;
		        dist = computeClosestPoint(*rigidlyAlignedSurfaceTemplate->nodes()[i], elem, closestPoint );
			dist = sqrt(dist);

			if((j == 0) || (dist < minDist))
			{
				minDist = dist;

				k = 0;
				for(triangleIt = trianglesOnSurface[j].begin(); triangleIt != trianglesOnSurface[j].end(); triangleIt++, k++)
					mappingIndicesSurf[3*i+k] = *triangleIt;

				vector<double> barycentrics = computeBarycentrics(rigidlyAlignedSurfaceTemplate->nodes()[i]->coordinate(), closestPoint, &elem);
				mappingWeightsSurf[3*i] = barycentrics[0];
				mappingWeightsSurf[3*i+1] = barycentrics[1];
				mappingWeightsSurf[3*i+2] = barycentrics[2];
				offsetsSurf[i] = barycentrics[3];
			}


			//---------------------------
			if(i == 0 && contactPoint != NULL){
			        g_Vector closestContactPoint;
				distContactPoint = computeClosestPoint(*contactPoint, elem, closestContactPoint );
				distContactPoint = sqrt(distContactPoint);
				// g_Vector closestContactPoint = computeClosestPoint(contactPoint, &elem);
				// distContactPoint = closestContactPoint.DistanceTo(contactPoint->coordinate());
				if((j == 0) || (distContactPoint < minDistContactPoint))
				{
					minDistContactPoint = distContactPoint;

					k = 0;
					for(triangleIt = trianglesOnSurface[j].begin(); triangleIt != trianglesOnSurface[j].end(); triangleIt++, k++)
						contactTriangleId[3*i+k] = *triangleIt;

					vector<double> barycentricsContactPoint = computeBarycentrics(contactPoint->coordinate(), closestContactPoint, &elem);
					contactWeights[3*i] = barycentricsContactPoint[0];
					contactWeights[3*i+1] = barycentricsContactPoint[1];
					contactWeights[3*i+2] = barycentricsContactPoint[2];
					contactoffset[i] = barycentricsContactPoint[3];
				}
			}
			//----------------------------
		}
	}

	//Export
	if(outfileMappingSurf != NULL)
	{
#if 0 
		FILE * fp = fopen(outfileMappingSurf, "w");
		if(fp == NULL)
		{
			cout<<"Problem writing "<<outfileMappingSurf<<endl;
			return;
		}
		for(i = 0; i < numNodesSurf; i++)
			fprintf(fp, "%d %d %d %f %f %f %f\n", mappingIndicesSurf[3*i], mappingIndicesSurf[3*i+1], mappingIndicesSurf[3*i+2], 
				mappingWeightsSurf[3*i], mappingWeightsSurf[3*i+1], mappingWeightsSurf[3*i+2], offsetsSurf[i]);
		fclose(fp);
#else
		// Make a surface mesh using the tetmesh surface plus the coordinates from the surface mesh
		TriangleMesh surfTet;
		for (int i=0; i<numNodesSurf; ++i ) {
		  // std::cerr << i << " " << std::endl;
		  g_Vector coord =  mappingWeightsSurf[3*i] * volumetricMeshNodes[mappingIndicesSurf[3*i]]->coordinate();
		  coord += mappingWeightsSurf[3*i+1] * volumetricMeshNodes[mappingIndicesSurf[3*i+1]]->coordinate(); 
		  coord += mappingWeightsSurf[3*i+2] * volumetricMeshNodes[mappingIndicesSurf[3*i+2]]->coordinate();
		  surfTet.node(new g_Node( coord ));
		}
		// std::cerr << std::endl;
		g_ElementContainer eleSurf = rigidlyAlignedSurfaceTemplate->elements();
		g_NodeContainer newNodes = surfTet.nodes();
		for ( g_ElementContainer::const_iterator fIt=eleSurf.begin(); fIt != eleSurf.end(); ++fIt ) {
		  g_Element *ele = new g_Element(); 
		  g_NodeContainer faceNodes = (*fIt)->nodes(); 
		  for ( g_NodeContainer::const_iterator nIt = faceNodes.begin(); 
			nIt != faceNodes.end(); ++nIt ) {
		    ele->node(newNodes[(*nIt)->id()-1]);
		  }
		  surfTet.element(ele);
		}
		exportMeshWrapper( outfileMappingSurf, &surfTet ); 
#endif


	}
}
TriangleMesh * CorrespondTemplates::computeSurface(char * exportFilename, bool useMapping)
{
	int i, j, counter, numTetNodes;
	TriangleMesh * resultMesh = new TriangleMesh();
	vector<int> surfaceIds;

	//Find the surface:
	findSurfaceNodes();

	numTetNodes = volumetricMeshNodes.numberOfItems();
	surfaceIds.resize(numTetNodes);

	g_NodeContainer nodesSurf;
	if ( useMapping ) 
	   nodesSurf = rigidlyAlignedSurfaceTemplate->nodes();

	//Add the nodes:
	counter = 0;
	for(i = 0; i < numTetNodes; i++)
	{
		if(surfaceNodes[i] == -1) 
			surfaceIds[i] = -1;
		else 
		{
			surfaceIds[i] = counter;
			counter++;

			g_Vector coord;
			if ( useMapping ) {
			  coord =  mappingWeightsTet[3*i] * nodesSurf[mappingIndicesTet[3*i]]->coordinate(); 
			  coord += mappingWeightsTet[3*i+1] * nodesSurf[mappingIndicesTet[3*i+1]]->coordinate(); 
			  coord += mappingWeightsTet[3*i+2] * nodesSurf[mappingIndicesTet[3*i+2]]->coordinate();
			} else {
			  coord = volumetricMeshNodes[i]->coordinate();
			}
			g_Node * newNode = new g_Node(coord); 
			resultMesh->node(newNode);
		}
	}

	//Add the triangles (find the correct orientation):
	for(i = 0; i < trianglesOnSurface.size(); i++)
	{
		g_Element * elem = new g_Element();
	
		for(j = 0; j < allTetrahedra.size(); j++)
		{
			set<int> triangle; triangle.insert(allTetrahedra[j][0]); triangle.insert(allTetrahedra[j][1]); triangle.insert(allTetrahedra[j][2]);
			if(trianglesOnSurface[i] == triangle)
			{
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][0]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][2]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][1]]]);
				break;
			}
			triangle.clear(); triangle.insert(allTetrahedra[j][0]); triangle.insert(allTetrahedra[j][1]); triangle.insert(allTetrahedra[j][3]);
			if(trianglesOnSurface[i] == triangle)
			{
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][0]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][1]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][3]]]);
				break;
			}
			triangle.clear(); triangle.insert(allTetrahedra[j][0]); triangle.insert(allTetrahedra[j][2]); triangle.insert(allTetrahedra[j][3]);
			if(trianglesOnSurface[i] == triangle)
			{
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][0]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][3]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][2]]]);
				break;
			}
			triangle.clear(); triangle.insert(allTetrahedra[j][1]); triangle.insert(allTetrahedra[j][2]); triangle.insert(allTetrahedra[j][3]);
			if(trianglesOnSurface[i] == triangle)
			{
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][1]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][2]]]);
				elem->node(resultMesh->nodes()[surfaceIds[allTetrahedra[j][3]]]);
				break;
			}
		}

		resultMesh->element(elem);
	}

	//Export:
	if(exportFilename != NULL)
	{
		exportMeshWrapper(exportFilename, resultMesh);
	}

	return resultMesh;
}
Ejemplo n.º 13
0
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroid += vertex0;
							centroid += vertex1;
							centroid += vertex2;
							
						}
					}

					centroid *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					bool isDynamic = true;
					float mass = 1.f;
					CollisionShape* convexShape = new ConvexTriangleMeshShape(trimesh);
					SimdTransform trans;
					trans.setIdentity();
					trans.setOrigin(centroid);
					m_convexDemo->LocalCreatePhysicsObject(isDynamic, mass, trans,convexShape);

					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}
Ejemplo n.º 14
0
void ConvexDecompositionDemo::initPhysics(const char* filename)
{
	ConvexDecomposition::WavefrontObj wo;

	tcount = wo.loadObj(filename);

	CollisionDispatcher* dispatcher = new	CollisionDispatcher();


	SimdVector3 worldAabbMin(-10000,-10000,-10000);
	SimdVector3 worldAabbMax(10000,10000,10000);

	OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax);
	//OverlappingPairCache* broadphase = new SimpleBroadphase();

	m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
	m_physicsEnvironmentPtr->setDeactivationTime(2.f);

	m_physicsEnvironmentPtr->setGravity(0,-10,0);

	SimdTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(SimdVector3(0,-4,0));

	LocalCreatePhysicsObject(false,0,startTransform,new BoxShape(SimdVector3(30,2,30)));

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{

		ConvexDecompositionDemo*	m_convexDemo;
		public:

		MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo)
			:m_convexDemo(demo),
				mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile)

		{
		}
		
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroid += vertex0;
							centroid += vertex1;
							centroid += vertex2;
							
						}
					}

					centroid *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					bool isDynamic = true;
					float mass = 1.f;
					CollisionShape* convexShape = new ConvexTriangleMeshShape(trimesh);
					SimdTransform trans;
					trans.setIdentity();
					trans.setOrigin(centroid);
					m_convexDemo->LocalCreatePhysicsObject(isDynamic, mass, trans,convexShape);

					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
  			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		TriangleMesh* trimesh = new TriangleMesh();

		SimdVector3 localScaling(6.f,6.f,6.f);
		
		for (int i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			SimdVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			SimdVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			SimdVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->AddTriangle(vertex0,vertex1,vertex2);
		}

		CollisionShape* convexShape = new ConvexTriangleMeshShape(trimesh);
		bool isDynamic = true;
		float mass = 1.f;
		
		SimdTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(SimdVector3(20,2,0));

		LocalCreatePhysicsObject(isDynamic, mass, startTransform,convexShape);

	}
			

	if (tcount)
	{

		char outputFileName[512];
  		strcpy(outputFileName,filename);
  		char *dot = strstr(outputFileName,".");
  		if ( dot ) 
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
  		FILE* outputFile = fopen(outputFileName,"wb");
				
		unsigned int depth = 7;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.01;

		printf("WavefrontObj num triangles read %i",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       =	wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile,this);
		desc.mCallback = &convexDecomposition;
		
		

		//convexDecomposition.performConvexDecomposition(desc);

		ConvexBuilder cb(desc.mCallback);
		cb.process(desc);
		
		if (outputFile)
			fclose(outputFile);


	}


	m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);

}
Ejemplo n.º 15
0
//////////////////////////////////////////////////////////
//
// MeshSweeper implementation
// ===========
//
TriangleMesh*
MeshSweeper::makeCylinder(
  const Polyline& circle,
  const vec3& path,
  const mat4& m)
//[]----------------------------------------------------[]
//|  Make cylinder                                       |
//[]----------------------------------------------------[]
{
  int np = circle.getNumberOfVertices();
  int nv = np * 2; // number of vertices
  int nb = np - 2; // number of triangles of the base
  int nt = nv + 2 * nb; // number of triangles
  TriangleMesh::Arrays data;

  data.vertices = new vec3[data.numberOfVertices = nv];
  data.triangles = new TriangleMesh::Triangle[data.numberOfTriangles = nt];

  vec3 c(0, 0, 0);

  if (true)
  {
    Polyline::VertexIterator vit(circle.getVertexIterator());

    for (int i = 0; i < np; i++)
    {
      const vec3& p = vit++.position;

      c += p;
      data.vertices[i + np] = m.transform3x4(p);
      data.vertices[i] = m.transform3x4(p + path);
    }
    c *= Math::inverse(REAL(np));
  }

  TriangleMesh::Triangle* triangle = data.triangles;

  for (int i = 0; i < np; i++)
  {
    int j = (i + np);
    int k = (i + 1) % np;

    triangle->setVertices(i, j, k);
    triangle[1].setVertices(j, k + np, k);
    triangle += 2;
  }

  int v0 = 0;
  int v1 = 1;
  int v2 = 2;

  for (int i = 0; i < nb; i++)
  {
    triangle->setVertices(v0, v1, v2);
    triangle[nb].setVertices(v0 + np, v2 + np, v1 + np);
    triangle++;
    v2 = ((v1 = (v0 = v2) + 1) + 1) % np;
  }

  TriangleMesh* mesh = new TriangleMesh(data);

  mesh->computeNormals();
  return mesh;
}
Ejemplo n.º 16
0
int
main(const int argc, const char **argv)
{
    // parse all command line options into a DynamicConfig
    ConfigDef config_def;
    config_def.merge(cli_config_def);
    config_def.merge(print_config_def);
    DynamicConfig config(&config_def);
    t_config_option_keys input_files;
    config.read_cli(argc, argv, &input_files);
    
    // apply command line options to a more handy CLIConfig
    CLIConfig cli_config;
    cli_config.apply(config, true);
    
    DynamicPrintConfig print_config;
    
    // load config files supplied via --load
    for (std::vector<std::string>::const_iterator file = cli_config.load.values.begin();
        file != cli_config.load.values.end(); ++file) {
        if (!boost::filesystem::exists(*file)) {
            std::cout << "No such file: " << *file << std::endl;
            exit(1);
        }
        
        DynamicPrintConfig c;
        try {
            c.load(*file);
        } catch (std::exception &e) {
            std::cout << "Error while reading config file: " << e.what() << std::endl;
            exit(1);
        }
        c.normalize();
        print_config.apply(c);
    }
    
    // apply command line options to a more specific DynamicPrintConfig which provides normalize()
    // (command line options override --load files)
    print_config.apply(config, true);
    print_config.normalize();
    
    // write config if requested
    if (!cli_config.save.value.empty()) print_config.save(cli_config.save.value);
    
    // read input file(s) if any
    std::vector<Model> models;
    for (t_config_option_keys::const_iterator it = input_files.begin(); it != input_files.end(); ++it) {
        if (!boost::filesystem::exists(*it)) {
            std::cout << "No such file: " << *it << std::endl;
            exit(1);
        }
        
        Model model;
        // TODO: read other file formats with Model::read_from_file()
        try {
            Slic3r::IO::STL::read(*it, &model);
        } catch (std::exception &e) {
            std::cout << *it << ": " << e.what() << std::endl;
            exit(1);
        }
        
        if (model.objects.empty()) {
            printf("Error: file is empty: %s\n", it->c_str());
            continue;
        }
        
        model.add_default_instances();
        
        // apply command line transform options
        for (ModelObjectPtrs::iterator o = model.objects.begin(); o != model.objects.end(); ++o) {
            if (cli_config.scale_to_fit.is_positive_volume())
                (*o)->scale_to_fit(cli_config.scale_to_fit.value);
            
            (*o)->scale(cli_config.scale.value);
            (*o)->rotate(cli_config.rotate.value, Z);
        }
        
        // TODO: handle --merge
        models.push_back(model);
    }
    
    for (std::vector<Model>::iterator model = models.begin(); model != models.end(); ++model) {
        if (cli_config.info) {
            // --info works on unrepaired model
            model->print_info();
        } else if (cli_config.export_obj) {
            std::string outfile = cli_config.output.value;
            if (outfile.empty()) outfile = model->objects.front()->input_file + ".obj";
    
            TriangleMesh mesh = model->mesh();
            mesh.repair();
            Slic3r::IO::OBJ::write(mesh, outfile);
            printf("File exported to %s\n", outfile.c_str());
        } else if (cli_config.export_pov) {
            std::string outfile = cli_config.output.value;
            if (outfile.empty()) outfile = model->objects.front()->input_file + ".pov";
    
            TriangleMesh mesh = model->mesh();
            mesh.repair();
            Slic3r::IO::POV::write(mesh, outfile);
            printf("File exported to %s\n", outfile.c_str());
        } else if (cli_config.export_svg) {
            std::string outfile = cli_config.output.value;
            if (outfile.empty()) outfile = model->objects.front()->input_file + ".svg";
            
            SLAPrint print(&*model);
            print.config.apply(print_config, true);
            print.slice();
            print.write_svg(outfile);
            printf("SVG file exported to %s\n", outfile.c_str());
        } else {
            std::cerr << "error: only --export-svg and --export-obj are currently supported" << std::endl;
            return 1;
        }
    }
    
    return 0;
}
Ejemplo n.º 17
0
//-----------------------------------------------------------------------------
//  BoundaryMap private method definitions
//-----------------------------------------------------------------------------
void BoundaryMap::computeSignedDistanceField(SparseVoxelMap<float*>& map, 
        const TriangleMesh& mesh)
{
    const float* vertexList = mesh.getVertexList();
    const unsigned int* faceList = mesh.getFaceList();
    const float *v1, *v2, *v3;
    unsigned int cMin[3];
    unsigned int cMax[3];
    float x0 = mDomain.getV1().getX();
    float y0 = mDomain.getV1().getY();
    float z0 = mDomain.getV1().getZ();
    float x[3];
    float normal[3];
    float dist;

    //
    // compute distance
    //

    // for each triangle of the mesh
    for (unsigned int m = 0; m < mesh.getNumFaces(); m++) 
    {
        std::cout << m << " of " << mesh.getNumFaces() << std::endl;

        //get triangle vertices
        v1 = &vertexList[3*faceList[3*m + 0]];
        v2 = &vertexList[3*faceList[3*m + 1]];
        v3 = &vertexList[3*faceList[3*m + 2]];

        // compute bounding box of the triangle
        this->computeGridCoordinates(cMin, cMax, v1, v2, v3);

        //std::cout << "cMin[0] = " << cMin[0] << std::endl;
        //std::cout << "cMin[1] = " << cMin[1] << std::endl;
        //std::cout << "cMin[2] = " << cMin[2] << std::endl;
        //std::cout << "cMax[0] = " << cMax[0] << std::endl;
        //std::cout << "cMax[1] = " << cMax[1] << std::endl;
        //std::cout << "cMax[2] = " << cMax[2] << std::endl;

        // for each coordinate within the bounding box
        for (unsigned int k = cMin[2]; k <= cMax[2]; k++) 
        {
            for (unsigned int j = cMin[1]; j <= cMax[1]; j++) 
            {
                for (unsigned int i = cMin[0]; i <= cMax[0]; i++) 
                {
                    // translate coordinate to world coordinates
                    x[0] = x0 + i*mDx;
                    x[1] = y0 + j*mDx;
                    x[2] = z0 + k*mDx;

                    // compute distance to the triangle
                    compute_distance_point_triangle(dist, normal, x, v1, v2, v3);

                    // update sparse voxel map
                    if (dist <= mMaxDist)
                    {
                        Coordinate coord(i, j, k);

                        // if the map already contains distance information
                        // at the current coordinate
                        if (map.contains(coord)) 
                        {
                            // check if the previously computed distance is
                            // is greater than [dist].
                            float prev;
                            float* nodeContent;
                            map.get(nodeContent, coord);
                            prev = nodeContent[NC_DISTANCE];
                            if (prev > dist)
                            {
                                // if yes, update the map
                                delete[] nodeContent;
                                nodeContent = new float[NC_NUM_ELEMENTS];
                                nodeContent[NC_DISTANCE] = dist;
                                nodeContent[NC_NORMAL_X] = normal[0];
                                nodeContent[NC_NORMAL_Y] = normal[1];
                                nodeContent[NC_NORMAL_Z] = normal[2];
                                map.add(coord, nodeContent);
                            }
                        }
                        // if not yet contained in the map
                        else
                        {
                            float* nodeContent = new float[NC_NUM_ELEMENTS];
                            nodeContent[NC_DISTANCE] = dist;
                            nodeContent[NC_NORMAL_X] = normal[0];
                            nodeContent[NC_NORMAL_Y] = normal[1];
                            nodeContent[NC_NORMAL_Z] = normal[2];
                            //std::cout << dist << std::endl;
                            // just add val to the map
                            map.add(coord, nodeContent);
                        }
                    }
                }
            }
        }
    }

    //
    // compute sign of distance
    //
    std::cout << "point in mesh test" << std::endl;
    PointInMeshTest test(mesh, 20);
    
    // for each coordinate in the signed distance field
    std::list<Coordinate>::const_iterator& it = mNodeContents.begin();
    std::list<Coordinate>::const_iterator& end = mNodeContents.end();
    Coordinate c;

    for (; it != end; it++)
    { 
        // translate coordinate to world coordinate
        c = *it;
        x[0] = x0 + c.i*mDx;
        x[1] = y0 + c.j*mDx;
        x[2] = z0 + c.k*mDx;
        
        // if [x] is inside the mesh
        if (test.isContained(Vector3f(x[0], x[1], x[2])))
        {
            // negate the distances in the signed distance field
            float* nodeContent;
            mNodeContents.get(nodeContent, c);
            nodeContent[NC_DISTANCE] = -nodeContent[NC_DISTANCE]; 
        }
    }
    
    std::cout << "point in mesh test finished" << std::endl;
}
Ejemplo n.º 18
0
void simplifyMesh(TriangleMesh &src, TriangleMesh &dst){
	namespace SMS = CGAL::Surface_mesh_simplification; 

	Surface surface;
  PolyhedronBuilder<HalfedgeDS> builder(src.points, src.facets);
	surface.delegate(builder);


	// --- before mesh simplification, to maintain mesh quality high poisson surface reconstruction is applied ---


	// This is a stop predicate (defines when the algorithm terminates).
	// In this example, the simplification stops when the number of undirected edges
	// left in the surface drops below the specified number (1000) 
	// SMS::Count_stop_predicate<Surface> stop(3000);
   //SMS::Count_ratio_stop_predicate<Surface> stop(0.1);
	SMS::Count_stop_predicate<Surface> stop(100);	
  // This the actual call to the simplification algorithm.
  // The surface and stop conditions are mandatory arguments. 
  // The index maps are needed because the vertices and edges 
  // of this surface lack an "id()" field.
  int r = SMS::edge_collapse
             (surface
             ,stop
             ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index, surface))
             .edge_index_map(boost::get(CGAL::edge_external_index, surface))
             .get_cost(CGAL::Surface_mesh_simplification::Edge_length_cost<Polyhedron>())
             .get_placement(CGAL::Surface_mesh_simplification::Midpoint_placement<Polyhedron>())
             //.get_cost(CGAL::Surface_mesh_simplification::LindstromTurk_cost<Polyhedron>())            
             //.get_placement(CGAL::Surface_mesh_simplification::LindstromTurk_placement<Polyhedron>())
             );
  std::cout << "\nFinished...\n" << r << " edges removed.\n"
           << (surface.size_of_halfedges()/2) << " final edges.\n" ;

	std::vector<Eigen::Vector3d> points;
	std::vector<std::vector<int> > faces;
	points.resize(surface.size_of_vertices());
	faces.resize(surface.size_of_facets());

	Polyhedron::Point_iterator pit;
	int index = 0;
	for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){
		points[index][0] = pit->x();
		points[index][1] = pit->y();
		points[index][2] = pit->z();				
		index ++;
	}
	index = 0;
	Polyhedron::Face_iterator fit;
	for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){
		std::vector<int > face(3);
		Halfedge_facet_circulator j = fit->facet_begin();
		int f_index = 0;
		do {
			face[f_index] = std::distance(surface.vertices_begin(), j->vertex());
			f_index++;
    } while ( ++j != fit->facet_begin());    

    faces[index] = face;
		index++;
	}

	dst.createFromFaceVertex(points, faces);
}
Ejemplo n.º 19
0
void setup_vertex_position_buffer_object(void) {
	glGenBuffers(1, &vertex_position_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_position_buffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * trig.VertexCount(),
		         &trig.Vertices()[0], GL_STATIC_DRAW);
}
Ejemplo n.º 20
0
void
SLAPrint::slice()
{
    TriangleMesh mesh = this->model->mesh();
    mesh.repair();
    
    // align to origin taking raft into account
    this->bb = mesh.bounding_box();
    if (this->config.raft_layers > 0) {
        this->bb.min.x -= this->config.raft_offset.value;
        this->bb.min.y -= this->config.raft_offset.value;
        this->bb.max.x += this->config.raft_offset.value;
        this->bb.max.y += this->config.raft_offset.value;
    }
    mesh.translate(0, 0, -bb.min.z);
    this->bb.translate(0, 0, -bb.min.z);
    
    // if we are generating a raft, first_layer_height will not affect mesh slicing
    const float lh       = this->config.layer_height.value;
    const float first_lh = this->config.first_layer_height.value;
    
    // generate the list of Z coordinates for mesh slicing
    // (we slice each layer at half of its thickness)
    this->layers.clear();
    {
        const float first_slice_lh = (this->config.raft_layers > 0) ? lh : first_lh;
        this->layers.push_back(Layer(first_slice_lh/2, first_slice_lh));
    }
    while (this->layers.back().print_z + lh/2 <= mesh.stl.stats.max.z) {
        this->layers.push_back(Layer(this->layers.back().print_z + lh/2, this->layers.back().print_z + lh));
    }
    
    // perform slicing and generate layers
    {
        std::vector<float> slice_z;
        for (size_t i = 0; i < this->layers.size(); ++i)
            slice_z.push_back(this->layers[i].slice_z);
        
        std::vector<ExPolygons> slices;
        TriangleMeshSlicer(&mesh).slice(slice_z, &slices);
        
        for (size_t i = 0; i < slices.size(); ++i)
            this->layers[i].slices.expolygons = slices[i];
    }
    
    // generate infill
    if (this->config.fill_density < 100) {
        std::auto_ptr<Fill> fill(Fill::new_from_type(this->config.fill_pattern.value));
        fill->bounding_box.merge(Point::new_scale(bb.min.x, bb.min.y));
        fill->bounding_box.merge(Point::new_scale(bb.max.x, bb.max.y));
        fill->spacing       = this->config.get_abs_value("infill_extrusion_width", this->config.layer_height.value);
        fill->angle         = Geometry::deg2rad(this->config.fill_angle.value);
        fill->density       = this->config.fill_density.value/100;
        
        parallelize<size_t>(
            0,
            this->layers.size()-1,
            boost::bind(&SLAPrint::_infill_layer, this, _1, fill.get()),
            this->config.threads.value
        );
    }
    
    // generate support material
    this->sm_pillars.clear();
    ExPolygons overhangs;
    if (this->config.support_material) {
        // flatten and merge all the overhangs
        {
            Polygons pp;
            for (std::vector<Layer>::const_iterator it = this->layers.begin()+1; it != this->layers.end(); ++it)
                pp += diff(it->slices, (it - 1)->slices);
            overhangs = union_ex(pp);
        }
        
        // generate points following the shape of each island
        Points pillars_pos;
        const coordf_t spacing = scale_(this->config.support_material_spacing);
        const coordf_t radius  = scale_(this->sm_pillars_radius());
        for (ExPolygons::const_iterator it = overhangs.begin(); it != overhangs.end(); ++it) {
            // leave a radius/2 gap between pillars and contour to prevent lateral adhesion
            for (float inset = radius * 1.5;; inset += spacing) {
                // inset according to the configured spacing
                Polygons curr = offset(*it, -inset);
                if (curr.empty()) break;
                
                // generate points along the contours
                for (Polygons::const_iterator pg = curr.begin(); pg != curr.end(); ++pg) {
                    Points pp = pg->equally_spaced_points(spacing);
                    for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
                        pillars_pos.push_back(*p);
                }
            }
        }
        
        // for each pillar, check which layers it applies to
        for (Points::const_iterator p = pillars_pos.begin(); p != pillars_pos.end(); ++p) {
            SupportPillar pillar(*p);
            bool object_hit = false;
            
            // check layers top-down
            for (int i = this->layers.size()-1; i >= 0; --i) {
                // check whether point is void in this layer
                if (!this->layers[i].slices.contains(*p)) {
                    // no slice contains the point, so it's in the void
                    if (pillar.top_layer > 0) {
                        // we have a pillar, so extend it
                        pillar.bottom_layer = i + this->config.raft_layers;
                    } else if (object_hit) {
                        // we don't have a pillar and we're below the object, so create one
                        pillar.top_layer = i + this->config.raft_layers;
                    }
                } else {
                    if (pillar.top_layer > 0) {
                        // we have a pillar which is not needed anymore, so store it and initialize a new potential pillar
                        this->sm_pillars.push_back(pillar);
                        pillar = SupportPillar(*p);
                    }
                    object_hit = true;
                }
            }
            if (pillar.top_layer > 0) this->sm_pillars.push_back(pillar);
        }
    }
    
    // generate a solid raft if requested
    // (do this after support material because we take support material shape into account)
    if (this->config.raft_layers > 0) {
        ExPolygons raft = this->layers.front().slices + overhangs;  // take support material into account
        raft = offset_ex(raft, scale_(this->config.raft_offset));
        for (int i = this->config.raft_layers; i >= 1; --i) {
            this->layers.insert(this->layers.begin(), Layer(0, first_lh + lh * (i-1)));
            this->layers.front().slices = raft;
        }
        
        // prepend total raft height to all sliced layers
        for (size_t i = this->config.raft_layers; i < this->layers.size(); ++i)
            this->layers[i].print_z += first_lh + lh * (this->config.raft_layers-1);
    }
}
Ejemplo n.º 21
0
int main(int argc,char** argv)
{

	setCameraDistance(30.f);

#define TRISIZE 10.f
#ifdef DEBUG_MESH
	SimdVector3 vert0(-TRISIZE ,0,TRISIZE );
	SimdVector3 vert1(TRISIZE ,10,TRISIZE );
	SimdVector3 vert2(TRISIZE ,0,-TRISIZE );
	meshData.AddTriangle(vert0,vert1,vert2);
	SimdVector3 vert3(-TRISIZE ,0,TRISIZE );
	SimdVector3 vert4(TRISIZE ,0,-TRISIZE );
	SimdVector3 vert5(-TRISIZE ,0,-TRISIZE );
	meshData.AddTriangle(vert3,vert4,vert5);
#else
#ifdef ODE_MESH
	SimdVector3 Size = SimdVector3(15.f,15.f,12.5f);
	
  gVertices[0][0] = -Size[0];
  gVertices[0][1] = Size[2];
  gVertices[0][2] = -Size[1];
  
  gVertices[1][0] = Size[0];
  gVertices[1][1] = Size[2];
  gVertices[1][2] = -Size[1];
  
  gVertices[2][0] = Size[0];
  gVertices[2][1] = Size[2];
  gVertices[2][2] = Size[1];  

  gVertices[3][0] = -Size[0];
  gVertices[3][1] = Size[2];
  gVertices[3][2] = Size[1];
  
  gVertices[4][0] = 0;
  gVertices[4][1] = 0;
  gVertices[4][2] = 0;
  
  gIndices[0] = 0;
  gIndices[1] = 1;
  gIndices[2] = 4;
  
  gIndices[3] = 1;
  gIndices[4] = 2;
  gIndices[5] = 4;
  
  gIndices[6] = 2;
  gIndices[7] = 3;
  gIndices[8] = 4;
  
  gIndices[9] = 3;
  gIndices[10] = 0;
  gIndices[11] = 4;

  int vertStride = sizeof(SimdVector3);
  int indexStride = 3*sizeof(int);

	TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(NUM_TRIANGLES,
		gIndices,
		indexStride,
		NUM_VERTICES,(float*) &gVertices[0].x(),vertStride);

	//shapePtr[4] = new TriangleMeshShape(indexVertexArrays);
	shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays);
#else

	int vertStride = sizeof(SimdVector3);
	int indexStride = 3*sizeof(int);

	const int NUM_VERTS_X = 50;
	const int NUM_VERTS_Y = 50;
	const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y;
	
	const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1);

	SimdVector3*	gVertices = new SimdVector3[totalVerts];
	int*	gIndices = new int[totalTriangles*3];

	int i;

	for ( i=0;i<NUM_VERTS_X;i++)
	{
		for (int j=0;j<NUM_VERTS_Y;j++)
		{
			gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*10.f,2.f*sinf((float)i)*cosf((float)j),(j-NUM_VERTS_Y*0.5f)*10.f);
		}
	}

	int index=0;
	for ( i=0;i<NUM_VERTS_X-1;i++)
	{
		for (int j=0;j<NUM_VERTS_Y-1;j++)
		{
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = j*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;

			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
		}
	}
	
	TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(totalTriangles,
		gIndices,
		indexStride,
		totalVerts,(float*) &gVertices[0].x(),vertStride);

	//shapePtr[4] = new TriangleMeshShape(indexVertexArrays);
	shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays);
#endif

	

#endif//DEBUG_MESH


//	GLDebugDrawer	debugDrawer;

	//ConstraintSolver* solver = new SimpleConstraintSolver;
	ConstraintSolver* solver = new OdeConstraintSolver;

	CollisionDispatcher* dispatcher = new	CollisionDispatcher();
		
	BroadphaseInterface* broadphase = new SimpleBroadphase();


	physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
	

	physicsEnvironmentPtr->setGravity(-1,-10,1);
	PHY_ShapeProps shapeProps;
	
	shapeProps.m_do_anisotropic = false;
	shapeProps.m_do_fh = false;
	shapeProps.m_do_rot_fh = false;
	shapeProps.m_friction_scaling[0] = 1.;
	shapeProps.m_friction_scaling[1] = 1.;
	shapeProps.m_friction_scaling[2] = 1.;

	shapeProps.m_inertia = 1.f;
	shapeProps.m_lin_drag = 0.95999998f;
	shapeProps.m_ang_drag = 0.89999998f;
	shapeProps.m_mass = 1.0f;
	
	PHY_MaterialProps materialProps;
	materialProps.m_friction = 0.f;// 50.5f;
	materialProps.m_restitution = 0.1f;

	CcdConstructionInfo ccdObjectCi;
	ccdObjectCi.m_friction = 0.f;//50.5f;

	ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag;
	ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag;

	SimdTransform tr;
	tr.setIdentity();

	
	for (i=0;i<numObjects;i++)
	{
		if (i>0)
			shapeIndex[i] = 1;//2 = tetrahedron
		else
			shapeIndex[i] = 4;
	}
	for (i=0;i<numObjects;i++)
	{
		shapeProps.m_shape = shapePtr[shapeIndex[i]];

		bool isDyna = i>0;
		
		if (!i)
		{
			//SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI);
			//ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
			//ms[i].setWorldPosition(0,-10,0);
		} else
		{
				ms[i].setWorldPosition(10,i*15-10,0);
		}
		
//either create a few stacks, to show several islands, or create 1 large stack, showing stability
		//ms[i].setWorldPosition((i*5) % 30,i*15-10,0);
		

		ccdObjectCi.m_MotionState = &ms[i];
		ccdObjectCi.m_gravity = SimdVector3(0,0,0);
		ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0);
		if (!isDyna)
		{
			shapeProps.m_mass = 0.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
		}
		else
		{
			shapeProps.m_mass = 1.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
		}

		
		SimdVector3 localInertia;
		if (shapeProps.m_mass>0.f)
		{
			shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		} else
		{
			localInertia.setValue(0.f,0.f,0.f);

		}
		ccdObjectCi.m_localInertiaTensor = localInertia;

		ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]];


		physObjects[i]= new CcdPhysicsController( ccdObjectCi);
		physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]);

/*		if (i==0)
		{
			physObjects[i]->SetAngularVelocity(0,0,-2,true);
			physObjects[i]->GetRigidBody()->setDamping(0,0);
		}
*/
		//for the line that represents the AABB extents
//	physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);

		
	}
	return glutmain(argc, argv,640,480,"Static Concave Mesh Demo");
}
Ejemplo n.º 22
0
    void SpatialSplit::Split::split<false>(size_t threadIndex, size_t threadCount, LockStepTaskScheduler* scheduler, PrimRefBlockAlloc<PrimRef>& alloc, 
					   Scene* scene, TriRefList& prims, 
					   TriRefList& lprims_o, PrimInfo& linfo_o, 
					   TriRefList& rprims_o, PrimInfo& rinfo_o) const
    {
      assert(valid());
      TriRefList::item* lblock = lprims_o.insert(alloc.malloc(threadIndex));
      TriRefList::item* rblock = rprims_o.insert(alloc.malloc(threadIndex));
      linfo_o.reset();
      rinfo_o.reset();
    
      /* sort each primitive to left, right, or left and right */
      while (atomic_set<PrimRefBlock>::item* block = prims.take()) 
      {
	for (size_t i=0; i<block->size(); i++) 
	{
	  const PrimRef& prim = block->at(i); 
	  const BBox3fa bounds = prim.bounds();
	  const int bin0 = mapping.bin(bounds.lower)[dim];
	  const int bin1 = mapping.bin(bounds.upper)[dim];

	  /* sort to the left side */
	  if (bin1 < pos)
	  {
	    linfo_o.add(bounds,center2(bounds));
	    if (likely(lblock->insert(prim))) continue; 
	    lblock = lprims_o.insert(alloc.malloc(threadIndex));
	    lblock->insert(prim);
	    continue;
	  }
	  
	  /* sort to the right side */
	  if (bin0 >= pos)
	  {
	    rinfo_o.add(bounds,center2(bounds));
	    if (likely(rblock->insert(prim))) continue;
	    rblock = rprims_o.insert(alloc.malloc(threadIndex));
	    rblock->insert(prim);
	    continue;
	  }
	  
	  /* split and sort to left and right */
	  TriangleMesh* mesh = (TriangleMesh*) scene->get(prim.geomID());
	  TriangleMesh::Triangle tri = mesh->triangle(prim.primID());
	  const Vec3fa v0 = mesh->vertex(tri.v[0]);
	  const Vec3fa v1 = mesh->vertex(tri.v[1]);
	  const Vec3fa v2 = mesh->vertex(tri.v[2]);
	  
	  PrimRef left,right;
	  float fpos = mapping.pos(pos,dim);
	  splitTriangle(prim,dim,fpos,v0,v1,v2,left,right);
	
	  if (!left.bounds().empty()) {
	    linfo_o.add(left.bounds(),center2(left.bounds()));
	    if (!lblock->insert(left)) {
	      lblock = lprims_o.insert(alloc.malloc(threadIndex));
	      lblock->insert(left);
	    }
	  }
	  
	  if (!right.bounds().empty()) {
	    rinfo_o.add(right.bounds(),center2(right.bounds()));
	    if (!rblock->insert(right)) {
	      rblock = rprims_o.insert(alloc.malloc(threadIndex));
	      rblock->insert(right);
	    }
	  }
	}
	alloc.free(threadIndex,block);
      }
    }
void PoissonSurfaceReconstruction::reconstruct(std::vector<Eigen::Vector3d> &points, std::vector<Eigen::Vector3d> &normals, TriangleMesh &mesh){

	assert(points.size() == normals.size());

  std::cout << "creating points with normal..." << std::endl;
  std::vector<Point_with_normal> points_with_normal;
  points_with_normal.resize((int)points.size());
  for(int i=0; i<(int)points.size(); i++){
    Vector vec(normals[i][0], normals[i][1], normals[i][2]);
    //Point_with_normal pwn(points[i][0], points[i][1], points[i][2], vec);
    //points_with_normal[i]  = pwn;
    points_with_normal[i] = Point_with_normal(points[i][0], points[i][1], points[i][2], vec);
  }

  std::cout << "constructing poisson reconstruction function..." << std::endl;
  Poisson_reconstruction_function function(points_with_normal.begin(), points_with_normal.end(),
                                           CGAL::make_normal_of_point_with_normal_pmap(PointList::value_type()));

  std::cout << "computing implicit function..." << std::endl;
  if( ! function.compute_implicit_function() ) {
  	std::cout << "compute implicit function is failure" << std::endl;
  	return;
  }
  	//return EXIT_FAILURE;

  // Computes average spacing
  std::cout << "compute average spacing..." << std::endl;
  FT average_spacing = CGAL::compute_average_spacing(points_with_normal.begin(), points_with_normal.end(),
                                                       6 /* knn = 1 ring */);
  // Gets one point inside the implicit surface
  // and computes implicit function bounding sphere radius.
  Point inner_point = function.get_inner_point();
  Sphere bsphere = function.bounding_sphere();
  FT radius = std::sqrt(bsphere.squared_radius());

  // Defines the implicit surface: requires defining a
  // conservative bounding sphere centered at inner point.
  FT sm_sphere_radius = 5.0 * radius;
  FT sm_dichotomy_error = distance_criteria*average_spacing/1000.0; // Dichotomy error must be << sm_distance
  //FT sm_dichotomy_error = distance_criteria*average_spacing/10.0; // Dichotomy error must be << sm_distance
  std::cout << "reconstructed surface" << std::endl;
  Surface_3 reconstructed_surface(function,
                    Sphere(inner_point,sm_sphere_radius*sm_sphere_radius),
                    sm_dichotomy_error/sm_sphere_radius);

  // Defines surface mesh generation criteria    
  CGAL::Surface_mesh_default_criteria_3<STr> criteria(angle_criteria,  // Min triangle angle (degrees)
                                                        radius_criteria*average_spacing,  // Max triangle size
                                                        distance_criteria*average_spacing); // Approximation error
  
  std::cout << "generating surface mesh..." << std::endl;
  // Generates surface mesh with manifold option
  STr tr; // 3D Delaunay triangulation for surface mesh generation
  C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation
  CGAL::make_surface_mesh(c2t3,                                 // reconstructed mesh
                            reconstructed_surface,                              // implicit surface
                            criteria,                             // meshing criteria
                            CGAL::Manifold_tag());  // require manifold mesh

  if(tr.number_of_vertices() == 0){
  	std::cout << "surface mesh generation is failed" << std::endl;
  	return;
  }

  Polyhedron surface;
  CGAL::output_surface_facets_to_polyhedron(c2t3, surface);

  // convert CGAL::surface to TriangleMesh //
  std::cout << "converting CGA::surface to TriangleMesh..." << std::endl;
	std::vector<Eigen::Vector3d> pts;
	std::vector<std::vector<int> > faces;
	pts.resize(surface.size_of_vertices());
	faces.resize(surface.size_of_facets());

	Polyhedron::Point_iterator pit;
	int index = 0;
	for(pit=surface.points_begin(); pit!=surface.points_end(); ++pit){
		pts[index][0] = pit->x();
		pts[index][1] = pit->y();
		pts[index][2] = pit->z();				
		index ++;
	}
	index = 0;
	Polyhedron::Face_iterator fit;
	for(fit=surface.facets_begin(); fit!=surface.facets_end(); ++fit){
		std::vector<int > face(3);
		Halfedge_facet_circulator j = fit->facet_begin();
		int f_index = 0;
		do {
			face[f_index] = std::distance(surface.vertices_begin(), j->vertex());
			f_index++;
    } while ( ++j != fit->facet_begin());    

    faces[index] = face;
		index++;
	}

	mesh.createFromFaceVertex(pts, faces);  
}
Ejemplo n.º 24
0
void display_handler(void) {
    // clear scene
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glColor3f(1,1,1);
	shader.Bind();

	// pass uniform variables to shader
	GLint projectionMatrix_location    = glGetUniformLocation(shader.ID(), "projectionMatrix");
	GLint viewMatrix_location          = glGetUniformLocation(shader.ID(), "viewMatrix");
	GLint modelMatrix_location         = glGetUniformLocation(shader.ID(), "modelMatrix");
	GLint normalMatrix_location        = glGetUniformLocation(shader.ID(), "normalMatrix");
	GLint materialAmbient_location     = glGetUniformLocation(shader.ID(), "materialAmbient");
	GLint materialDiffuse_location     = glGetUniformLocation(shader.ID(), "materialDiffuse");
	GLint materialSpecular_location    = glGetUniformLocation(shader.ID(), "materialSpecular");
	GLint lightPosition_location       = glGetUniformLocation(shader.ID(), "lightPosition");
	GLint lightAmbient_location        = glGetUniformLocation(shader.ID(), "lightAmbient");
	GLint lightDiffuse_location        = glGetUniformLocation(shader.ID(), "lightDiffuse");
	GLint lightSpecular_location       = glGetUniformLocation(shader.ID(), "lightSpecular");
	GLint lightGlobal_location         = glGetUniformLocation(shader.ID(), "lightGlobal");
	GLint materialShininess_location   = glGetUniformLocation(shader.ID(), "materialShininess");
	GLint constantAttenuation_location = glGetUniformLocation(shader.ID(), "constantAttenuation");
	GLint linearAttenuation_location   = glGetUniformLocation(shader.ID(), "linearAttenuation");
	GLint useTexture_location          = glGetUniformLocation(shader.ID(), "useTexture");
	glUniformMatrix4fv( projectionMatrix_location, 1, GL_FALSE, &projectionMatrix[0][0]);
	glUniformMatrix4fv( viewMatrix_location,       1, GL_FALSE, &viewMatrix[0][0]);
	glUniformMatrix4fv( modelMatrix_location,      1, GL_FALSE, &modelMatrix[0][0]);
	glUniformMatrix3fv( normalMatrix_location,     1, GL_FALSE, &normalMatrix[0][0]);
    glUniform3fv(       materialAmbient_location,  1, materialAmbient);
    glUniform3fv(       materialDiffuse_location,  1, materialDiffuse);
    glUniform3fv(       materialSpecular_location, 1, materialSpecular);
    glUniform3fv(       lightPosition_location,    1, lightPosition);
    glUniform3fv(       lightAmbient_location,     1, lightAmbient);
    glUniform3fv(       lightDiffuse_location,     1, lightDiffuse);
    glUniform3fv(       lightSpecular_location,    1, lightSpecular);
    glUniform3fv(       lightGlobal_location,      1, lightGlobal);
    glUniform1f(        materialShininess_location,   materialShininess);
    glUniform1f(        constantAttenuation_location, constantAttenuation);
    glUniform1f(        linearAttenuation_location,   linearAttenuation);
    glUniform1i(        useTexture_location,          useTexture);

    // bind texture to shader
    GLint texture0_location = glGetAttribLocation(shader.ID(), "texture0");
    if (texture0_location != -1) {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureID);
        glUniform1i(texture0_location, 0);
    }
    // bind vertex uv coordinates to shader
	GLint uv_location = glGetAttribLocation(shader.ID(), "vertex_uv");
	if (uv_location != -1) {
        glEnableVertexAttribArray(uv_location);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_uv_buffer);
        glVertexAttribPointer(uv_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
    }
    // bind vertex positions to shader
	GLint position_location = glGetAttribLocation(shader.ID(), "vertex_position");
	if (position_location != -1) {
        glEnableVertexAttribArray(position_location);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_position_buffer);
        glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
    }
    // bind vertex normals to shader
	GLint normal_location = glGetAttribLocation(shader.ID(), "vertex_normal");
	if (normal_location != -1) {
        glEnableVertexAttribArray(normal_location);
        glBindBuffer(GL_ARRAY_BUFFER, vertex_normal_buffer);
        glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
    }

    // draw the scene
	glDrawArrays(GL_TRIANGLES, 0, trig.VertexCount());
	glDisableVertexAttribArray(position_location);
	glDisableVertexAttribArray(uv_location);
	glDisableVertexAttribArray(normal_location);
	shader.Unbind();
	glFlush();
}
Ejemplo n.º 25
-1
int main(int argc, char **argv) {
	atexit(cleanup);
    // parse arguments
    char *model_path = NULL;
    char *vertexshader_path = NULL;
    char *fragmentshader_path = NULL;
    char *texture_path = NULL;
    bool use_smoothed_normals;
    if (argc >= 6) {
        texture_path = argv[5];
        useTexture = 1;
    }
	if (argc >= 5) {
        model_path = argv[1];
        vertexshader_path = argv[2];
        fragmentshader_path = argv[3];
        use_smoothed_normals = *argv[4] != '0';
	} else {
        std::cerr << "Usage:" << std::endl;
        std::cerr << argv[0]
             << " <model::path> "
             << " <vertex-shader::path> "
             << " <fragment-shader::path> "
             << " <smooth-normals::{0,1}>"
             << " (<texture::path>)"
             << std::endl;
		exit(1);
	}
	// initialise OpenGL
	glutInit(&argc, argv);
	glutInitWindowSize(windowX, windowY);
	glutCreateWindow("CG-CW1");
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glEnable(GL_DEPTH_TEST);
    // set display and keyboard callbacks
	glutDisplayFunc(display_handler);
    glutKeyboardFunc(keyboard_handler);
	// initialise the OpenGL Extension Wrangler library for VBOs
	GLenum err = glewInit();
	if (err != GLEW_OK){
        std::cerr << "Error!" << std::endl;
		exit(1);
	}
	if (!GLEW_VERSION_2_1) {
        std::cerr << "Error 2.1!" << std::endl;
		exit(1);
	}
	// create shader, prepare data for OpenGL
    trig.LoadFile(model_path);
	shader.Init(vertexshader_path, fragmentshader_path);
    setup_texture(texture_path, &textureID);
	setup_vertex_position_buffer_object();
	setup_vertex_uv_buffer_object();
    setup_vertex_normal_buffer_object(use_smoothed_normals);
	// set up camera and object transformation matrices
	projectionMatrix = get_default_projectionMatrix();
	viewMatrix = get_default_viewMatrix();
	modelMatrix = get_default_modelMatrix();
    normalMatrix = get_default_normalMatrix();
	glutMainLoop();
}