ObjMesh * ObjMeshOrientable::GenerateOrientedMesh()
{
  ObjMesh * outputObjMesh = new ObjMesh(*objMesh);

  for(unsigned int i=0; i < outputObjMesh->getNumGroups(); i++) // over all groups
  {
    ObjMesh::Group * groupHandle = (ObjMesh::Group*) outputObjMesh->getGroupHandle(i);
    for (unsigned int j=0; j < groupHandle->getNumFaces(); j++) // over all faces
    {
      const ObjMesh::Face * face = groupHandle->getFaceHandle(j);
      if (face->getNumVertices() < 3)
      {
        printf("Warning: encountered a face with fewer than 3 vertices.\n");
        continue;
      }

      HalfEdge edge = edgeAtFace(i, j);

      // loop until edge is first edge
      unsigned int startPosition = face->getVertex(0).getPositionIndex();
      while (edgeStartVertex(edge).getPositionIndex() != startPosition)
        edge = edgeNext(edge);

      // reverse the face if not correctly oriented
      if (edgeEndVertex(edge).getPositionIndex() != face->getVertex(1).getPositionIndex())
        groupHandle->reverseFace(j);
    }
  }

  return outputObjMesh;
}
Esempio n. 2
0
void World::SetupAnimalScene()
{
	// Create the objects in the scene
	NxSoftBodyDesc softBodyDesc;
	softBodyDesc.globalPose.t		= NxVec3(0.0f, 3.0f, 0.0f);
	softBodyDesc.particleRadius		= 0.2f;
	softBodyDesc.volumeStiffness	= 0.5f;
	softBodyDesc.stretchingStiffness= 1.0f;
	softBodyDesc.friction			= 1.0f;
	softBodyDesc.attachmentResponseCoefficient = 0.1f;
	softBodyDesc.solverIterations	= 5;

	char *fileName = "froggyNormalized";

	char tetFileName[256], objFileName[256], s[256];
	sprintf(tetFileName, "%s.tet", fileName);
	sprintf(objFileName, "%s.obj", fileName);

	ObjMesh *objMesh = new ObjMesh();
	objMesh->loadFromObjFile(FindMediaFile(objFileName, s));
	gObjMeshes.pushBack(objMesh);

	if(objMesh == NULL)
	{
		printf("objMesh %s\n");
	}

	NxMat33 rot;
	rot.rotX(NxHalfPiF32);

	for (int i = 0; i < 5; i++)
	{
		softBodyDesc.globalPose.t	= NxVec3(0, 3+i*3, 0);
		MySoftBody *softBody		= new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName, s), objMesh);
		assert(softBody);
		if (!softBody->getNxSoftBody())
		{
			printf("Error: unable to create the softbody for the current scene.\n");
			delete softBody;
		}
		else
		{
			gSoftBodies.pushBack(softBody);
			NxActor *caps = MyCreateCapsule(NxVec3(0.0f, 3.0f + i*3.0f, -0.3f), 1.0f, 0.73f, 1.0f);
			caps->userData = (void*)&gInvisible;
			caps->setGlobalOrientation(rot);
			softBody->getNxSoftBody()->attachToShape(caps->getShapes()[0], NX_SOFTBODY_ATTACHMENT_TWOWAY);
		}
	}
}
Esempio n. 3
0
void Mesh::loadOBJ(const std::string& filename)
{
    ObjMesh* pRawObjMesh = ObjMesh::LoadFromFile(filename);

    if (!pRawObjMesh)
    {
        std::cerr << "Mesh::loadObj: error loading file " << filename << "." << std::endl;
        return;
    }

    // Makes sure we have an indexed face set
    ObjMesh* pObjMesh = pRawObjMesh->createIndexedFaceSet(Obj::Options(Obj::AllAttribs|Obj::Triangulate));
    delete pRawObjMesh;
    pRawObjMesh = 0;

    // copy vertices
    mVertices.resize(pObjMesh->positions.size());

    for (int i=0 ; i<pObjMesh->positions.size() ; ++i)
    {
        mVertices[i] = Vertex(Vector3f(pObjMesh->positions[i]));

        if(!pObjMesh->texcoords.empty())
            mVertices[i].texcoord = Vector2f(pObjMesh->texcoords[i]);

        if(!pObjMesh->normals.empty())
            mVertices[i].normal = Vector3f(pObjMesh->normals[i]);
    }

    // copy faces
    for (int smi=0 ; smi<pObjMesh->getNofSubMeshes() ; ++smi)
    {
        const ObjSubMesh* pSrcSubMesh = pObjMesh->getSubMesh(smi);

        mFaces.reserve(pSrcSubMesh->getNofFaces());

        for (uint fid = 0 ; fid<pSrcSubMesh->getNofFaces() ; ++fid)
        {
            ObjConstFaceHandle srcFace = pSrcSubMesh->getFace(fid);
            mFaces.push_back(Vector3i(srcFace.vPositionId(0), srcFace.vPositionId(1), srcFace.vPositionId(2)));
        }
    }

    if(pObjMesh->normals.empty())
    {
        std::cout << "compute normals\n";
        computeNormals();
    }
}
Esempio n. 4
0
//ImplicitFuncMesh3DAccurate
ImplicitFuncMesh3DAccurate::ImplicitFuncMesh3DAccurate(const ObjMesh& mesh,const scalar& cellSz,const BBox<scalar>& bb):_cellSz(cellSz)
{
    const vector<Vec3,Eigen::aligned_allocator<Vec3> >& vv=mesh.getV();
    const vector<Vec3i,Eigen::aligned_allocator<Vec3i> >& vi=mesh.getI();
    const vector<Vec3,Eigen::aligned_allocator<Vec3> >& tnor=mesh.getTN();
    const vector<Vec3,Eigen::aligned_allocator<Vec3> >& nor=mesh.getN();

    _bb=bb;

    _mesh.reset(new MeshSLC());
    //copy verts
    _mesh->_verts.resize(vv.size());
    for(sizeType i=0; i<(sizeType)vv.size(); i++)
        _mesh->_verts[i]=Vec3SLC(vv[i].x(),vv[i].y(),vv[i].z());
    //copy inds
    _mesh->_inds.resize(vi.size());
    for(sizeType i=0; i<(sizeType)vi.size(); i++)
        _mesh->_inds[i]=Vec3i(vi[i].x(),vi[i].y(),vi[i].z());
    //copy nors
    _mesh->_nors.resize(nor.size());
    for(sizeType i=0; i<(sizeType)nor.size(); i++)
        _mesh->_nors[i]=Vec3SLC(nor[i].x(),nor[i].y(),nor[i].z());
    //copy tnors
    _mesh->_tnors.resize(tnor.size());
    for(sizeType i=0; i<(sizeType)tnor.size(); i++)
        _mesh->_tnors[i]=Vec3SLC(tnor[i].x(),tnor[i].y(),tnor[i].z());
    _mesh->searchNeigh();
    //initialize BVH
    _bvh.reset(new AABBvh(_mesh.get()));
    //initialize octree
    BBox<scalarD> bbD;
    bbD.copy(_bb);
    const Vec3SLC cellSzD(cellSz,cellSz,cellSz);
    sizeType level=0;
    {
        const sizeType maxCellDim=(sizeType)std::ceil(_bb.getExtent().maxCoeff()/cellSz);
        while((((sizeType)1)<<level) < maxCellDim)
            level++;
    }
    INFO("Building Distance Octree");
    _octree.reset(new OctreeDistance(bbD,cellSzD,level,_helper));
    if(!_octree->buildFromAABBvhTopDown(_bvh.get(),false)){
        NOTIFY_MSG("Fail Building OctDistanceTree, Check Your Mesh!")
    }
    INFO("Built");
}
Esempio n. 5
0
//ImplicitFuncMesh3D
ImplicitFuncMesh3D::ImplicitFuncMesh3D(const ObjMesh& mesh,const scalar& cellSz,const BBox<scalar>& bb):_cellSz(cellSz)
{
    const vector<Vec3,Eigen::aligned_allocator<Vec3> >& vv=mesh.getV();
    const vector<Vec3i,Eigen::aligned_allocator<Vec3i> >& vi=mesh.getI();

    _bb=bb;

    _mesh.reset(new MeshSLC());
    //copy verts
    _mesh->_verts.resize(vv.size());
    for(sizeType i=0; i<(sizeType)vv.size(); i++)
        _mesh->_verts[i]=Vec3SLC(vv[i].x(),vv[i].y(),vv[i].z());
    //copy inds
    _mesh->_inds.resize(vi.size());
    for(sizeType i=0; i<(sizeType)vi.size(); i++)
        _mesh->_inds[i]=Vec3i(vi[i].x(),vi[i].y(),vi[i].z());
    //initialize BVH
    _bvh.reset(new AABBvh(_mesh.get()));
}
Esempio n. 6
0
void World::SetupBunnyScene()
{
	NxSoftBodyDesc softBodyDesc;
	softBodyDesc.globalPose.t = NxVec3(0,35,-1);
	softBodyDesc.particleRadius = 0.2f;
	softBodyDesc.volumeStiffness = 1.0f;
	softBodyDesc.stretchingStiffness = 0.07f;
	softBodyDesc.friction = 1.0f;

	char *fileName = "bunny";	
	char tetFileName[256], objFileName[256], s[256];
	sprintf(tetFileName, "%s.tet", fileName);
	sprintf(objFileName, "%s.obj", fileName);

	ObjMesh *objMesh = new ObjMesh(); // it is for mesh surface rendering
	objMesh->loadFromObjFile(FindMediaFile(objFileName, s));  

	MySoftBody *softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);

	if (!softBody->getNxSoftBody())
	{
		printf("Error: Unable to create the SoftBody for the current scene.\n");
		delete softBody;
	} else
	{
		gSoftBodies.push_back(softBody);  // soft body is pushed to list.
		gObjMeshes.push_back(objMesh);  // surface mesh is pushed to list.
	}

	NxMat33 rot;
	NxActor *plate0 = CreateBox(NxVec3(-2.5,10,0), NxVec3(20.0f, 1.0f, 10.0f), 0,0.0f);
	rot.rotZ(1.5f);
	plate0->setGlobalOrientation(rot);
	NxActor *plate1 = CreateBox(NxVec3(2.5,10,0), NxVec3(20.0f, 1.0f, 10.0f), 0,0.0f);
	rot.rotZ(1.5f);
	plate1->setGlobalOrientation(rot);

	// set camera position and direction
	gCameraPos.set(-5.0f, 40.0f, 35.0f);
	gCameraForward.set(0.2,-1.1,-2);
	gCameraForward.normalize();
}
Esempio n. 7
0
//ImplicitFuncMesh2D
ImplicitFuncMesh2D::ImplicitFuncMesh2D(const ObjMesh& mesh,const scalar& cellSz,const BBox<scalar>& bb):_cellSz(cellSz)
{
    const vector<Vec3,Eigen::aligned_allocator<Vec3> >& vv=mesh.getV();
    const vector<Vec3i,Eigen::aligned_allocator<Vec3i> >& vi=mesh.getI();
    const BBoxf meshBB=mesh.getBB();
    const scalarF ext=(scalarF)bb.getExtent().maxCoeff();
    _bb=bb;

    _mesh.reset(new MeshSLC());
    //copy verts
    _mesh->_verts.resize(vv.size());
    for(sizeType i=0; i<(sizeType)vv.size(); i++)
        _mesh->_verts[i]=Vec3SLC(vv[i].x(),vv[i].y(),vv[i].z());
    //copy inds
    _mesh->_inds.resize(vi.size());
    for(sizeType i=0; i<(sizeType)vi.size(); i++)
        _mesh->_inds[i]=Vec3i(vi[i].x(),vi[i].y(),vi[i].z());
    //initialize BVH
    _bvh.reset(new AABBvh(_mesh.get()));

    //copy to grid
    Vec3i nrCell=ceil((Vec3)(bb.getExtent()/cellSz));
    BBox<scalar> bbLs(Vec3(bb._minC.x()-ext*0.1f,bb._minC.y()-ext*0.1f,0.0f),
                      Vec3(bb._maxC.x()+ext*0.1f,bb._maxC.y()+ext*0.1f,0.0f));
    _ls.reset(nrCell,bbLs,0.0f);
    for(sizeType x=0; x<nrCell.x(); x++) {
        //INFOV("X: %d",x)
        for(sizeType y=0; y<nrCell.y(); y++) {
            const Vec3 pos=_ls.getPt(Vec3i(x,y,0));
            Vec3SLC a(pos.x(),pos.y(),pos.z());
            a.z()=meshBB._minC.z()-cellSz;
            Vec3SLC b(pos.x(),pos.y(),pos.z());
            b.z()=meshBB._maxC.z()+cellSz;
            _ls.get(Vec3i(x,y,0))=_bvh->intersectLineSeg3D(a,b,0) ? -_cellSz : _cellSz;
        }
    }

    GridOp<scalar,scalar>::reinitialize(_ls);
    GridOp<scalar,scalar>::write2DScalarGridVTK("./levelSet.vtk",_ls);
}
Esempio n. 8
0
void World::SetupPalmScene()
{
	NxSoftBodyDesc softBodyDesc;
	softBodyDesc.globalPose.t = NxVec3(0,3,0);
	softBodyDesc.particleRadius = 0.2f; 
	softBodyDesc.volumeStiffness = 0.5;
	softBodyDesc.stretchingStiffness = 1.0f;
	softBodyDesc.friction  = 1.0f;
	softBodyDesc.flags |= NX_SBF_COLLISION_TWOWAY;

	char* fileName = "palm";

	char tetFileName[256], objFileName[256], s[256];
	//sprintf(tetFileName, "%s.tet", fileName);
	sprintf(objFileName, "%s.obj", fileName);

	ObjMesh *objMesh = new ObjMesh();
	objMesh->loadFromObjFile(FindMediaFile(objFileName, s));

	MySoftBody *softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);
	if (!softBody->getNxSoftBody())
	{
		printf("Error: Unable to create the SoftBody for the current scene.\n");
		delete softBody;
	}
	else
	{
		gSoftBodies.push_back(softBody);
		gObjMeshes.push_back(objMesh);

		softBody->getNxSoftBody()->setExternalAcceleration(NxVec3(5,0,0));

		NxActor *caps0 = CreateCompoundCapsule(NxVec3(-0.46f, -0.15f, 0.68f), 1.7f, 0.21f, 2.0f, 0.18f);
		caps0->userData = (void*)&gInvisible;
		CreateRopeSphericalJoint(NULL, caps0, NxVec3(-0.46f, -0.0f, 0.68f), NxVec3(0,0,1));

		softBody->getNxSoftBody()->attachToCollidingShapes(0);
	}
}
int main( int argc, char** argv )
{

  if ( argc < 3 )
  {
    std::cout << "Usage: " << argv[0] << " [volumetric mesh file] [output obj file] [-t]" << std::endl;
    std::cout << "Generates the surface mesh of the given volumetric mesh." << std::endl;
    std::cout << "-t: (this option only applies with cubic meshes) Triangulates each quad face. Default: faces are left as quads." << std::endl;
    return 1;
  }

  char * meshFile = argv[1];
  char * outputFile = argv[2];

  bool outputTriangleMesh = false;

  opt_t opttable[] =
  {
    { (char*)"t", OPTBOOL, &outputTriangleMesh },
    { NULL, 0, NULL }
  };

  argv += 1;
  argc -= 1;
  getopts(argc,argv,opttable);

  if (outputTriangleMesh)
    printf("Triangle mesh will be triangulated (if needed).\n");

  VolumetricMesh * mesh = VolumetricMeshLoader::load(meshFile);

  GenerateSurfaceMesh generateSurfaceMesh;
  ObjMesh * objMesh = generateSurfaceMesh.ComputeMesh(mesh, outputTriangleMesh);
  objMesh->save(outputFile);

  return 0;
}
Esempio n. 10
0
void MeshAnimation::Part::Draw(const ObjMesh& mesh, double ticks, int tickCount) const
{
    if (ticks > 1)
        ticks = ticks;

    double angle = ::Lerp(ticks, tickCount, angles);
    Vec3 offset = ::Lerp(ticks, tickCount, offsets);

    glPushMatrix();

    GL::Translate(offset);

    GL::Translate(pivot);
    GL::Rotate(angle, axis);
    GL::Translate(-pivot);

    mesh.DrawObject(name);

    for (auto& part : parts)
        part.Draw(mesh, ticks, tickCount);

    glPopMatrix();
}
Esempio n. 11
0
void World::SetupSoftWheelCarScene()
{
	NxSoftBodyDesc softBodyDesc;
	softBodyDesc.particleRadius = 0.2f;
	softBodyDesc.volumeStiffness = 1.0f;
	softBodyDesc.stretchingStiffness = 1.0f;
	softBodyDesc.friction = 1.0f;
	softBodyDesc.attachmentResponseCoefficient = 0.8f;
	softBodyDesc.tearFactor = 10.1;						// should be more than 1.0, the less, the easier to tear with flag NX_SBF_TEARABLE

	softBodyDesc.flags |= NX_SBF_HARDWARE | NX_SBF_VOLUME_CONSERVATION | NX_SBF_TEARABLE;

	char *fileName = "wheel";
	char tetFileName[256], objFileName[256], s[256];
	sprintf(tetFileName, "%s.tet", fileName);
	sprintf(objFileName, "%s.obj", fileName);

	MySoftBody *softBody;

	NxReal carHeight = 7.5f;
	NxReal stiffness = 0.9f;
	NxMat34 capsulePose = NxMat34(NxMat33(NX_IDENTITY_MATRIX), NxVec3(-4, carHeight, -5.0f));
	printf("capsulePose %f %f %f\n", capsulePose.t.x, capsulePose.t.y, capsulePose.t.z);
	capsulePose.M.rotX(NxHalfPiF32);
	NxActor *caps1 = CreateOrientedCapsule(capsulePose, 7.1f, 1.3f, 1.0f);
	capsulePose.t = NxVec3(4, carHeight, -5.0f);
	NxActor *caps2 = CreateOrientedCapsule(capsulePose, 7.1f, 1.3f, 1.0f);
	
	ObjMesh *objMesh = new ObjMesh();
	objMesh->loadFromObjFile(FindMediaFile(objFileName, s));
	
	NxMat33 rot;
	rot.rotX(NxPiF32);
	softBodyDesc.globalPose.t = NxVec3(4.0f, carHeight, 3.4f);
	softBodyDesc.globalPose.M = rot;
	softBodyDesc.stretchingStiffness = stiffness;
	softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);
	if (!softBody->getNxSoftBody())
	{
		printf("Error: Unable to create Softbody for the current scene.\n");
		delete softBody;
	}
	else
	{
		gObjMeshes.push_back(objMesh);

		// wheel 1 
		softBody->getNxSoftBody()->attachToCollidingShapes(NX_SOFTBODY_ATTACHMENT_TWOWAY);
		gSoftBodies.push_back(softBody);

		softBodyDesc.globalPose.t = NxVec3(-4.0f ,carHeight, 3.4f);
		softBodyDesc.globalPose.M = rot;
		softBodyDesc.stretchingStiffness = stiffness;
		softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);
		softBody->getNxSoftBody()->attachToCollidingShapes(NX_SOFTBODY_ATTACHMENT_TWOWAY);
		gSoftBodies.push_back(softBody);

		softBodyDesc.globalPose.t = NxVec3(4.0f, carHeight, -3.4f);
		softBodyDesc.globalPose.M.id();
		softBodyDesc.stretchingStiffness = stiffness;
		softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);
		softBody->getNxSoftBody()->attachToCollidingShapes(NX_SOFTBODY_ATTACHMENT_TWOWAY);
		gSoftBodies.push_back(softBody);

		softBodyDesc.globalPose.t = NxVec3(-4.0f, carHeight, -3.4f);
		softBodyDesc.globalPose.M.id();
		softBodyDesc.stretchingStiffness = stiffness;
		softBody = new MySoftBody(gScene, softBodyDesc, FindMediaFile(tetFileName,s), objMesh);
		softBody->getNxSoftBody()->attachToCollidingShapes(NX_SOFTBODY_ATTACHMENT_TWOWAY);		// bind soft wheel with capsule colliding with it
		gSoftBodies.push_back(softBody);

		NxActor *box = CreateBox(NxVec3(0,carHeight,0), NxVec3(4.6f, 0.5f, 1.0f), 0,1.0f);
		CreateRevoluteJoint(box, caps1, NxVec3(-4,carHeight,-3.5f), NxVec3(0,0,1), false);
		CreateRevoluteJoint(box, caps2, NxVec3( 4,carHeight,-3.5f), NxVec3(0,0,1), false);

	}
	gSelectedActor = caps1;

}
Esempio n. 12
0
bool LoadFromObjMesh(const std::string& path, RenderDevice* device, TextureManager* texManater, Matrix4x4 posMatrix, Matrix4x4 texcoordMatrix, std::vector<Primitive* >& primList)
{
	ObjMesh objMesh;

	bool success = objMesh.Load(path);

	std::string folderPath = PathRemoveFileName(objMesh.path);

	for(size_t i = 0; i < objMesh.geomList.size(); i++)
	{
		std::vector<ObjMesh::FusedVertex> vertices;
		std::vector<int> indices;

		objMesh.CreateVertexIndexBuffer(i, vertices, indices);

		for(size_t v = 0; v < vertices.size(); v++)
		{
			Vector4 pos =  posMatrix * Vector4(vertices[v].position.x, vertices[v].position.y, vertices[v].position.z, 1.f);
			vertices[v].position = Vector3(pos.x, pos.y, pos.z);

			Vector4 normal = posMatrix * Vector4(vertices[v].normal.x, vertices[v].normal.y, vertices[v].normal.z, 1.f);
			vertices[v].normal = Vector3(normal.x, normal.y, normal.z);


			Vector4 texcoord(vertices[v].texcoord.x, vertices[v].texcoord.y, 0.f, 1.f);
			texcoord = texcoordMatrix * texcoord;
			vertices[v].texcoord.x = texcoord.x;
			vertices[v].texcoord.y = texcoord.y;
		}

		HWVertexBuffer* vertexBuffer;
		HWIndexBuffer* indexBuffer;

		device->CreateVertexBuffer(sizeof(ObjMesh::FusedVertex) * vertices.size(), &vertices[0], &vertexBuffer);
		device->CreateIndexBuffer(sizeof(int) * indices.size(), &indices[0], &indexBuffer);

		Mesh* mesh = new Mesh();

		mesh->vertexBuffer = vertexBuffer;
		mesh->indexBuffer = indexBuffer;
		mesh->numVertices = vertices.size();
		mesh->numIndices = indices.size();

		mesh->positionList = new Vector3[vertices.size()];
		mesh->normalList = new Vector3[vertices.size()];
		mesh->texcoordList = new Vector2[vertices.size()];

		mesh->vertices = new VertexP3N3T2[vertices.size()];

		for(size_t v = 0; v < vertices.size(); v++)
		{
			mesh->vertices[v].position = mesh->positionList[v] = vertices[v].position;
			mesh->vertices[v].normal = mesh->normalList[v] = vertices[v].normal;
			mesh->vertices[v].texcoord = mesh->texcoordList[v] = vertices[v].texcoord;
		}

		Primitive* prim = new Primitive();
		Material* material = new Material();
		ObjMesh::Material& mat = objMesh.matList[objMesh.geomList[i].matIndex];

		material->ambient = mat.ka;
		material->diffuse = mat.kd;
		material->specular = mat.ks;
		material->roughness = mat.ns;

		if(!mat.mapKd.empty())
			material->diffuseMap = texManater->Load(folderPath + "\\" + mat.mapKd );
		if(!mat.mapKs.empty() )
			material->specularMap = texManater->Load(folderPath + "\\" + mat.mapKs );
		if(!mat.mapBump.empty())
			material->normalMap = texManater->Load(folderPath + "\\" + mat.mapBump);
		if(!mat.mapD.empty())
			material->dissolveMask = texManater->Load(folderPath + "\\" + mat.mapD);

		prim->mesh = mesh;
		prim->material = material;

		primList.push_back(prim);
	}


	return success;
}
Esempio n. 13
0
/*
  Pour chaque objet, construire une liste unique de sommets et de triangles, récupérer le matériau et appeler un callback pour mettre l'objet dans la scène.
 */
