Example #1
0
void Topo3PrimalRender<PFP>::setDartsIdColor(typename PFP::MAP& map)
{
	m_vbo2->bind();
	float* colorBuffer = reinterpret_cast<float*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));
	unsigned int nb = 0;

	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
		if (nb < m_nbDarts)
		{
			float r,g,b;
			dartToCol(d, r,g,b);

			float* local = colorBuffer+3*m_attIndex[d]; // get the right position in VBO
			*local++ = r;
			*local++ = g;
			*local++ = b;
			*local++ = r;
			*local++ = g;
			*local++ = b;
			nb++;
		}
		else
		{
			CGoGNerr << "Error buffer too small for color picking (change the selector parameter ?)" << CGoGNendl;
			break;
		}
	}
	glUnmapBuffer(GL_ARRAY_BUFFER);
}
Example #2
0
typename PFP::REAL vertexVoronoiArea(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
{
	typename PFP::REAL area(0) ;
	Traversor2VF<typename PFP::MAP> t(map, d) ;
	for(Dart it = t.begin(); it != t.end(); it = t.next())
	{
		const typename PFP::VEC3& p1 = position[it] ;
		const typename PFP::VEC3& p2 = position[map.phi1(it)] ;
		const typename PFP::VEC3& p3 = position[map.phi_1(it)] ;
		if(!Geom::isTriangleObtuse(p1, p2, p3))
		{
			typename PFP::REAL a = Geom::angle(p3 - p2, p1 - p2) ;
			typename PFP::REAL b = Geom::angle(p1 - p3, p2 - p3) ;
			area += ( (p2 - p1).norm2() / tan(b) + (p3 - p1).norm2() / tan(a) ) / 8 ;
		}
		else
		{
			typename PFP::REAL tArea = Geom::triangleArea(p1, p2, p3) ;
			if(Geom::angle(p2 - p1, p3 - p1) > M_PI / 2)
				area += tArea / 2 ;
			else
				area += tArea / 4 ;
		}
	}
	return area ;
}
Example #3
0
void mergeVertices(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, int precision)
{
	// TODO optimiser en triant les sommets
	// map.template enableQuickTraversal<VERTEX>();
	TraversorV<typename PFP::MAP> travV1(map) ;
	CellMarker<typename PFP::MAP, VERTEX> vM(map);
	for(Dart d1 = travV1.begin() ; d1 != travV1.end() ; d1 = travV1.next())
	{
		vM.mark(d1);
		TraversorV<typename PFP::MAP> travV2(map) ;
		for(Dart d2 = travV2.begin() ; d2 != travV2.end() ; d2 = travV2.next())
		{
			if(!vM.isMarked(d2))
			{
				if(positions[d1].isNear(positions[d2], precision))
				{
					if (map.sameVertex(d1,d2))
						std::cout << "fusion: sameVertex" << std::endl ;
					if (!map.sameVertex(d1,d2))
						mergeVertex<PFP>(map,positions,d1,d2,precision);
				}
			}
		}
	}
	//	map.template disableQuickTraversal<VERTEX>();
}
Example #4
0
typename PFP::REAL triangleArea(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
{
	typename PFP::VEC3 p1 = position[d] ;
	typename PFP::VEC3 p2 = position[map.phi1(d)] ;
	typename PFP::VEC3 p3 = position[map.phi_1(d)] ;

	return Geom::triangleArea(p1, p2, p3) ;
}
Example #5
0
typename PFP::REAL tetrahedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position)
{
    typedef typename PFP::VEC3 VEC3;

    VEC3 p1 = position[v.dart] ;
    VEC3 p2 = position[map.phi1(v)] ;
    VEC3 p3 = position[map.phi_1(v)] ;
    VEC3 p4 = position[map.phi_1(map.phi2(v))] ;

    return Geom::tetraVolume(p1, p2, p3, p4) ;
}
void ColorPerFaceRender::updateVBO(Utils::VBO& vboPosition, Utils::VBO& vboColor, typename PFP::MAP& map,
			const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, const AttributeHandler<typename PFP::VEC3,ORBIT, typename PFP::MAP>& colorPerXXX)
{
	typedef typename PFP::VEC3 VEC3;
	typedef typename PFP::REAL REAL;
	typedef Geom::Vec3f VEC3F;

	std::vector<VEC3F> buffer;
	buffer.reserve(16384);

	std::vector<VEC3F> bufferColors;
	bufferColors.reserve(16384);

	TraversorCell<typename PFP::MAP, FACE> traFace(map);

	for (Dart d=traFace.begin(); d!=traFace.end(); d=traFace.next())
	{
		Dart a = d;
		Dart b = map.phi1(a);
		Dart c = map.phi1(b);
		// loop to cut a polygon in triangle on the fly (works only with convex faces)
		do
		{
			buffer.push_back(positions[d]);
			bufferColors.push_back(colorPerXXX[d]);
			buffer.push_back(positions[b]);
			bufferColors.push_back(colorPerXXX[b]);
			buffer.push_back(positions[c]);
			bufferColors.push_back(colorPerXXX[c]);
			b = c;
			c = map.phi1(b);
		} while (c != d);
	}

	m_nbTris = GLuint(buffer.size()/3);

	vboPosition.setDataSize(3);
	vboPosition.allocate(uint32(buffer.size()));
	VEC3F* ptrPos = reinterpret_cast<VEC3F*>(vboPosition.lockPtr());
	memcpy(ptrPos,&buffer[0],buffer.size()*sizeof(VEC3F));
	vboPosition.releasePtr();

	vboColor.setDataSize(3);
	vboColor.allocate(uint32(bufferColors.size()));
	VEC3F* ptrCol = reinterpret_cast<VEC3F*>(vboColor.lockPtr());
	memcpy(ptrCol,&bufferColors[0],bufferColors.size()*sizeof(VEC3F));
	vboColor.releasePtr();
}
Example #7
0
bool intersectionLineConvexFace(typename PFP::MAP& map, Face f, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position, const typename PFP::VEC3& P, const typename PFP::VEC3& Dir, typename PFP::VEC3& Inter)
{
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL;

	const REAL SMALL_NUM = std::numeric_limits<typename PFP::REAL>::min() * 5.0f;

	Dart d = f.dart;

	VEC3 p1 = position[d];
	VEC3 n = faceNormal<PFP>(map, d, position);
	VEC3 w0 = P - p1;
	REAL a = -(n*w0);
	REAL b = n*Dir;

    if (fabs(b) < SMALL_NUM)
		return false;

	REAL r = a / b;
	Inter = P + r * Dir;           // intersect point of ray and plane

    // is I inside the face?
	VEC3 p2 = position[map.phi1(d)];
	VEC3 v = p2 - p1 ;
	VEC3 vInter = Inter - p1;
	REAL dirV = v * vInter;
	if(fabs(dirV) < SMALL_NUM) // on an edge
		return true;

	Dart it = map.phi1(d);
	while(it != d)
	{
		p1 = p2;
		p2 = position[map.phi1(it)];
		v = p2 - p1;
		vInter = Inter - p1;
		REAL dirD = v * vInter;

		if(fabs(dirD) < SMALL_NUM) // on an edge
			return true;
		if((dirV > SMALL_NUM && dirD < SMALL_NUM) || (dirV < SMALL_NUM && dirD > SMALL_NUM)) //exterior of the face
			return false;
		it = map.phi1(it) ;
	}

    return true;
}
Example #8
0
typename PFP::REAL convexPolyhedronVolume(typename PFP::MAP& map, Vol v, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position)
{
    typedef typename PFP::MAP MAP;
    typedef typename PFP::VEC3 VEC3;

    if (Volume::Modelisation::Tetrahedralization::isTetrahedron<PFP>(map, v))
        return tetrahedronVolume<PFP>(map, v, position) ;
    else
    {
        typename PFP::REAL vol = 0 ;
        VEC3 vCentroid = Algo::Surface::Geometry::volumeCentroid<PFP>(map, v, position) ;

        DartMarkerStore<MAP> mark(map) ;	// Lock a marker

        std::vector<Face> visitedFaces ;
        visitedFaces.reserve(100) ;

        Face f(v.dart) ;
        visitedFaces.push_back(f) ;
        mark.markOrbit(f) ;

        for(unsigned int iface = 0; iface != visitedFaces.size(); ++iface)
        {
            f = visitedFaces[iface] ;
            if(map.isCycleTriangle(f))
            {
                VEC3 p1 = position[f.dart] ;
                VEC3 p2 = position[map.phi1(f)] ;
                VEC3 p3 = position[map.phi_1(f)] ;
                vol += Geom::tetraVolume(p1, p2, p3, vCentroid) ;
            }
            else
            {
                VEC3 fCentroid = Algo::Surface::Geometry::faceCentroid<PFP>(map, f, position) ;
                Dart d = f.dart ;
                do
                {
                    VEC3 p1 = position[d] ;
                    VEC3 p2 = position[map.phi1(d)] ;
                    vol += Geom::tetraVolume(p1, p2, fCentroid, vCentroid) ;
                    d = map.phi1(d) ;
                } while(d != f.dart) ;
            }
            Dart d = f.dart;
            do	// add all face neighbours to the table
            {
                Dart dd = map.phi2(d) ;
                if(!mark.isMarked(dd)) // not already marked
                {
                    Face ff(dd);
                    visitedFaces.push_back(ff) ;
                    mark.markOrbit(ff) ;
                }
                d = map.phi1(d) ;
            } while(d != f.dart) ;
        }

        return vol ;
    }
}
Example #9
0
void drawerAddEdgeShrink(Utils::Drawer& dr, typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& positions, const typename PFP::VEC3& C, float k)
{
	const typename  PFP::VEC3& P = positions[d];
	Dart e = map.phi1(d);
	const typename PFP::VEC3& Q = positions[e];

	dr.vertex(C*(1.0f-k) + k*P);
	dr.vertex(C*(1.0f-k) + k*Q);
}
Example #10
0
typename PFP::REAL convexFaceArea(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
{
	typedef typename PFP::VEC3 VEC3 ;

	if(map.faceDegree(d) == 3)
		return triangleArea<PFP>(map, d, position) ;
	else
	{
		float area = 0.0f ;
		VEC3 centroid = Algo::Geometry::faceCentroid<PFP>(map, d, position) ;
		Traversor2FE<typename PFP::MAP> t(map, d) ;
		for(Dart it = t.begin(); it != t.end(); it = t.next())
		{
			VEC3 p1 = position[it] ;
			VEC3 p2 = position[map.phi1(it)] ;
			area += Geom::triangleArea(p1, p2, centroid) ;
		}
		return area ;
	}
}
Example #11
0
void mergeVertex(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, Dart d, Dart e, int precision)
{
	assert(positions[d].isNear(positions[e], precision) && !map.sameVertex(d, e)) ;

	bool notempty = true ;
	do // While vertex of e contains more than one dart
	{
		Dart e1 = map.alpha1(e) ;			// e1 stores next dart of vertex of e
		if (e1 == e)
			notempty = false ;				// last dart of vertex of e
		else
		{
			map.removeEdgeFromVertex(e) ;	// detach e from its vertex
		}
		// Searchs where e may be inserted in the vertex of d
		Dart d1 = d ;
		do
		{
			if (isBetween<PFP>(map, positions, e, d, map.alpha1(d)))
				break ;
			d = map.alpha1(d) ;
		} while (d != d1) ;

		// Inserted e in the correct place (after d)
		map.insertEdgeInVertex(d, e) ;

		// Go on with next darts
		d = e ;
		e = e1 ;
	} while (notempty) ;
}
Example #12
0
bool intersectionSphereEdge(typename PFP::MAP& map, const typename PFP::VEC3& center, typename PFP::REAL radius, Edge e, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position, typename PFP::REAL& alpha)
{
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL ;

	const VEC3& p1 = position[e.dart];
	const VEC3& p2 = position[map.phi1(e.dart)];
	if(Geom::isPointInSphere(p1, center, radius) && !Geom::isPointInSphere(p2, center, radius))
	{
		VEC3 p = p1 - center;
		VEC3 qminusp = p2 - center - p;
		REAL s = p * qminusp;
		REAL n2 = qminusp.norm2();
		alpha = (- s + sqrt(s*s + n2 * (radius*radius - p.norm2()))) / n2;
		return true ;
	}
	return false ;
}
Example #13
0
typename V_ATT::DATA_TYPE localvolumeCentroidELW(typename PFP::MAP& map, Vol d, const V_ATT& attributs)
{
	typedef typename V_ATT::DATA_TYPE EMB;
	EMB center(0.0);

	double count=0.0;

	for (Edge it : edgesIncidentToVolume3(map,d))
	{
		EMB e1 = attributs[it.dart];
		EMB e2 = attributs[map.phi1(it)];
		double l = (e2-e1).norm();
		center += (e1+e2)*l;
		count += 2.0*l ;
	}
	center /= double(count);
	return center ;
}
Example #14
0
bool areTrianglesInIntersection(typename PFP::MAP& map, Face t1, Face t2, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& position)
{
	typedef typename PFP::VEC3 VEC3 ;
	typedef typename PFP::REAL REAL;

	Dart tri1 = t1.dart;
	Dart tri2 = t2.dart;

	//get vertices position
	VEC3 tris1[3];
	VEC3 tris2[3];
	for (unsigned int i = 0; i < 3; ++i)
	{
		tris1[i] = position[tri1];
		tris2[i] = position[tri2];
		tri1 = map.phi1(tri1);
		tri2 = map.phi1(tri2);
	}

// 	gmtl::Vec3f nTri1,nTri2;
//	float offset1,offset2;
// 	CGoGN::Algo::Geometry::trianglePlane<PFP>(map,tri1,nTri1,offset1);
// 	CGoGN::Algo::Geometry::trianglePlane<PFP>(map,tri2,nTri2,offset2);
//
// 	Orientation3D oP[2][3];
// 	oP[0][0] = testOrientation3D(tris2[0],offset1,nTri1);
// 	oP[0][1] = testOrientation3D(tris2[1],offset1,nTri1);
// 	oP[0][2] = testOrientation3D(tris2[2],offset1,nTri1);
//
// 	if(oP[0][0]==oP[0][1] && oP[0][1]==oP[0][2]) {
// 		if(oP[0][0]==ON) { //coplanar triangles
// 			return isSegmentInTriangle2D(tris1[0],tris1[1],tris2[0],tris2[1],triS2[2],nTri2)
// 			||  isSegmentInTriangle2D(tris1[1],tris1[2],tris2[0],tris2[1],triS2[2],nTri2)
// 			|| isSegmentInTriangle2D(tris1[2],tris1[0],tris2[0],tris2[1],triS2[2],nTri2);
// 		}
// 		else
// 			return false;
// 	}
//
// 	oP[1][0] = testOrientation3D(tris1[0],offset2,nTri2);
// 	oP[1][1] = testOrientation3D(tris1[1],offset2,nTri2);
// 	oP[1][2] = testOrientation3D(tris1[2],offset2,nTri2);
//
// 	if(oP[1][0]==oP[1][1] && oP[1][1]==oP[1][2])
// 		return false;
//
// 	//search segment of tri 1 in plane of tri 2
// 	gmtl::Point3f inter1,inter2;
// 	bool found = false;
// 	for(unsigned int i=0;i<3 && !found;++i) {
// 		//test if the first point is the one opposite to the two others
// 		if(oP[0][i]!=oP[0][(1+i)%3] && oP[0][(1+i)%3]==oP[0][(2+i)%3]) {
// 			found=true;
// 			//search collision points with the two edges
// 			float offset= gmtl::dot(tris2[0],nTri2);
// 			gmtl::Planef pl(nTri2,offset);
//
// 			gmtl::Vec3f dir1(oP[0][(1+i)%3]);
// 			dir1 -= oP[0][i];
//
// 			gmtl::Vec3f dir2(oP[0][(2+i)%3]);
// 			dir2 -= oP[0][i];
//
// 			inter1 = gmtl::intersect(pl,gmtl::Ray(oP[0][i],dir1));
// 			inter2 = gmtl::intersect(pl,gmtl::Ray(oP[0][i],dir2));
// 		}
// 	}
//
// 	return isSegmentInTriangle2D(inter1,inter2,tris2[0],tris2[1],triS2[2],nTri2);

	//compute face normal
	VEC3 normale1 = faceNormal<PFP>(map, t1, position);
	VEC3 bary1 = faceCentroid<PFP>(map, t1, position);

	int pos = 0;
	int neg = 0;
	//test position of points relative to first tri
	for (unsigned int i = 0; i < 3 ; ++i)
	{
		VEC3 nTest = bary1 - tris2[i];
		REAL scal = nTest * normale1;
		if (scal < 0)
			++neg;
		if (scal > 0)
			++pos;
	}

	//if all pos or neg then no intersection
	if (neg == 3 || pos == 3)
		return false;

	//same for the second triangle
	VEC3 normale2 = faceNormal<PFP>(map, t2, position);
	VEC3 bary2 = faceCentroid<PFP>(map, t2, position);
	pos = 0;
	neg = 0;
	for (unsigned int i = 0; i < 3 ; ++i)
	{
		VEC3 nTest = bary2 - tris1[i];
		REAL scal = nTest * normale2;
		if (scal<0)
			++neg;
		if (scal>0)
			++pos;
	}

	if (neg == 3 || pos == 3)
		return false;

	bool intersection = false;

	for (unsigned int i = 0; i < 3 && !intersection; ++i)
	{
		VEC3 inter;
		intersection = Geom::intersectionSegmentTriangle(tris1[i], tris1[(i + 1) % 3], tris2[0], tris2[1], tris2[2], inter) != Geom::NO_INTERSECTION;
	}

	if (intersection)
		return true;

	for (unsigned int i = 0; i < 3 && !intersection; ++i)
	{
		VEC3 inter;
		intersection = Geom::intersectionSegmentTriangle(tris2[i], tris2[(i + 1) % 3], tris1[0], tris1[1], tris1[2], inter) != Geom::NO_INTERSECTION;
	}

	return intersection;
}
Example #15
0
bool importOFFWithELERegions(typename PFP::MAP& map, const std::string& filenameOFF, const std::string& filenameELE, std::vector<std::string>& attrNames)
{
	typedef typename PFP::VEC3 VEC3;

	VertexAttribute<VEC3> position = map.template addAttribute<VEC3, VERTEX>("position") ;
	attrNames.push_back(position.name()) ;

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

	unsigned int m_nbVertices = 0, m_nbFaces = 0, m_nbEdges = 0, m_nbVolumes = 0;

	VertexAutoAttribute< NoMathIONameAttribute< std::vector<Dart> > > vecDartsPerVertex(map, "incidents");

	// open files
	std::ifstream foff(filenameOFF.c_str(), std::ios::in);
	if (!foff.good())
	{
		CGoGNerr << "Unable to open OFF file " << CGoGNendl;
		return false;
	}

	std::ifstream fele(filenameELE.c_str(), std::ios::in);
	if (!fele.good())
	{
		CGoGNerr << "Unable to open ELE file " << CGoGNendl;
		return false;
	}

	std::string line;

	//OFF reading
	std::getline(foff, line);
	if(line.rfind("OFF") == std::string::npos)
	{
		CGoGNerr << "Problem reading off file: not an off file"<<CGoGNendl;
		CGoGNerr << line << CGoGNendl;
		return false;
	}

	//Reading number of vertex/faces/edges in OFF file
	unsigned int nbe;
	{
		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
	unsigned int nbv;
	{
		do
		{
			std::getline(fele,line);
		}while(line.size() == 0);

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

	CGoGNout << "nb points = " << m_nbVertices << " / nb faces = " << m_nbFaces << " / nb edges = " << m_nbEdges << " / nb tet = " << m_nbVolumes << CGoGNendl;

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

	for(unsigned int i = 0 ; i < m_nbVertices ; ++i)
	{
		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);

		unsigned int id = container.insertLine();
		position[id] = pos;
		verticesID.push_back(id);
	}

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

	DartMarkerNoUnmark m(map) ;

	//Read and embed tetrahedra TODO
	for(unsigned i = 0; i < m_nbVolumes ; ++i)
	{
		do
		{
			std::getline(fele,line);
		} while(line.size() == 0);

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

		Dart d = Algo::Modelisation::createTetrahedron<PFP>(map);
		Geom::Vec4ui pt;
		oss >> pt[0];
		oss >> pt[1];
		oss >> pt[2];
		oss >> pt[3];

		//regions ?
		oss >> nbe;

		// Embed three vertices
		for(unsigned int j = 0 ; j < 3 ; ++j)
		{
			FunctorSetEmb<typename PFP::MAP, VERTEX> fsetemb(map, verticesID[pt[2-j]]);
			map.template foreach_dart_of_orbit<PFP::MAP::VERTEX_OF_PARENT>(d, fsetemb);

			//store darts per vertices to optimize reconstruction
			Dart dd = d;
			do
			{
				m.mark(dd) ;
				vecDartsPerVertex[pt[2-j]].push_back(dd);
				dd = map.phi1(map.phi2(dd));
			} while(dd != d);

			d = map.phi1(d);

		}

		//Embed the last vertex
		d = map.phi_1(map.phi2(d));

		FunctorSetEmb<typename PFP::MAP, VERTEX> fsetemb(map, verticesID[pt[3]]);
		map.template foreach_dart_of_orbit<PFP::MAP::VERTEX_OF_PARENT>(d, fsetemb);

		//store darts per vertices to optimize reconstruction
		Dart dd = d;
		do
		{
			m.mark(dd) ;
			vecDartsPerVertex[pt[3]].push_back(dd);
			dd = map.phi1(map.phi2(dd));
		} while(dd != d);

	}

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

	//Association des phi3
	unsigned int nbBoundaryFaces = 0 ;
	for (Dart d = map.begin(); d != map.end(); map.next(d))
	{
		if (m.isMarked(d))
		{
			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)
			{
				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)) */)
				{
					good_dart = *it ;
				}
			}

			if (good_dart != NIL)
			{
				map.sewVolumes(d, good_dart, false);
				m.template unmarkOrbit<FACE>(d);
			}
			else
			{
				m.template unmarkOrbit<PFP::MAP::FACE_OF_PARENT>(d);
				++nbBoundaryFaces;
			}
		}
	}

	if (nbBoundaryFaces > 0)
	{
		std::cout << "closing" << std::endl ;
		map.closeMap();
		CGoGNout << "Map closed (" << nbBoundaryFaces << " boundary faces)" << CGoGNendl;
	}

	return true;
}
Example #16
0
bool isBetween(typename PFP::MAP& map, const VertexAttribute<typename PFP::VEC3, typename PFP::MAP>& positions, Dart d, Dart e, Dart f)
{
	return CGoGN::Geom::isBetween(positions[map.phi1(d)]-positions[d],
	                 positions[map.phi1(e)]-positions[e],
	                 positions[map.phi1(f)]-positions[f]);
}