importObjEle.hpp 6.56 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
*                                                                              *
* 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 PURPOSE. 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.           *
*                                                                              *
20
* Web site: http://cgogn.u-strasbg.fr/                                         *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24 25 26 27 28 29
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Algo/Modelisation/polyhedron.h"
#include <vector>

namespace CGoGN
{
Pierre Kraemer's avatar
Pierre Kraemer committed
30

Pierre Kraemer's avatar
Pierre Kraemer committed
31 32
namespace Algo
{
Pierre Kraemer's avatar
Pierre Kraemer committed
33 34

namespace Import
Pierre Kraemer's avatar
Pierre Kraemer committed
35 36 37
{

template<typename PFP>
Pierre Kraemer's avatar
Pierre Kraemer committed
38
bool importOFFWithELERegions(typename PFP::MAP& map, const std::string& filenameOFF, const std::string& filenameELE, std::vector<std::string>& attrNames)
Pierre Kraemer's avatar
Pierre Kraemer committed
39 40 41
{
	typedef typename PFP::VEC3 VEC3;

42
	AttributeHandler<VEC3> position = map.template addAttribute<VEC3>(VERTEX, "position") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
43 44
	attrNames.push_back(position.name()) ;

45
	AttributeContainer& container = map.getAttributeContainer(VERTEX) ;
46 47

	unsigned int m_nbVertices = 0, m_nbFaces = 0, m_nbEdges = 0, m_nbVolumes = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
48

49
	AutoAttributeHandler<  NoMathIONameAttribute< std::vector<Dart> > > vecDartsPerVertex(map, VERTEX, "incidents");
Pierre Kraemer's avatar
Pierre Kraemer committed
50 51

	// open files
Pierre Kraemer's avatar
Pierre Kraemer committed
52
	std::ifstream foff(filenameOFF.c_str(), std::ios::in);
Pierre Kraemer's avatar
Pierre Kraemer committed
53 54
	if (!foff.good())
	{
55
		CGoGNerr << "Unable to open OFF file " << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
56 57 58
		return false;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
59
	std::ifstream fele(filenameELE.c_str(), std::ios::in);
Pierre Kraemer's avatar
Pierre Kraemer committed
60 61
	if (!fele.good())
	{
62
		CGoGNerr << "Unable to open ELE file " << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
63 64 65 66 67 68
		return false;
	}

	std::string line;

	//OFF reading
Pierre Kraemer's avatar
Pierre Kraemer committed
69
	std::getline(foff, line);
Pierre Kraemer's avatar
Pierre Kraemer committed
70 71
	if(line.rfind("OFF") == std::string::npos)
	{
72 73
		CGoGNerr << "Problem reading off file: not an off file"<<CGoGNendl;
		CGoGNerr << line << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
74 75 76 77
		return false;
	}

	//Reading number of vertex/faces/edges in OFF file
Pierre Kraemer's avatar
Pierre Kraemer committed
78
	unsigned int nbe;
Pierre Kraemer's avatar
Pierre Kraemer committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92
	{
		do
		{
			std::getline(foff,line);
		}while(line.size() == 0);

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

	//Reading number of tetrahedra in ELE file
Pierre Kraemer's avatar
Pierre Kraemer committed
93
	unsigned int nbv;
Pierre Kraemer's avatar
Pierre Kraemer committed
94 95 96 97 98 99 100 101 102 103 104
	{
		do
		{
			std::getline(fele,line);
		}while(line.size() == 0);

		std::stringstream oss(line);
		oss >> m_nbVolumes;
		oss >> nbv ; oss >> nbv;
	}

105
	CGoGNout << "nb points = " << m_nbVertices << " / nb faces = " << m_nbFaces << " / nb edges = " << m_nbEdges << " / nb tet = " << m_nbVolumes << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
106 107 108 109 110

	//Reading vertices
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

Pierre Kraemer's avatar
Pierre Kraemer committed
111
	for(unsigned int i = 0 ; i < m_nbVertices ; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
	{
		do
		{
			std::getline(foff,line);
		}while(line.size() == 0);

		std::stringstream oss(line);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		//we can read colors informations if exists
		VEC3 pos(x,y,z);

Pierre Kraemer's avatar
Pierre Kraemer committed
127 128
		unsigned int id = container.insertLine();
		position[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
129 130 131 132 133 134
		verticesID.push_back(id);
	}

	std::vector<std::vector<Dart> > vecDartPtrEmb;
	vecDartPtrEmb.reserve(m_nbVertices);

untereiner's avatar
untereiner committed
135 136
	DartMarkerNoUnmark m(map) ;

Pierre Kraemer's avatar
Pierre Kraemer committed
137
	//Read and embed tetrahedra TODO
Pierre Kraemer's avatar
Pierre Kraemer committed
138
	for(unsigned i = 0; i < m_nbVolumes ; ++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
139 140 141 142 143 144 145 146 147
	{
		do
		{
			std::getline(fele,line);
		} while(line.size() == 0);

		std::stringstream oss(line);
		oss >> nbe;

untereiner's avatar
untereiner committed
148
		Dart d = Algo::Modelisation::createTetrahedron<PFP>(map);
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150 151 152 153 154 155 156 157 158
		Geom::Vec4ui pt;
		oss >> pt[0];
		oss >> pt[1];
		oss >> pt[2];
		oss >> pt[3];

		//regions ?
		oss >> nbe;

		// Embed three vertices
Pierre Kraemer's avatar
Pierre Kraemer committed
159
		for(unsigned int j = 0 ; j < 3 ; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
160
		{
untereiner's avatar
untereiner committed
161 162
			FunctorSetEmb<typename PFP::MAP> fsetemb(map, VERTEX, verticesID[pt[2-j]]);
			map.foreach_dart_of_orbit( PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb);
Pierre Kraemer's avatar
Pierre Kraemer committed
163

untereiner's avatar
untereiner committed
164
			//store darts per vertices to optimize reconstruction
Pierre Kraemer's avatar
Pierre Kraemer committed
165
			Dart dd = d;
untereiner's avatar
untereiner committed
166 167 168 169
			do
			{
				m.mark(dd) ;
				vecDartsPerVertex[pt[2-j]].push_back(dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
170
				dd = map.phi1(map.phi2(dd));
untereiner's avatar
untereiner committed
171
			} while(dd != d);
Pierre Kraemer's avatar
Pierre Kraemer committed
172

Pierre Kraemer's avatar
Pierre Kraemer committed
173
			d = map.phi1(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175 176 177

		}

		//Embed the last vertex
Pierre Kraemer's avatar
Pierre Kraemer committed
178
		d = map.phi_1(map.phi2(d));
Pierre Kraemer's avatar
Pierre Kraemer committed
179

untereiner's avatar
untereiner committed
180 181 182 183
		FunctorSetEmb<typename PFP::MAP> fsetemb(map, VERTEX, verticesID[pt[3]]);
		map.foreach_dart_of_orbit( PFP::MAP::ORBIT_IN_PARENT(VERTEX), d, fsetemb);

		//store darts per vertices to optimize reconstruction
Pierre Kraemer's avatar
Pierre Kraemer committed
184
		Dart dd = d;
untereiner's avatar
untereiner committed
185 186 187
		do
		{
			m.mark(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
188
			vecDartsPerVertex[pt[3]].push_back(dd);
Pierre Kraemer's avatar
Pierre Kraemer committed
189
			dd = map.phi1(map.phi2(dd));
Pierre Kraemer's avatar
Pierre Kraemer committed
190 191 192 193 194 195 196 197
		} while(dd != d);

	}

	foff.close();
	fele.close();

	//Association des phi3
untereiner's avatar
untereiner committed
198
	unsigned int nbBoundaryFaces = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
199
	for (Dart d = map.begin(); d != map.end(); map.next(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
200
	{
untereiner's avatar
untereiner committed
201
		if (m.isMarked(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
202
		{
untereiner's avatar
untereiner committed
203 204 205 206
			std::vector<Dart>& vec = vecDartsPerVertex[map.phi1(d)];

			Dart good_dart = NIL;
			for(typename std::vector<Dart>::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it)
Pierre Kraemer's avatar
Pierre Kraemer committed
207
			{
untereiner's avatar
untereiner committed
208 209 210
				if(map.getEmbedding(VERTEX, map.phi1(*it)) == map.getEmbedding(VERTEX, d) &&
				   map.getEmbedding(VERTEX, map.phi_1(*it)) == map.getEmbedding(VERTEX, map.phi_1(d)) /*&&
				   map.getEmbedding(VERTEX, *it) == map.getEmbedding(VERTEX, map.phi1(d)) */)
Pierre Kraemer's avatar
Pierre Kraemer committed
211
				{
untereiner's avatar
untereiner committed
212
					good_dart = *it ;
Pierre Kraemer's avatar
Pierre Kraemer committed
213 214
				}
			}
untereiner's avatar
untereiner committed
215 216 217 218 219 220 221 222 223 224 225

			if (good_dart != NIL)
			{
				map.sewVolumes(d, good_dart, false);
				m.unmarkOrbit(FACE, d);
			}
			else
			{
				m.unmarkOrbit(PFP::MAP::ORBIT_IN_PARENT(FACE), d);
				++nbBoundaryFaces;
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
226 227 228
		}
	}

untereiner's avatar
untereiner committed
229 230 231 232 233 234
	if (nbBoundaryFaces > 0)
	{
		std::cout << "closing" << std::endl ;
		map.closeMap();
		CGoGNout << "Map closed (" << nbBoundaryFaces << " boundary faces)" << CGoGNendl;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
235 236 237 238

	return true;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
239
} // namespace Import
Pierre Kraemer's avatar
Pierre Kraemer committed
240

Pierre Kraemer's avatar
Pierre Kraemer committed
241 242 243
} // namespace Algo

} // namespace CGoGN