void ObjLoader::getObjects (std::vector<loaders::Mesh *> &meshes) {
    {
        // add geometries
        for (std::map<std::string, Group *>::iterator group = allgroups.begin(); group != allgroups.end(); ++group) {
            Group *theGroup = group->second;
            if (!theGroup->empty) {
                ObjMesh *theMesh;
                theMesh = new ObjMesh (theGroup->name);
                for (std::map<int, FaceList>::iterator sg = theGroup->faces.begin(); sg != theGroup->faces.end(); ++sg) {
                    std::vector<Face *>::iterator it = sg->second.begin();
                    if (it != sg->second.end()) {
                        // le groupe n'est pas vide !
                        int type = faceType (*it);
                        switch (type) {
                        case 0: // group with complete faces
                            if (sg->first == 0) {
                                // pas de lissage sur ce smoothgroup
                                // ajout des sommets sans reorganisation
                                addRawVerticeNormalTexturePart (theMesh, sg->second, sg->first);
                            } else {
                                addVerticeNormalTexturePart (theMesh, sg->second, sg->first);
                            }
                            break;
                        case 1: // groupe avec faces vertex+normales
                            if (sg->first == 0) {
                                // pas de lissage sur ce smoothgroup
                                // ajout des sommets sans reorganisation
                                addRawVerticeNormalPart (theMesh, sg->second, sg->first);
                            } else {
                                addVerticeNormalPart (theMesh, sg->second, sg->first);
                            }
                            break;
                        case 2: // groupe avec faces vertex+textures
                            if (sg->first == 0) {
                                // pas de lissage sur ce smoothgroup
                                // ajout des sommets sans reorganisation
                                addRawVerticeTexturePart (theMesh, sg->second, sg->first);
                            } else {
                                addVerticeTexturePart (theMesh, sg->second, sg->first);
                            }
                            break;
                        case 3: // groupe avec faces vertex uniquement
                            if (sg->first == 0) {
                                // pas de lissage sur ce smoothgroup
                                // ajout des sommets sans reorganisation
                                addRawVerticePart (theMesh, sg->second, sg->first);
                            } else {
                                addVerticePart (theMesh, sg->second, sg->first);
                            }
                            break;
                        default :
                            std::cerr << "Cas normalement impossible !" << std::endl;
                        }
                    }
                }

                meshes.push_back( theMesh->compile() );
                delete theMesh;
            }
            delete theGroup;
        }
    }
}
Esempio n. 14
0
bool ofxOBJModel::load(string path) {
	bHasNormals = false;
	bHasTexCoords = false;
	filePath = path;
	path = ofToDataPath(path, true);
	
	string line;
	
	for(int i = 0; i < meshes.size(); i++) {
		delete meshes[i];
	}
	meshes.clear();
	
	ObjMesh *currMesh = NULL;
	
	// this is a list of all points
	// that we can drop after parsing
	vector<ofPoint> points; 
	vector<ofPoint> normals;
	vector<ofPoint> texCoords;
	
	// obj file format vertexes are 1-indexed
	points.push_back(ofPoint());
	normals.push_back(ofPoint());
	texCoords.push_back(ofPoint());
	ifstream myfile (path.c_str());
	if (myfile.is_open()) {
		while (! myfile.eof()) {
			getline (myfile,line);
			
			
			// parse the obj format here.
			//
			// the only things we're interested in is
			// lines beginning with 'g' - this says start of new object
			// lines beginning with 'v ' - coordinate of a vertex
			// lines beginning with 'vn ' - vertex normals                   -- todo
			// lines beginning with 'vt ' - texcoords (either 2 or 3 values) -- todo
			// lines beginning with 'f ' - specifies a face of a shape
			// 			we take each number before the slash as the index
			// 			of the vertex to join up to create a face.
			
			if(line.find("g ")==0) { // new object definition
				currMesh = new ObjMesh(line.substr(2));
				meshes.push_back(currMesh);
			} else if(line.find("v ")==0) { // new vertex
				points.push_back(parseCoords(line));
			} else if(line.find("vn ")==0) {
				bHasNormals = true;
				normals.push_back(parseCoords(line));
			} else if(line.find("vt ")==0) {
				bHasTexCoords = true;
				texCoords.push_back(parseCoords(line));
			} else if(line.find("f ")==0) { // face definition
				
				if(currMesh!=NULL) {
					line = line.substr(2); // lop off "f "
					vector<string> indices = split(line, ' ');
					// remove any texcoords (/xxx's)
					
					ObjFace *face = new ObjFace();
					for(int i = 0; i < indices.size(); i++) {
						vector<string> parts = ofSplitString(indices[i], "/");
						
						// first index is always a point
						face->points.push_back(points[atoi(parts[0].c_str())]);

						if(parts.size()==2) {
							face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]);
						} else if(parts.size()==3) {
							face->normals.push_back(normals[atoi(parts[2].c_str())]);
							if(parts[1]!="") {
								face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]);
							}
						}

					}
					currMesh->addFace(face);
				}
			}				
		}
		
		
		myfile.close();
