import2tablesSurface.hpp 19.3 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURVEC3E. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/                              *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Algo/Import/importPlyData.h"

#include "openctm.h"

#include "assimp.h"
#include "aiPostProcess.h"
#include "aiScene.h"


namespace CGoGN
{

namespace Algo
{

namespace Import
{

template<typename PFP>
ImportSurfacique::ImportType MeshTablesSurface<PFP>::getFileType(const std::string& filename)
{
	if ((filename.rfind(".trianbgz")!=std::string::npos) || (filename.rfind(".TRIANBGZ")!=std::string::npos))
		return ImportSurfacique::TRIANBGZ;
	if ((filename.rfind(".trian")!=std::string::npos) || (filename.rfind(".TRIAN")!=std::string::npos))
		return ImportSurfacique::TRIAN;

	if ((filename.rfind(".plyptm")!=std::string::npos) || (filename.rfind(".PLYGEN")!=std::string::npos))
		return ImportSurfacique::PLYPTM;

	if ((filename.rfind(".ply")!=std::string::npos) || (filename.rfind(".PLY")!=std::string::npos))
		return ImportSurfacique::PLY;
	if ((filename.rfind(".off")!=std::string::npos) || (filename.rfind(".OFF")!=std::string::npos))
		return ImportSurfacique::OFF;
	if ((filename.rfind(".obj")!=std::string::npos) || (filename.rfind(".OBJ")!=std::string::npos))
		return ImportSurfacique::OBJ;
	if ((filename.rfind(".ctm")!=std::string::npos) || (filename.rfind(".OBJ")!=std::string::npos))
		return ImportSurfacique::CTM;

	return ImportSurfacique::UNKNOWNSURFACE;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
67
bool MeshTablesSurface<PFP>::importMesh(const std::string& filename, std::vector<std::string>& attrNames, ImportSurfacique::ImportType kind)
Pierre Kraemer's avatar
Pierre Kraemer committed
68 69 70 71
{
	if (kind == ImportSurfacique::UNKNOWNSURFACE)
		kind = getFileType(filename);

Pierre Kraemer's avatar
Pierre Kraemer committed
72
	attrNames.clear() ;
Pierre Kraemer's avatar
Pierre Kraemer committed
73 74 75 76

	switch (kind)
	{
	case ImportSurfacique::TRIAN:
Pierre Kraemer's avatar
Pierre Kraemer committed
77 78
		std::cout << "TYPE: TRIAN" << std::endl;
		return importTrian(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
79 80
		break;
	case ImportSurfacique::TRIANBGZ:
Pierre Kraemer's avatar
Pierre Kraemer committed
81 82
		std::cout << "TYPE: TRIANBGZ" << std::endl;
		return importTrianBinGz(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
83 84
		break;
	case ImportSurfacique::CTM:
Pierre Kraemer's avatar
Pierre Kraemer committed
85 86
		std::cout << "TYPE: CTM" << std::endl;
		return importCTM(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
87 88
		break;
	case ImportSurfacique::OFF:
Pierre Kraemer's avatar
Pierre Kraemer committed
89 90
		std::cout << "TYPE: OFF" << std::endl;
		return importOff(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92
		break;
	case ImportSurfacique::PLY:
Pierre Kraemer's avatar
Pierre Kraemer committed
93 94
		std::cout << "TYPE: PLY" << std::endl;
		return importPly(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
95 96
		break;
	case ImportSurfacique::OBJ:
Pierre Kraemer's avatar
Pierre Kraemer committed
97 98
		std::cout << "TYPE: OBJ" << std::endl;
		return importObj(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
99 100
		break;
	default:
Pierre Kraemer's avatar
Pierre Kraemer committed
101 102
		std::cout << "TYPE: ASSIMP" << std::endl;
		return importASSIMP(filename, attrNames);
Pierre Kraemer's avatar
Pierre Kraemer committed
103 104 105 106 107 108
		break;
	}
	return false;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
109
bool MeshTablesSurface<PFP>::importTrian(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
110
{
Pierre Kraemer's avatar
Pierre Kraemer committed
111 112 113 114
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
115 116 117 118 119 120 121 122
	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
		std::cerr << "Unable to open file " << filename << std::endl;
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
123
	// read nb of points
Pierre Kraemer's avatar
Pierre Kraemer committed
124 125
	fp >> m_nbVertices;

Pierre Kraemer's avatar
Pierre Kraemer committed
126
	// read points
Pierre Kraemer's avatar
Pierre Kraemer committed
127 128 129
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

Pierre Kraemer's avatar
Pierre Kraemer committed
130
	for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
131 132 133 134 135
	{
		VEC3 pos;
		fp >> pos[0];
		fp >> pos[1];
		fp >> pos[2];
Pierre Kraemer's avatar
Pierre Kraemer committed
136 137
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
138 139 140 141 142 143 144 145
		verticesID.push_back(id);
	}

	// read nb of faces
	fp >> m_nbFaces;
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

Pierre Kraemer's avatar
Pierre Kraemer committed
146 147
	// read indices of faces
	for (unsigned int i = 0; i < m_nbFaces; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
	{
		m_nbEdges.push_back(3);
		// read the three vertices of triangle
		int pt;
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);

		// neighbour not always good in files !!
		int neigh;
		fp >> neigh;
		fp >> neigh;
		fp >> neigh;
	}

	fp.close();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
171
bool MeshTablesSurface<PFP>::importTrianBinGz(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
172
{
Pierre Kraemer's avatar
Pierre Kraemer committed
173 174 175 176
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
177 178 179 180 181 182 183 184
	// open file
	igzstream fs(filename.c_str(), std::ios::in|std::ios::binary);

	if (!fs.good())
	{
		std::cerr << "Unable to open file " << filename << std::endl;
		return false;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
185

Pierre Kraemer's avatar
Pierre Kraemer committed
186 187 188 189 190
	// read nb of points
	fs.read(reinterpret_cast<char*>(&m_nbVertices), sizeof(int));

	// read points
	std::vector<unsigned int> verticesID;
Pierre Kraemer's avatar
Pierre Kraemer committed
191
	{	// juste pour limiter la portee des variables
Pierre Kraemer's avatar
Pierre Kraemer committed
192 193
		verticesID.reserve(m_nbVertices);
		float* buffer = new float[m_nbVertices*3];
Pierre Kraemer's avatar
Pierre Kraemer committed
194
		fs.read(reinterpret_cast<char*>(buffer), 3*m_nbVertices*sizeof(float));
Pierre Kraemer's avatar
Pierre Kraemer committed
195
		float *ptr = buffer;
Pierre Kraemer's avatar
Pierre Kraemer committed
196
		for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
197 198 199 200 201 202
		{
			VEC3 pos;
			pos[0]= *ptr++;
			pos[1]= *ptr++;
			pos[2]= *ptr++;

Pierre Kraemer's avatar
Pierre Kraemer committed
203 204
			unsigned int id = container.insertLine();
			positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
205 206 207 208 209 210 211 212 213 214 215 216

			verticesID.push_back(id);
		}
		delete[] buffer;
	}

	// read nb of faces
	fs.read(reinterpret_cast<char*>(&m_nbFaces), sizeof(int));
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// read indices of faces
Pierre Kraemer's avatar
Pierre Kraemer committed
217
	{	// juste pour limiter la portee des variables
Pierre Kraemer's avatar
Pierre Kraemer committed
218 219 220 221
		int* buffer = new int[m_nbFaces*6];
		fs.read(reinterpret_cast<char*>(buffer),6*m_nbFaces*sizeof(float));
		int *ptr = buffer;

Pierre Kraemer's avatar
Pierre Kraemer committed
222
		for (unsigned int i = 0; i < m_nbFaces; i++)
Pierre Kraemer's avatar
Pierre Kraemer committed
223 224 225 226 227 228 229 230 231 232 233 234 235
		{
			m_nbEdges.push_back(3);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
		}
	}
	
	fs.close();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
236
bool MeshTablesSurface<PFP>::importOff(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
237
{
Pierre Kraemer's avatar
Pierre Kraemer committed
238 239 240 241
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
242 243 244 245
	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
246
		std::cerr << "Unable to open file " << filename << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
247 248 249 250 251 252 253 254 255
		return false;
	}

    std::string ligne;

    // lecture de OFF
    std::getline (fp, ligne);
    if (ligne.rfind("OFF") == std::string::npos)
    {
Pierre Kraemer's avatar
Pierre Kraemer committed
256 257 258
		std::cerr << "Problem reading off file: not an off file" << std::endl;
		std::cerr << ligne << std::endl;
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    }

    // lecture des nombres de sommets/faces/aretes
	int nbe;
    {
    	do
    	{
    		std::getline (fp, ligne);
    	} while (ligne.size()==0);

	    std::stringstream oss(ligne);
		oss >> m_nbVertices;
		oss >> m_nbFaces;
		oss >> nbe;
    }

	//lecture sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
278
	for (unsigned int i = 0; i < m_nbVertices;++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
279 280 281 282
	{
    	do
    	{
    		std::getline (fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
283
    	} while (ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
284 285 286 287 288 289 290 291 292 293

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		// on peut ajouter ici la lecture de couleur si elle existe
		VEC3 pos(x,y,z);

Pierre Kraemer's avatar
Pierre Kraemer committed
294 295
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
296 297 298 299 300 301 302 303 304

		verticesID.push_back(id);
	}

	// lecture faces
	// normalement nbVertices*8 devrait suffire largement
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(m_nbVertices*8);

Pierre Kraemer's avatar
Pierre Kraemer committed
305
	for (unsigned int i = 0; i < m_nbFaces; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
306 307 308 309
	{
    	do
    	{
    		std::getline (fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
310
    	} while (ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329

		std::stringstream oss(ligne);
		int n;
		oss >> n;
		m_nbEdges.push_back(n);
		for (int j=0;j<n; ++j)
		{
			int index; // index du plongement
			oss >> index;
			m_emb.push_back(verticesID[index]);
		}
		// on peut ajouter ici la lecture de couleur si elle existe
	}

	fp.close();
	return true;
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
330
bool MeshTablesSurface<PFP>::importObj(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
331
{
Pierre Kraemer's avatar
Pierre Kraemer committed
332 333 334 335
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
336 337 338 339
	// open file
	std::ifstream fp(filename.c_str(), std::ios::binary);
	if (!fp.good())
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
340
		std::cerr << "Unable to open file " << filename << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
341 342 343
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
344
//	fp.seekg(0, std::ios::end);
Pierre Kraemer's avatar
Pierre Kraemer committed
345
//	int ab = fp.tellg();
Pierre Kraemer's avatar
Pierre Kraemer committed
346
//	fp.seekg(0, std::ios::beg);
Pierre Kraemer's avatar
Pierre Kraemer committed
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
//	int ac = fp.tellg();

    std::string ligne;
    std::string tag;

    do
    {
    	fp >> tag;
    	std::getline (fp, ligne);
    }while (tag != std::string("v"));

    // lecture des sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(102400); // on tape large (400Ko wahouuuuu !!)

Pierre Kraemer's avatar
Pierre Kraemer committed
362
	unsigned int i = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
363 364 365 366 367 368 369 370 371 372 373 374 375
    do
    {
		if (tag == std::string("v"))
		{
			std::stringstream oss(ligne);
		
			float x,y,z;
			oss >> x;
			oss >> y;
			oss >> z;

			VEC3 pos(x,y,z);

Pierre Kraemer's avatar
Pierre Kraemer committed
376 377
			unsigned int id = container.insertLine();
			positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
378 379 380 381 382 383

			verticesID.push_back(id);
			i++;
		}

		fp >> tag;
Pierre Kraemer's avatar
Pierre Kraemer committed
384
    	std::getline(fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
    } while (!fp.eof());

	m_nbVertices = verticesID.size();

	// close/clear/open only way to go back to beginning of file
	fp.close();
	fp.clear();
	fp.open(filename.c_str());

	do
    {
    	fp >> tag;
    	std::getline (fp, ligne);
    } while (tag != std::string("f"));

	m_nbEdges.reserve(verticesID.size()*2);
	m_emb.reserve(verticesID.size()*8);

	std::vector<int> table;
Pierre Kraemer's avatar
Pierre Kraemer committed
404
	table.reserve(64); // 64 cotes pour une face devrait suffire
Pierre Kraemer's avatar
Pierre Kraemer committed
405 406 407
	m_nbFaces = 0;
    do
    {
Pierre Kraemer's avatar
Pierre Kraemer committed
408
    	if (tag == std::string("f")) // lecture d'une face
Pierre Kraemer's avatar
Pierre Kraemer committed
409 410 411 412 413 414 415 416
    	{
    		std::stringstream oss(ligne);
     		table.clear();
    		while (!oss.eof())  // lecture de tous les indices
    		{
    			std::string str;
    			oss >> str;

Pierre Kraemer's avatar
Pierre Kraemer committed
417
    			unsigned int ind = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
418 419 420
    			while ( (str[ind]!='/')&& (ind<str.length()) )
    				ind++;

Pierre Kraemer's avatar
Pierre Kraemer committed
421
				if (ind > 0)
Pierre Kraemer's avatar
Pierre Kraemer committed
422 423
				{
    				long index;
Pierre Kraemer's avatar
Pierre Kraemer committed
424
					std::stringstream iss(str.substr(0, ind));
Pierre Kraemer's avatar
Pierre Kraemer committed
425 426 427 428 429
					iss >> index;
		   			table.push_back(index);
				}
    		}

Pierre Kraemer's avatar
Pierre Kraemer committed
430
    		unsigned int n = table.size();
Pierre Kraemer's avatar
Pierre Kraemer committed
431
			m_nbEdges.push_back(short(n));
Pierre Kraemer's avatar
Pierre Kraemer committed
432
    		for (unsigned int j = 0; j < n; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
433
    		{
Pierre Kraemer's avatar
Pierre Kraemer committed
434
    			int index = table[j] - 1; // les index commencent a 1 (boufonnerie d'obj ;)
Pierre Kraemer's avatar
Pierre Kraemer committed
435 436 437 438 439
				m_emb.push_back(verticesID[index]);
    		}
			m_nbFaces++;
    	}
		fp >> tag;
Pierre Kraemer's avatar
Pierre Kraemer committed
440
    	std::getline(fp, ligne);
Pierre Kraemer's avatar
Pierre Kraemer committed
441 442 443 444 445 446 447
     } while (!fp.eof());

	fp.close ();
	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
448
bool MeshTablesSurface<PFP>::importPly(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
449
{
Pierre Kraemer's avatar
Pierre Kraemer committed
450 451 452 453
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
454 455 456 457
	PlyImportData pid;

	if (! pid.read_file(filename) )
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
458
		std::cerr << "Unable to open file " << filename << std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
459 460 461 462 463 464 465 466 467 468
		return false;
	}
	
    // lecture des nombres de sommets/aretes/faces
	m_nbVertices = pid.nbVertices();
	m_nbFaces = pid.nbFaces();
 
	//lecture sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
469
	for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
470 471
	{
		VEC3 pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
472
		pid.vertexPosition(i, pos);
Pierre Kraemer's avatar
Pierre Kraemer committed
473

Pierre Kraemer's avatar
Pierre Kraemer committed
474 475
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
476 477 478 479 480 481 482

		verticesID.push_back(id);
	}

	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(m_nbVertices*8);

Pierre Kraemer's avatar
Pierre Kraemer committed
483
	for (unsigned int i = 0; i < m_nbFaces; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
484
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
485
		unsigned int n = pid.getFaceValence(i);
Pierre Kraemer's avatar
Pierre Kraemer committed
486 487
		m_nbEdges.push_back(n);
		int* indices = pid.getFaceIndices(i);
Pierre Kraemer's avatar
Pierre Kraemer committed
488
		for (unsigned int j = 0; j < n; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
489
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
490
			m_emb.push_back(verticesID[indices[j]]);
Pierre Kraemer's avatar
Pierre Kraemer committed
491 492 493 494 495 496
		}
	}

	return true;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
template <typename PFP>
bool MeshTablesSurface<PFP>::importPlyPTM(const std::string& filename, std::vector<std::string>& attrNames)
{
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;
	AttributeHandler<typename PFP::MATRIX33> Frame = m_map.template addAttribute<typename PFP::MATRIX33>(VERTEX_ORBIT, "Frame") ;
	attrNames.push_back(Frame.name()) ;
	AttributeHandler<typename PFP::MATRIX36> RGBfunctions = m_map.template addAttribute<typename PFP::MATRIX36>(VERTEX_ORBIT, "RGBfunctions") ;
	attrNames.push_back(RGBfunctions.name()) ;

	std::ifstream fp(filename.c_str(), std::ios::binary);
	if (!fp.good())
	{
		std::cerr << "Unable to open file " << filename<< std::endl;
		return false;
	}

    std::string ligne;
    std::string tag;

	fp >> tag;
	if (tag != std::string("ply"))
	{
		std::cerr <<filename<< " is not a ply file !" <<  std::endl;
		return false;
	}

	// va au nombre de sommets
	do
	{
		fp >> tag;
	} while (tag != std::string("vertex"));

	unsigned int nbp;
	fp >> nbp;
	// read points
	std::vector<unsigned int> verticesID;
	verticesID.reserve(nbp);

	// va au nombre de faces en comptant le nombre de "property"
	unsigned int nb_props = 0;
	do
	{
		fp >> tag;
		if (tag == std::string("property"))
			nb_props++;
	} while (tag != std::string("face"));

	fp >> m_nbFaces;
 	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// lecture des sommets

	// saute à la fin du header
	do
	{
		fp >> tag;
	} while (tag != std::string("end_header"));

	float* properties = new float[nb_props];

	for (unsigned int i = 0; i < nbp; ++i)
	{
		unsigned int id = container.insertLine();
		verticesID.push_back(id);

		for (unsigned int j = 0; j < nb_props; ++j)
		{
			fp >> properties[j];
		}

		positions[id] = VEC3(properties[0],properties[1],properties[2]);

		for (unsigned int k = 0 ; k < 3 ; ++k)
			for (unsigned int l = 0 ; l < 3 ; ++l)
				Frame[id](k,l) = properties[3+(3*k+l)] ;

		for (unsigned int k = 0 ; k < 3 ; ++k)
			for (unsigned int l = 0 ; l < 6 ; ++l)
				RGBfunctions[id](k,l) = properties[12+(6*k+l)];
	}

	m_nbVertices = verticesID.size();
	delete[] properties;

// read indices of faces
	for (unsigned int i = 0; i < m_nbFaces; i++)
	{
		// read the indices vertices of face
		int nbe;
		fp >> nbe;
		m_nbEdges.push_back(nbe);

		int pt;
		for (int j=0; j<nbe; ++j)
		{
			fp >> pt;
			m_emb.push_back(verticesID[pt]);
		}
	}

	fp.close();
	return true;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
603 604

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
605
bool MeshTablesSurface<PFP>::importCTM(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
606
{
Pierre Kraemer's avatar
Pierre Kraemer committed
607 608 609 610
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
611 612 613 614 615 616 617
	// Load the file using the OpenCTM API
	CTMimporter ctm;
	// Load the file
	ctm.Load(filename.c_str());

 	m_nbVertices = ctm.GetInteger(CTM_VERTEX_COUNT);

Pierre Kraemer's avatar
Pierre Kraemer committed
618
 	// read points
Pierre Kraemer's avatar
Pierre Kraemer committed
619 620 621 622
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

	const CTMfloat* vertices = ctm.GetFloatArray(CTM_VERTICES);
Pierre Kraemer's avatar
Pierre Kraemer committed
623
	for (unsigned int i = 0; i < m_nbVertices; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
624
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
625 626 627 628
		VEC3 pos(vertices[0], vertices[1], vertices[2]);
		vertices += 3; // next vertex in float*
		unsigned int id = container.insertLine();
		positions[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
629 630 631 632 633 634 635 636 637
		verticesID.push_back(id);
	}

	// read nb of faces
	m_nbFaces = ctm.GetInteger(CTM_TRIANGLE_COUNT);
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	const CTMuint * indices = ctm.GetIntegerArray(CTM_INDICES);
Pierre Kraemer's avatar
Pierre Kraemer committed
638 639

	// read indices of faces
Pierre Kraemer's avatar
Pierre Kraemer committed
640 641 642 643 644 645 646 647 648 649 650 651 652
	for (unsigned i=0; i<m_nbFaces; i++)
	{
		m_nbEdges.push_back(3);
		// read the three vertices of triangle
		m_emb.push_back(verticesID[*indices++]);
		m_emb.push_back(verticesID[*indices++]);
		m_emb.push_back(verticesID[*indices++]);
	}

	return true;
}

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
653
void MeshTablesSurface<PFP>::extractMeshRec(AttribContainer& container, AttributeHandler<typename PFP::VEC3>& positions, const struct aiScene* scene, const struct aiNode* nd, struct aiMatrix4x4* trafo)
Pierre Kraemer's avatar
Pierre Kraemer committed
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673
{
	struct aiMatrix4x4 prev;

	prev = *trafo;
	aiMultiplyMatrix4(trafo,&nd->mTransformation);

	std::vector<unsigned int> verticesID;

	// foreach mesh of node
	for (unsigned int n = 0; n < nd->mNumMeshes; ++n)
	{
		const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];

		verticesID.clear();
		verticesID.reserve(mesh->mNumVertices);
		//read positions
		for (unsigned int t = 0; t < mesh->mNumVertices; ++t)
		{
			// transform position
			struct aiVector3D tmp = mesh->mVertices[t];
Pierre Kraemer's avatar
Pierre Kraemer committed
674
			aiTransformVecByMatrix4(&tmp, trafo);
Pierre Kraemer's avatar
Pierre Kraemer committed
675
			// now store it
Pierre Kraemer's avatar
Pierre Kraemer committed
676 677
			unsigned int id = container.insertLine();
			positions[id] = VEC3(tmp[0], tmp[1], tmp[2]);
Pierre Kraemer's avatar
Pierre Kraemer committed
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
			verticesID.push_back(id);
		}
		m_nbVertices += mesh->mNumVertices;

		// read faces indices
		for (unsigned int t = 0; t < mesh->mNumFaces; ++t)
		{
			const struct aiFace* face = &mesh->mFaces[t];
			m_nbEdges.push_back(face->mNumIndices);
			for(unsigned int i = 0; i < face->mNumIndices; i++)
			{
				unsigned int pt = face->mIndices[i];
				m_emb.push_back(verticesID[pt]);
			}
		}
		m_nbFaces += mesh->mNumFaces;
	}

	// recurse on all children of node
	for (unsigned int n = 0; n < nd->mNumChildren; ++n)
	{
//		std::cout << "Children "<<n<< std::endl;
Pierre Kraemer's avatar
Pierre Kraemer committed
700
		extractMeshRec(container, positions, scene, nd->mChildren[n], trafo);
Pierre Kraemer's avatar
Pierre Kraemer committed
701 702 703 704 705
	}
	*trafo = prev;
}

template <typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
706
bool MeshTablesSurface<PFP>::importASSIMP(const std::string& filename, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
707
{
Pierre Kraemer's avatar
Pierre Kraemer committed
708 709 710 711
	AttribContainer& container = m_map.getAttributeContainer(VERTEX_CELL) ;
	AttributeHandler<typename PFP::VEC3> positions = m_map.template addAttribute<typename PFP::VEC3>(VERTEX_ORBIT, "position") ;
	attrNames.push_back(positions.name()) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
712 713 714 715 716 717 718 719 720 721
	m_nbVertices = 0;
	m_nbFaces = 0;

 	m_nbEdges.reserve(5000);
	m_emb.reserve(15000);

	struct aiMatrix4x4 trafo;
	aiIdentityMatrix4(&trafo);

	m_lab = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
722 723
	const struct aiScene* scene = aiImportFile(filename.c_str(), aiProcess_FindDegenerates | aiProcess_JoinIdenticalVertices);
	extractMeshRec(container, positions, scene, scene->mRootNode, &trafo);
Pierre Kraemer's avatar
Pierre Kraemer committed
724 725 726 727 728 729 730 731 732

	return true;
}

} // namespace Import

} // namespace Algo

} // namespace CGoGN