importTet.hpp 6.55 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-2012, 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.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24 25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#include "Algo/Modelisation/polyhedron.h"
Sylvain Thery's avatar
Sylvain Thery committed
26
#include "Geometry/orientation.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
27 28 29 30
#include <vector>

namespace CGoGN
{
31

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

35 36 37
namespace Volume
{

Pierre Kraemer's avatar
Pierre Kraemer committed
38 39 40 41
namespace Import 
{

template <typename PFP>
Sylvain Thery's avatar
Sylvain Thery committed
42
bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector<std::string>& attrNames, float scaleFactor)
Pierre Kraemer's avatar
Pierre Kraemer committed
43 44 45
{
	typedef typename PFP::VEC3 VEC3;

46
	VertexAttribute<VEC3> position = map.template addAttribute<VEC3, VERTEX>("position") ;
Pierre Kraemer's avatar
Pierre Kraemer committed
47 48
	attrNames.push_back(position.name()) ;

49
	AttributeContainer& container = map.template getAttributeContainer<VERTEX>() ;
50

51
	unsigned int m_nbVertices = 0, m_nbVolumes = 0;
52
	VertexAutoAttribute< NoTypeNameAttribute< std::vector<Dart> > > vecDartsPerVertex(map, "incidents");
Pierre Kraemer's avatar
Pierre Kraemer committed
53

54
	//open file
Pierre Kraemer's avatar
Pierre Kraemer committed
55
	std::ifstream fp(filename.c_str(), std::ios::in);
Pierre Kraemer's avatar
Pierre Kraemer committed
56 57
	if (!fp.good())
	{
58
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
59 60 61 62
		return false;
	}

	std::string ligne;
Pierre Kraemer's avatar
Pierre Kraemer committed
63
	unsigned int nbv, nbt;
Sylvain Thery's avatar
Sylvain Thery committed
64

65
	// reading number of vertices
Pierre Kraemer's avatar
Pierre Kraemer committed
66 67 68 69
	std::getline (fp, ligne);
	std::stringstream oss(ligne);
	oss >> nbv;

70
	// reading number of tetrahedra
Pierre Kraemer's avatar
Pierre Kraemer committed
71 72 73 74
	std::getline (fp, ligne);
	std::stringstream oss2(ligne);
	oss2 >> nbt;

75
	//reading vertices
Pierre Kraemer's avatar
Pierre Kraemer committed
76 77
	std::vector<unsigned int> verticesID;
	verticesID.reserve(nbv);
Pierre Kraemer's avatar
Pierre Kraemer committed
78
	for(unsigned int i = 0; i < nbv;++i)
Pierre Kraemer's avatar
Pierre Kraemer committed
79 80 81 82
	{
		do
		{
			std::getline (fp, ligne);
Sylvain Thery's avatar
Sylvain Thery committed
83
		} while (ligne.size() == 0 );
Pierre Kraemer's avatar
Pierre Kraemer committed
84 85 86 87 88 89 90

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
Sylvain Thery's avatar
Sylvain Thery committed
91

92
		// TODO : if required read other vertices attributes here
Pierre Kraemer's avatar
Pierre Kraemer committed
93 94
		VEC3 pos(x*scaleFactor,y*scaleFactor,z*scaleFactor);

Pierre Kraemer's avatar
Pierre Kraemer committed
95 96
		unsigned int id = container.insertLine();
		position[id] = pos;
Pierre Kraemer's avatar
Pierre Kraemer committed
97 98 99 100

		verticesID.push_back(id);
	}

101
	m_nbVertices = nbv;
Pierre Kraemer's avatar
Pierre Kraemer committed
102 103
	m_nbVolumes = nbt;

104
	CGoGNout << "nb points = " << m_nbVertices  << " / nb tet = " << m_nbVolumes << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
105

106 107
	DartMarkerNoUnmark m(map) ;

Sylvain Thery's avatar
Sylvain Thery committed
108 109

	unsigned int invertTetra = 0;
110
	//Read and embed all tetrahedrons
Pierre Kraemer's avatar
Pierre Kraemer committed
111 112
	for(unsigned int i = 0; i < m_nbVolumes ; ++i)
	{
113 114
		//start one tetra

Pierre Kraemer's avatar
Pierre Kraemer committed
115 116
		int nbe;
		do
Pierre Kraemer's avatar
Pierre Kraemer committed
117
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
118 119
			std::getline(fp,ligne);
		} while(ligne.size() == 0);
Pierre Kraemer's avatar
Pierre Kraemer committed
120

Pierre Kraemer's avatar
Pierre Kraemer committed
121
		std::stringstream oss(ligne);
122
		oss >> nbe; //number of vertices = 4 or used for region mark
Pierre Kraemer's avatar
Pierre Kraemer committed
123

124
		Dart d = Surface::Modelisation::createTetrahedron<PFP>(map,false);
125

Pierre Kraemer's avatar
Pierre Kraemer committed
126
		Geom::Vec4ui pt;
Sylvain Thery's avatar
Sylvain Thery committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149


		if (i==0)
		{
			oss >> pt[0];
			oss >> pt[1];
			oss >> pt[2];
			oss >> pt[3];

			typename PFP::VEC3 P = position[verticesID[pt[0]]];
			typename PFP::VEC3 A = position[verticesID[pt[1]]];
			typename PFP::VEC3 B = position[verticesID[pt[2]]];
			typename PFP::VEC3 C = position[verticesID[pt[3]]];

			if (Geom::testOrientation3D<typename PFP::VEC3>(P,A,B,C) == Geom::OVER)
			{
				invertTetra=1;
				unsigned int ui=pt[1];
				pt[1] = pt[2];
				pt[2] = ui;
			}
		}

Pierre Kraemer's avatar
Pierre Kraemer committed
150
		oss >> pt[0];
151 152
		oss >> pt[1+invertTetra];
		oss >> pt[2-invertTetra];
Pierre Kraemer's avatar
Pierre Kraemer committed
153
		oss >> pt[3];
Pierre Kraemer's avatar
Pierre Kraemer committed
154

155
		// Embed three "base" vertices
Pierre Kraemer's avatar
Pierre Kraemer committed
156
		for(unsigned int j = 0 ; j < 3 ; ++j)
Pierre Kraemer's avatar
Pierre Kraemer committed
157
		{
158
			FunctorSetEmb<typename PFP::MAP, VERTEX> fsetemb(map, verticesID[pt[2-j]]);
Pierre Kraemer's avatar
Pierre Kraemer committed
159
			map.template foreach_dart_of_orbit<PFP::MAP::VERTEX_OF_PARENT>(d, fsetemb);
Pierre Kraemer's avatar
Pierre Kraemer committed
160

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

Pierre Kraemer's avatar
Pierre Kraemer committed
170
			d = map.phi1(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
171 172
		}

173
		//Embed the last "top" vertex
Pierre Kraemer's avatar
Pierre Kraemer committed
174 175
		d = map.phi_1(map.phi2(d));

176
		FunctorSetEmb<typename PFP::MAP, VERTEX> fsetemb(map, verticesID[pt[3]]);
Pierre Kraemer's avatar
Pierre Kraemer committed
177
		map.template foreach_dart_of_orbit<PFP::MAP::VERTEX_OF_PARENT>(d, fsetemb);
178 179

		//store darts per vertices to optimize reconstruction
Pierre Kraemer's avatar
Pierre Kraemer committed
180
		Dart dd = d;
Pierre Kraemer's avatar
Pierre Kraemer committed
181 182
		do
		{
183
			m.mark(dd) ;
Pierre Kraemer's avatar
Pierre Kraemer committed
184 185 186 187
			vecDartsPerVertex[pt[3]].push_back(dd);
			dd = map.phi1(map.phi2(dd));
		} while(dd != d);

188
		//end of tetra
Pierre Kraemer's avatar
Pierre Kraemer committed
189
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
190

Pierre Kraemer's avatar
Pierre Kraemer committed
191
	//Association des phi3
192
	unsigned int nbBoundaryFaces = 0 ;
Pierre Kraemer's avatar
Pierre Kraemer committed
193 194
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
195
		if (m.isMarked(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
196
		{
197 198 199 200
			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
201
			{
202 203 204
				if(map.template getEmbedding<VERTEX>(map.phi1(*it)) == map.template getEmbedding<VERTEX>(d) &&
				   map.template getEmbedding<VERTEX>(map.phi_1(*it)) == map.template getEmbedding<VERTEX>(map.phi_1(d)) /*&&
				   map.template getEmbedding<VERTEX>(*it) == map.template getEmbedding<VERTEX>(map.phi1(d)) */)
Pierre Kraemer's avatar
Pierre Kraemer committed
205
				{
206
					good_dart = *it ;
Pierre Kraemer's avatar
Pierre Kraemer committed
207 208
				}
			}
209 210 211 212

			if (good_dart != NIL)
			{
				map.sewVolumes(d, good_dart, false);
213
				m.template unmarkOrbit<FACE>(d);
214 215 216
			}
			else
			{
Pierre Kraemer's avatar
Pierre Kraemer committed
217
				m.unmarkOrbit<PFP::MAP::FACE_OF_PARENT>(d);
218 219
				++nbBoundaryFaces;
			}
Pierre Kraemer's avatar
Pierre Kraemer committed
220
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
221
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
222

223 224 225 226 227 228 229
	if (nbBoundaryFaces > 0)
	{
		std::cout << "closing" << std::endl ;
		map.closeMap();
		CGoGNout << "Map closed (" << nbBoundaryFaces << " boundary faces)" << CGoGNendl;
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
230 231 232 233
	fp.close();
	return true;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
234 235
} // namespace Import

236 237
}

Pierre Kraemer's avatar
Pierre Kraemer committed
238 239 240
} // namespace Algo

} // namespace CGoGN