//#define NORMALIZE_TEXCOORDS 
#ifdef NORMALIZE_TEXCOORDS
			ofPoint pmin(FLT_MAX, FLT_MAX);
			ofPoint pmax(FLT_MIN, FLT_MIN);
			for(int i = 0; i < texCoords.size(); i++) {
				if(texCoords[i].x<pmin.x) pmin.x = texCoords[i].x;
				if(texCoords[i].y<pmin.y) pmin.y = texCoords[i].y;
				
				if(texCoords[i].x>pmax.x) pmax.x = texCoords[i].x;
				if(texCoords[i].y>pmax.y) pmax.y = texCoords[i].y;
			}
			
			for(int k = 0; k < meshes.size(); k++) 
			for(int i = 0; i < meshes[k]->faces.size(); i++) 
				for(int j = 0; j < meshes[k]->faces[i]->texCoords.size(); j++) {
					ofPoint p = meshes[k]->faces[i]->texCoords[j];
					
					p.x = ofMap(p.x, pmin.x, pmax.x, 0, 1);
					p.y = ofMap(p.y, pmin.y, pmax.y, 0, 1);
					
					meshes[k]->faces[i]->texCoords[j] = p;

				}
#endif
		loadVbo();
		ofLog(OF_LOG_NOTICE, "Successfully loaded %s\n-----\nVertices: %d\nMeshes: %d\nNormals: %d\nTexCoords: %d\n", path.c_str(), points.size(), meshes.size(), normals.size(), texCoords.size());
		
		return true;
	} else {
		ofLog(OF_LOG_ERROR, "Couldn't find the OBJ file %s\n", path.c_str());
		return false;
	}
}
Esempio n. 15
0
bool ofxOBJModel::load(string path) {
	filePath = path;
	path = ofToDataPath(path, true);
	string line;
	
	for(int i = 0; i < meshes.size(); i++) {
		delete meshes[i];
	}
	meshes.clear();
	
	ObjMesh *currMesh = NULL;
	// this is a list of all points
	// that we can drop after parsing
	vector<ofPoint> points; 
	
	// obj file format vertexes are 1-indexed
	points.push_back(ofPoint());
	
	ifstream myfile (path.c_str());
	if (myfile.is_open()) {
		while (! myfile.eof()) {
			getline (myfile,line);
			
			
			// parse the obj format here.
			//
			// the only things we're interested in is
			// lines beginning with 'g' - this says start of new object
			// lines beginning with 'v ' - coordinate of a vertex
			// lines beginning with 'f ' - specifies a face of a shape
			// 			we take each number before the slash as the index
			// 			of the vertex to join up to create a face.
			
			if(line.find("g ")==0) { // new object definition
				currMesh = new ObjMesh(line.substr(2));
				meshes.push_back(currMesh);
			} else if(line.find("v ")==0) { // new vertex
				points.push_back(parseVertex(line));
			} else if(line.find("f ")==0) { // face definition
				if(currMesh!=NULL) {
					line = line.substr(2); // lop off "f "
					vector<string> indices = split(line, ' ');
					// remove any texcoords (/xxx's)
					for(int i = 0; i < indices.size(); i++) {
						int slashPos = indices[i].find("/");
						if(slashPos!=-1) {
							indices[i] = indices[i].substr(0, slashPos);
						}
					}
					ObjFace *face = new ObjFace();
					for(int i = 0; i < indices.size(); i++) {
						face->points.push_back(points[atoi(indices[i].c_str())]);
					}
					currMesh->addFace(face);
				}
			}				
		}
		
		
		myfile.close();
		
		printf("Successfully loaded %s\n-----\nVertices: %d\nMeshes: %d\n", path.c_str(), points.size(), meshes.size());
		
		return true;
	} else {
		printf("Couldn't find the OBJ file %s\n", path.c_str());
		return false;
	}
}
Esempio n. 16
0
int main( int argc, char** argv )
{
  const int numFixedArguments = 3;
  if( argc < numFixedArguments )
  {
    std::cout << "Merges several obj meshes into one. This routine uses the \"objMesh\" class to load the meshes. It can also merge materials." << std::endl;
    std::cout << "Usage: " << argv[0] << " [list of obj files] [output file] [-m]" << std::endl;
    std::cout << "  -m : also output materials" << std::endl;
    std::cout << "  -d : (if -m) also remove duplicate materials" << std::endl;
    return 1;
  }

  bool outputMaterials = false; 
  bool removeDuplicatedMaterials = false; 
  char * objListFilename = argv[1];
  char * objMeshname = argv[2];

  opt_t opttable[] =
  {
    { (char*)"m", OPTBOOL, &outputMaterials },
    { (char*)"d", OPTBOOL, &removeDuplicatedMaterials },
    { NULL, 0, NULL }
  };
  
  argv += numFixedArguments-1;
  argc -= numFixedArguments-1;
  int optup = getopts(argc,argv,opttable);
  if (optup != argc)
  {
    printf("Error parsing options. Error at option %s.\n",argv[optup]);
    return 1;
  }

  ObjMesh outputObjMesh;

  char s[4096];
  FILE * fin;
  char fileMode[96] = "r";
  OpenFile_(objListFilename, &fin, fileMode);

  while(fgets(s,4096,fin) != 0)
  {
    if(s[strlen(s)-1] == '\n')
      s[strlen(s)-1] = '\0';

    printf("%s\n",s);

    ObjMesh * objMesh = new ObjMesh(s);

    // add vertices
    int numVerticesCurrent = outputObjMesh.getNumVertices();
    for(unsigned int i=0; i<objMesh->getNumVertices(); i++)
      outputObjMesh.addVertexPosition(objMesh->getPosition(i));

    // add normals
    int numNormalsCurrent = outputObjMesh.getNumNormals();
    for(unsigned int i=0; i<objMesh->getNumNormals(); i++)
      outputObjMesh.addVertexNormal(objMesh->getNormal(i));
   
    // add texture coordinates
    int numTextureCoordinatesCurrent = outputObjMesh.getNumTextureCoordinates();
    for(unsigned int i=0; i<objMesh->getNumTextureCoordinates(); i++)
      outputObjMesh.addTextureCoordinate(objMesh->getTextureCoordinate(i));

    // add materials
    int numMaterialsCurrent = outputObjMesh.getNumMaterials();
    for(unsigned int i=0; i<objMesh->getNumMaterials(); i++)
      outputObjMesh.addMaterial(objMesh->getMaterial(i));

    for(unsigned int i=0; i<objMesh->getNumGroups(); i++)
    {
      const ObjMesh::Group * group = objMesh->getGroupHandle(i);
      outputObjMesh.addGroup(group->getName());
      unsigned int newGroupID = outputObjMesh.getNumGroups() - 1;
      ObjMesh::Group * newGroup = (ObjMesh::Group*) outputObjMesh.getGroupHandle(newGroupID);
      newGroup->setMaterialIndex(numMaterialsCurrent + group->getMaterialIndex());

      // over all faces in the group of the current obj file
      for(unsigned int j=0; j<group->getNumFaces(); j++)
      {
        const ObjMesh::Face * face = group->getFaceHandle(j);
        for(unsigned int k=0; k<face->getNumVertices(); k++)
        {
          ObjMesh::Vertex * vertex = (ObjMesh::Vertex*) face->getVertexHandle(k);
          vertex->setPositionIndex(vertex->getPositionIndex() + numVerticesCurrent);
          if (vertex->hasNormalIndex())
            vertex->setNormalIndex(vertex->getNormalIndex() + numNormalsCurrent);
          if (vertex->hasTextureCoordinateIndex())
            vertex->setTextureCoordinateIndex(vertex->getTextureCoordinateIndex() + numTextureCoordinatesCurrent);
        }
        outputObjMesh.addFaceToGroup(*face,newGroupID);
      }
    }

    delete(objMesh);
  }
  
  fclose(fin);

  if (outputMaterials)
  {
    if (removeDuplicatedMaterials)
    {
      printf("Removing duplicated materials..."); fflush(NULL);
      int numNewMaterials = outputObjMesh.removeDuplicatedMaterials();
      printf(" retained %d materials.\n", numNewMaterials);
    }
    outputObjMesh.save(objMeshname, 1);
  }
  else
  {
    outputObjMesh.save(objMeshname);
  }

  return(0);
}
int main(int argc, char ** argv)
{
  if (argc < 4)
  {
    printf("Generates an interpolant between a given volumetric mesh and a surface obj mesh.\n");
    printf("Usage: %s <volumetric mesh file> <target obj file> <output interpolant file> [-s volumetric mesh element list output filename] [-z threshold] [-S] [-T]\n",argv[0]);
    printf("-s : output list of (1-indexed) volumetric mesh elements that contain at least one obj mesh vertex\n");
    printf("-z : assign zero interpolation to vertices too far away from the volumetric mesh\n");
    return 0;
  }

  char * meshFile = argv[1];
  char * objMeshname = argv[2];
  char * outputFilename = argv[3];

  char outputElementFilename[4096] = "__none";
  char zeroThresholdString[4096] = "__none";

  opt_t opttable[] =
  {
    { (char*)"s", OPTSTR, &outputElementFilename },
    { (char*)"z", OPTSTR, &zeroThresholdString },
    { NULL, 0, NULL }
  };

  argv += 3;
  argc -= 3;
  int optup = getopts(argc,argv,opttable);
  if (optup != argc)
  {
    printf("Error parsing options. Error at option %s.\n",argv[optup]);
    return 1;
  }

  double threshold;
  if (strcmp(zeroThresholdString,"__none") == 0)
    threshold = -1;
  else
    threshold = strtod(zeroThresholdString, NULL);

  VolumetricMesh * volumetricMesh = VolumetricMeshLoader::load(meshFile);
  
  if (volumetricMesh == NULL)
  {
    printf("Error: unable to load the volumetric mesh from %s.\n", meshFile);
    exit(1);
  }
 
  int n = volumetricMesh->getNumVertices();
  int nel = volumetricMesh->getNumElements();
  printf("Info on %s:\n", meshFile);
  printf("Num vertices: %d\n", n);
  printf("Num elements: %d\n", nel);

  ObjMesh * objMesh = new ObjMesh(objMeshname);

  int numInterpolationLocations = objMesh->getNumVertices();
  double * interpolationLocations = (double*) malloc (sizeof(double) * 3 * numInterpolationLocations);
  for(int i=0; i< numInterpolationLocations; i++)
  {
    Vec3d pos = objMesh->getPosition(i);
    interpolationLocations[3*i+0] = pos[0];
    interpolationLocations[3*i+1] = pos[1];
    interpolationLocations[3*i+2] = pos[2];
  }

  int * vertices;
  double * weights;

  int * elementList;
  int ** elementListp = NULL;
  if (strcmp(outputElementFilename, "__none") != 0)
  {
    elementListp = &elementList;    
  }

  int verbose = 1;
  int numExternalVertices;
  numExternalVertices = volumetricMesh->generateInterpolationWeights(numInterpolationLocations, interpolationLocations, &vertices, &weights, threshold, elementListp, verbose);

  printf("Saving weights to %s...\n", outputFilename); fflush(NULL);
  volumetricMesh->saveInterpolationWeights(outputFilename, numInterpolationLocations, volumetricMesh->getNumElementVertices(), vertices, weights);

  if (strcmp(outputElementFilename, "__none") != 0)
  {
    set<int> uniqueElementSet;
    for(unsigned int i=0; i<numInterpolationLocations; i++)
      uniqueElementSet.insert(elementList[i]);

    vector<int> uniqueElementList;
    for(set<int>::iterator iter = uniqueElementSet.begin(); iter != uniqueElementSet.end(); iter++)
      uniqueElementList.push_back(*iter);

    LoadList saveList;
    sort(uniqueElementList.begin(), uniqueElementList.end());
    int oneIndexed = 1;
    saveList.save(outputElementFilename, uniqueElementList.size(), &uniqueElementList[0], oneIndexed);
  }
  printf("\n");

  return 0;
}