importSvg.hpp 15.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
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009-2012, 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 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.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

untereiner's avatar
...    
untereiner committed
25
26
27
28
#include <iostream>
#include "Geometry/bounding_box.h"
#include "Geometry/plane_3d.h"
#include "Algo/BooleanOperator/mergeVertices.h"
untereiner's avatar
untereiner committed
29
#include "Container/fakeAttribute.h"
untereiner's avatar
...    
untereiner committed
30
31
32
33
34
35
36
37
#include <limits>

namespace CGoGN
{

namespace Algo
{

38
39
40
namespace Surface
{

untereiner's avatar
...    
untereiner committed
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
namespace Import
{

inline bool checkXmlNode(xmlNodePtr node, const std::string& name)
{
	return (strcmp((char*)(node->name),(char*)(name.c_str())) == 0);
}

template<typename T>
inline bool valueOf(const std::string &s, T &obj)
{
  std::istringstream is(s);
  return is >> obj;
}

template <typename VEC>
bool posSort(const std::pair<VEC, Dart>& a1, const std::pair<VEC, Dart>& a2)
{
	VEC v1 = a1.first;
	VEC v2 = a2.first;
	return v1[0] < v2[0] || (v1[0] == v2[0] && v1[1] < v2[1]);
}

template <typename VEC3>
void getPolygonFromSVG(std::string allcoords, std::vector<VEC3>& curPoly, bool& closedPoly)
{
	closedPoly=false;
	std::stringstream is(allcoords);
	bool relative=false;
	bool push_point;
	std::string coord;
	int mode = -1;

	while ( std::getline( is, coord, ' ' ) )
	{
		float x,y;
		push_point=false;

		if(coord[0]=='m' || coord[0]=='l' || coord[0]=='t') //start point, line or quadratic bezier curve
		{
			mode = 0;
			relative=true;
		}
		else if(coord[0]=='M' || coord[0] == 'L' || coord[0]=='T') //same in absolute coordinates
		{
			mode = 1;
			relative=false;
		}
		else if(coord[0]=='h' || coord[0] == 'H') //horizontal line
		{
			mode = 2;
			relative=(coord[0]=='h');
		}
		else if(coord[0]=='v' || coord[0] == 'V') //vertical line
		{
			mode = 3;
			relative=(coord[0]=='v');
		}
		else if(coord[0]=='c' || coord[0] == 'C') //bezier curve
		{
			mode = 4;
			relative=(coord[0]=='c');
		}
		else if(coord[0]=='s' || coord[0] == 'S' || coord[0]=='q' || coord[0] == 'Q') //bezier curve 2
		{
			mode = 5;
			relative= ((coord[0]=='s') || (coord[0]=='q'));
		}
		else if(coord[0]=='a' || coord[0] == 'A') //elliptic arc
		{
			mode =6;
			relative= (coord[0]=='a');
		}
114
		else if(coord[0]=='z') //end of path
untereiner's avatar
...    
untereiner committed
115
116
		{
			closedPoly = true;
Jund Thomas's avatar
Jund Thomas committed
117

untereiner's avatar
...    
untereiner committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
		}
		else //coordinates
		{
			switch(mode)
			{
				case 0 : //relative
				break;
				case 1 : //absolute
				break;
				case 2 : //horizontal
				{
					std::stringstream streamCoord(coord);
					std::string xS;
					std::getline(streamCoord, xS, ',' );

					valueOf(xS,x);

					VEC3 previous = (curPoly)[(curPoly).size()-1];
					y = previous[1];

					push_point=true;
				}
				break;
				case 3 : //vertical
				{
					std::stringstream streamCoord(coord);
					std::string yS;
					std::getline(streamCoord, yS, ',' );

					valueOf(yS,y);

untereiner's avatar
untereiner committed
149
					VEC3 previous = (curPoly)[(curPoly).size()-1];
untereiner's avatar
...    
untereiner committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
					x = previous[0];

					push_point=true;
				}
				break;
				case 4 : //bezier
				{
					std::getline( is, coord, ' ' ); //ignore first control point
					std::getline( is, coord, ' ' ); //ignore second control point
				}
				break;
				case 5 : //bezier 2
				{
					std::getline( is, coord, ' ' ); //ignore control point

				}
				break;
				case 6 : //elliptic
					std::getline( is, coord, ' ' ); //ignore rx
					std::getline( is, coord, ' ' ); //ignore ry
					std::getline( is, coord, ' ' ); //ignore x-rotation
					std::getline( is, coord, ' ' ); //ignore large arc flag
					std::getline( is, coord, ' ' ); //ignore sweep flag
				break;
			}

			std::stringstream streamCoord(coord);
			std::string xS,yS;
			std::getline(streamCoord, xS, ',' );
			std::getline(streamCoord, yS, ',' );

			valueOf(xS,x);
			valueOf(yS,y);

			push_point = true;
		}

		//if there is a point to push
		if(push_point)
		{

			VEC3 previous;

			if(curPoly.size()>0)
				previous = (curPoly)[(curPoly).size()-1];

			if(relative)
			{
				x += previous[0];
				y += previous[1];
			}

			if(curPoly.size()==0 || (curPoly.size()>0 && (x!=previous[0] || y!= previous[1])))
				curPoly.push_back(VEC3(x,y,0));
		}
	}
}

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
template <typename PFP>
void readCoordAndStyle(xmlNode* cur_path,
		std::vector<std::vector<VEC3 > >& allPoly,
		std::vector<std::vector<VEC3 > >& allBrokenLines,
		std::vector<float>& allBrokenLinesWidth)
{
	typedef typename PFP::VEC3 VEC3;
	typedef std::vector<VEC3 > POLYGON;

	bool closedPoly;
	POLYGON curPoly;

//	CGoGNout << "--load a path--"<< CGoGNendl;
	xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "d");
	std::string allcoords((reinterpret_cast<const char*>(prop)));
	getPolygonFromSVG(allcoords,curPoly,closedPoly);

	//check orientation : set in CCW
	if(curPoly.size()>2)
	{
Jund Thomas's avatar
Jund Thomas committed
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
		VEC3 v(0), v1, v2;
		typename std::vector<VEC3 >::iterator it0, it1, it2;
		it0 = curPoly.begin();
		it1 = it0+1;
		it2 = it1+1;
		for(unsigned int i = 0 ; i < curPoly.size() ; ++i)
		{
			VEC3 t = (*it1)^(*it0);
			v += t;

			it0=it1;
			it1=it2;
			it2++;
			if(it2 == curPoly.end())
				it2 = curPoly.begin();
		}

		if(v[2]>0)
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		{
			std::reverse(curPoly.begin(), curPoly.end());
		}
	}

	//closed polygon ?
	if(closedPoly)
		allPoly.push_back(curPoly);
	else
	{
		//if not : read the linewidth for further dilatation
		allBrokenLines.push_back(curPoly);
		xmlChar* prop = xmlGetProp(cur_path, BAD_CAST "style");
		std::string allstyle((reinterpret_cast<const char*>(prop)));
		std::stringstream is(allstyle);
		std::string style;
		while ( std::getline( is, style, ';' ) )
		{
			if(style.find("stroke-width:")!=std::string::npos)
			{
				std::stringstream isSize(style);
				std::getline( isSize, style, ':' );
				float sizeOfLine;
				isSize >> sizeOfLine;
				allBrokenLinesWidth.push_back(sizeOfLine);
			}
		}
	}
}

untereiner's avatar
...    
untereiner committed
276
template <typename PFP>
David Cazier's avatar
David Cazier committed
277
bool importSVG(typename PFP::MAP& map, const std::string& filename, VertexAttribute<typename PFP::VEC3>& position, CellMarker<EDGE>& obstacleMark, CellMarker<FACE>& buildingMark)
untereiner's avatar
...    
untereiner committed
278
{
279
280
281
	//TODO : remove auto-intersecting faces
	//TODO : handling polygons with holes

untereiner's avatar
...    
untereiner committed
282
	typedef typename PFP::VEC3 VEC3;
David Cazier's avatar
David Cazier committed
283
	typedef std::vector<VEC3> POLYGON;
untereiner's avatar
...    
untereiner committed
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

	xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
	xmlNodePtr map_node = xmlDocGetRootElement(doc);

	if (!checkXmlNode(map_node,"svg"))
	{
		CGoGNerr << "Wrong xml format: Root node != svg"<< CGoGNendl;
		return false;
	}

	std::vector<POLYGON> allPoly;
	std::vector<POLYGON> allBrokenLines;
	std::vector<float> allBrokenLinesWidth;

	for (xmlNode* cur_node = map_node->children; cur_node; cur_node = cur_node->next)
	{
		// for each layer
		if (checkXmlNode(cur_node, "g"))
			for (xmlNode* cur_path = cur_node->children ; cur_path; cur_path = cur_path->next)
			{
				if (checkXmlNode(cur_path, "path"))
305
					readCoordAndStyle<PFP>(cur_path, allPoly, allBrokenLines, allBrokenLinesWidth);
untereiner's avatar
...    
untereiner committed
306
			}
307
308
		else if (checkXmlNode(cur_node, "path"))
				readCoordAndStyle<PFP>(cur_node, allPoly, allBrokenLines, allBrokenLinesWidth);
untereiner's avatar
...    
untereiner committed
309
310
311
312
	}

	xmlFreeDoc(doc);

313
314
	std::cout << "importSVG : XML read." << std::endl;

315
	CellMarker<EDGE> brokenMark(map);
316
317
	EdgeAttribute<float> edgeWidth = map.template addAttribute<float, EDGE>("width");
	EdgeAttribute<NoMathAttribute<Geom::Plane3D<typename PFP::REAL> > > edgePlanes = map.template addAttribute<NoMathAttribute<Geom::Plane3D<typename PFP::REAL> >, EDGE>("planes");
untereiner's avatar
...    
untereiner committed
318
319
320
321
322

	/////////////////////////////////////////////////////////////////////////////////////////////
	//create broken lines
	DartMarker brokenL(map);

David Cazier's avatar
David Cazier committed
323
	typename std::vector<POLYGON >::iterator it;
untereiner's avatar
...    
untereiner committed
324
	std::vector<float >::iterator itW = allBrokenLinesWidth.begin();
David Cazier's avatar
David Cazier committed
325
	for(it = allBrokenLines.begin() ; it != allBrokenLines.end() ; ++it, ++itW)
untereiner's avatar
...    
untereiner committed
326
327
328
329
330
331
332
333
	{
		if(it->size()<2)
		{
			it = allBrokenLines.erase(it);
			itW = allBrokenLinesWidth.erase(itW);
		}
		else
		{
David Cazier's avatar
David Cazier committed
334
			Dart d = map.newPolyLine(it->size()-1);
untereiner's avatar
...    
untereiner committed
335

David Cazier's avatar
David Cazier committed
336
			for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
untereiner's avatar
...    
untereiner committed
337
			{
David Cazier's avatar
David Cazier committed
338
339
				brokenL.mark(d);
				brokenL.mark(map.phi2(d));
340

David Cazier's avatar
David Cazier committed
341
				edgeWidth[d] = *itW;
Jund Thomas's avatar
Jund Thomas committed
342
343
				if (*itW == 0)
					std::cout << "importSVG : null path width" << std::endl ;
David Cazier's avatar
David Cazier committed
344
345
				position[d] = *emb;
				d = map.phi1(d);
untereiner's avatar
...    
untereiner committed
346
			}
347
348
		}
	}
David Cazier's avatar
David Cazier committed
349
	std::cout << "importSVG : broken lines created : " << std::endl;
untereiner's avatar
...    
untereiner committed
350
351

	/////////////////////////////////////////////////////////////////////////////////////////////
David Cazier's avatar
David Cazier committed
352
	// Merge near vertices
Sylvain Thery's avatar
Sylvain Thery committed
353
	BooleanOperator::mergeVertices<PFP>(map,position,1);
354
	std::cout << "importSVG : Merging of vertices." << std::endl;
355

Jund Thomas's avatar
Jund Thomas committed
356
	/////////////////////////////////////////////////////////////////////////////////////////////
357

Jund Thomas's avatar
Jund Thomas committed
358
359
	std::cout << "buildings " << allPoly.size() << std::endl;
	unsigned int c = 0;
untereiner's avatar
...    
untereiner committed
360

Jund Thomas's avatar
Jund Thomas committed
361
362
363
	//create polygons
	for(it = allPoly.begin() ; it != allPoly.end() ; ++it)
	{
David Cazier's avatar
David Cazier committed
364
		if(it->size()<3)
Jund Thomas's avatar
Jund Thomas committed
365
366
367
368
369
370
		{
			it = allPoly.erase(it);
		}
		else
		{
			Dart d = map.newFace(it->size());
Jund Thomas's avatar
Jund Thomas committed
371
			c++;
David Cazier's avatar
David Cazier committed
372
373
			buildingMark.mark(d);
			buildingMark.mark(map.phi2(d));
374

untereiner's avatar
...    
untereiner committed
375
376
			for(typename POLYGON::iterator emb = it->begin(); emb != it->end() ; emb++)
			{
David Cazier's avatar
David Cazier committed
377
				position[d] = *emb;
David Cazier's avatar
David Cazier committed
378
				obstacleMark.mark(d);
David Cazier's avatar
David Cazier committed
379
				d = map.phi1(d);
untereiner's avatar
...    
untereiner committed
380
			}
381
		}
Jund Thomas's avatar
Jund Thomas committed
382
	}
untereiner's avatar
...    
untereiner committed
383

David Cazier's avatar
David Cazier committed
384
385
386
387
	Geom::BoundingBox<typename PFP::VEC3> bb ;
	bb = Algo::Geometry::computeBoundingBox<PFP>(map, position) ;
	float tailleX = bb.size(0) ;
	float tailleY = bb.size(1) ;
388
	float tailleM = std::max<float>(tailleX, tailleY) / 30 ;
David Cazier's avatar
David Cazier committed
389
390
	std::cout << "bounding box = " << tailleX << " X " << tailleY << std::endl;

Jund Thomas's avatar
Jund Thomas committed
391
392
393
394
	for(Dart d = map.begin();d != map.end(); map.next(d))
	{
		if(position[d][0] == position[map.phi1(d)][0] && position[d][1] == position[map.phi1(d)][1])
			std::cout << "prob d " << d << std::endl;
395
396
	}

Jund Thomas's avatar
Jund Thomas committed
397
	std::cout << "importSVG : Polygons generated." << std::endl;
398
399

	/////////////////////////////////////////////////////////////////////////////////////////////
400
	unsigned int count = 0 ;
untereiner's avatar
...    
untereiner committed
401
402

	//cut the edges to have a more regular sampling
David Cazier's avatar
David Cazier committed
403
404
	TraversorE<typename PFP::MAP> edges(map) ;
	for (Dart d = edges.begin() ; d != edges.end() ; d = edges.next())
405
	{
David Cazier's avatar
David Cazier committed
406
		if (!buildingMark.isMarked(d))
407
408
409
410
		{
			VEC3 p1 = position[d] ;
			VEC3 p2 = position[map.phi1(d)] ;
			VEC3 v  = p2 - p1 ;
David Cazier's avatar
David Cazier committed
411
			float length = v.norm() ;
412

David Cazier's avatar
David Cazier committed
413
			if (length > tailleM)
414
			{
David Cazier's avatar
David Cazier committed
415
				unsigned int nbSeg = (unsigned int)(length / tailleM) ;
416
				v /= nbSeg ;
David Cazier's avatar
David Cazier committed
417
				count += nbSeg ;
418
419
420

				for (unsigned int i = 0 ; i < nbSeg - 1 ; ++i)
					map.cutEdge(d) ;
untereiner's avatar
...    
untereiner committed
421

422
423
424
				brokenL.mark(d);
				brokenL.mark(map.phi2(d));
				Dart dd = map.phi1(d) ;
untereiner's avatar
...    
untereiner committed
425

426
427
428
429
430
431
432
433
434
435
				for (unsigned int i = 1 ; i < nbSeg ; ++i)
				{
					brokenL.mark(dd);
					brokenL.mark(map.phi2(dd));
					position[dd] = p1 + v * i ;
					dd = map.phi1(dd) ;
				}
			}
		}
	}
David Cazier's avatar
David Cazier committed
436
	std::cout << "importSVG : Subdivision of long edges : " << count << " morceaux."<< std::endl;
untereiner's avatar
...    
untereiner committed
437
438

	/////////////////////////////////////////////////////////////////////////////////////////////
David Cazier's avatar
David Cazier committed
439
	//simplify the edges to have a more regular sampling
David Cazier's avatar
David Cazier committed
440
	count = 0 ;
David Cazier's avatar
David Cazier committed
441
442
	for (Dart d = map.begin() ; d != map.end() ; map.next(d))
	{
David Cazier's avatar
David Cazier committed
443
		if(!buildingMark.isMarked(d))
David Cazier's avatar
David Cazier committed
444
445
		{
			bool canSimplify = true ;
446
			while ( canSimplify && (Geometry::edgeLength<PFP>(map,d,position) < edgeWidth[d]) )
David Cazier's avatar
David Cazier committed
447
			{
448
449
				if (map.vertexDegree(map.phi1(d)) == 2)
				{
David Cazier's avatar
David Cazier committed
450
					map.uncutEdge(d) ;
David Cazier's avatar
David Cazier committed
451
					count++;
David Cazier's avatar
David Cazier committed
452
				}
453
454
				else
					canSimplify = false ;
David Cazier's avatar
David Cazier committed
455
456
457
			}
		}
	}
David Cazier's avatar
David Cazier committed
458
	std::cout << "importSVG : Downsampling of vertices : " << count << " sommets supprimés." << std::endl;
untereiner's avatar
...    
untereiner committed
459
460
461

	/////////////////////////////////////////////////////////////////////////////////////////////
	//process broken lines
462
463
	CellMarker<EDGE> eMTreated(map) ;
	for (Dart d = map.begin() ; d != map.end() ; map.next(d))
untereiner's avatar
...    
untereiner committed
464
	{
465
		if (brokenL.isMarked(d) && !eMTreated.isMarked(d))
untereiner's avatar
...    
untereiner committed
466
		{
467
468
			eMTreated.mark(d) ;
			//insert a quadrangular face in the broken line
untereiner's avatar
...    
untereiner committed
469
			// -> we convert broken lines to faces to represent their width
470
			// -> the intersection are then closed
untereiner's avatar
...    
untereiner committed
471

472
473
			Dart d1 = d ;
			Dart d2 = map.phi2(d1) ;
untereiner's avatar
...    
untereiner committed
474

475
476
			map.unsewFaces(d1) ;
			Dart dN = map.newFace(4) ;
untereiner's avatar
...    
untereiner committed
477

478
479
480
481
482
483
484
			VEC3 p1 = position[d1] ;
			VEC3 p2 = position[d2] ;
			VEC3 v = p2 - p1 ;
			VEC3 ortho = v ^ VEC3(0, 0, 1);
			float width = edgeWidth[d1] / 2.0f ;
			ortho.normalize() ;
			v.normalize() ;
untereiner's avatar
...    
untereiner committed
485
486
487

			//if the valence of one of the vertex is equal to one
			//cut the edge to insert the quadrangular face
Jund Thomas's avatar
Jund Thomas committed
488
			if(map.vertexDegree(d1)==2)
untereiner's avatar
...    
untereiner committed
489
			{
490
491
492
493
				map.cutEdge(d2) ;
				brokenL.mark(map.phi1(d2)) ;
				eMTreated.mark(map.phi1(d2)) ;
				map.sewFaces(map.phi_1(d1), map.phi1(dN)) ;
David Cazier's avatar
David Cazier committed
494
				obstacleMark.mark(map.phi_1(d1)) ;
495
496
				position[map.phi_1(d1)] = p1 ;
				edgePlanes[map.phi_1(d1)] = Geom::Plane3D<typename PFP::REAL>(v, p1) ;
untereiner's avatar
...    
untereiner committed
497
498
			}

Jund Thomas's avatar
Jund Thomas committed
499
			if(map.vertexDegree(d2)==2)
500
			{
501
502
503
504
				map.cutEdge(d1) ;
				brokenL.mark(map.phi1(d1)) ;
				eMTreated.mark(map.phi1(d1)) ;
				map.sewFaces(map.phi_1(d2), map.phi_1(dN)) ;
David Cazier's avatar
David Cazier committed
505
				obstacleMark.mark(map.phi_1(d2)) ;
506
507
				position[map.phi_1(d2)] = p2 ;
				edgePlanes[map.phi_1(d2)] = Geom::Plane3D<typename PFP::REAL>(-1.0f * v, p2) ;
508
			}
untereiner's avatar
...    
untereiner committed
509

510
			map.sewFaces(d1, dN) ;
David Cazier's avatar
David Cazier committed
511
			obstacleMark.mark(d1) ;
512
			edgePlanes[d1] = Geom::Plane3D<typename PFP::REAL>(ortho, p1 - (width * ortho)) ;
untereiner's avatar
...    
untereiner committed
513

David Cazier's avatar
David Cazier committed
514
515
			map.sewFaces(d2, map.phi1(map.phi1(dN))) ;
			obstacleMark.mark(d2) ;
516
			edgePlanes[d2] = Geom::Plane3D<typename PFP::REAL>(-1.0f * ortho, p2 + (width * ortho)) ;
untereiner's avatar
...    
untereiner committed
517
518
519
		}
	}

Jund Thomas's avatar
Jund Thomas committed
520
	if(allBrokenLines.size()>0)
521
	{
Jund Thomas's avatar
Jund Thomas committed
522
		for (Dart d = map.begin() ; d != map.end() ; map.next(d))
523
		{
Sylvain Thery's avatar
Sylvain Thery committed
524
			if(map.isBoundaryMarked2(d))
Jund Thomas's avatar
Jund Thomas committed
525
526
			{
				map.fillHole(d);
untereiner's avatar
...    
untereiner committed
527
			}
528

Jund Thomas's avatar
Jund Thomas committed
529
			if(map.faceDegree(d)==2)
530
			{
Jund Thomas's avatar
Jund Thomas committed
531
				map.mergeFaces(d);
532
			}
533
		}
untereiner's avatar
...    
untereiner committed
534

Jund Thomas's avatar
Jund Thomas committed
535
536
		//embed the path
		for (Dart d = map.begin() ; d != map.end() ; map.next(d))
untereiner's avatar
...    
untereiner committed
537
		{
Jund Thomas's avatar
Jund Thomas committed
538
539
540
			if (brokenL.isMarked(d))
			{
				VEC3 pos;
Jund Thomas's avatar
Jund Thomas committed
541

Jund Thomas's avatar
Jund Thomas committed
542
543
				Geom::Plane3D<typename PFP::REAL> pl;
				pos = position[d] ;
untereiner's avatar
...    
untereiner committed
544

Jund Thomas's avatar
Jund Thomas committed
545
546
547
				pl = edgePlanes[d] ;
				pl.project(pos) ;
				position[d] = pos ;
Jund Thomas's avatar
Jund Thomas committed
548

Jund Thomas's avatar
Jund Thomas committed
549
550
551
552
				pos = position[map.phi1(d)] ;
				pl.project(pos) ;
				position[map.phi1(d)] = pos ;
			}
untereiner's avatar
...    
untereiner committed
553
554
		}

555
		map.template initAllOrbitsEmbedding<FACE>(true);
556

untereiner's avatar
...    
untereiner committed
557

558
		for (Dart d = map.begin() ; d != map.end() ; map.next(d))
untereiner's avatar
...    
untereiner committed
559
		{
Sylvain Thery's avatar
Sylvain Thery committed
560
			if (!map.isBoundaryMarked2(d) && brokenL.isMarked(d))
561
562
563
564
			{
				map.deleteFace(d,false);
			}
		}
untereiner's avatar
...    
untereiner committed
565

Jund Thomas's avatar
Jund Thomas committed
566
		map.closeMap();
567

568
569
		for (Dart d = map.begin() ; d != map.end() ; map.next(d))
		{
Sylvain Thery's avatar
Sylvain Thery committed
570
			if (map.isBoundaryMarked2(d))
571
				buildingMark.mark(d);
untereiner's avatar
...    
untereiner committed
572
573
		}

Jund Thomas's avatar
Jund Thomas committed
574
	}
untereiner's avatar
...    
untereiner committed
575
576
577
578

	return true ;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
579
} // namespace Import
untereiner's avatar
...    
untereiner committed
580

581
582
}

Pierre Kraemer's avatar
Pierre Kraemer committed
583
} // namespace Algo
untereiner's avatar
...    
untereiner committed
584

Pierre Kraemer's avatar
Pierre Kraemer committed
585
} // namespace CGoGN