Пример #1
0
bool Delaunay2dMesh::buildMesh(	const std::vector<CCVector2>& points2D,
								const std::vector<int>& segments2D,
								char* outputErrorStr/*=0*/)
{
#if defined(USE_CGAL_LIB)

	//CGAL boilerplate
	typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
	//We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index.
	typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb;
	typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
	typedef CGAL::No_intersection_tag  Itag; //This tag could ben changed if we decide to handle intersection
	typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
	typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT;
	typedef CDT::Point cgalPoint;

	std::vector< std::pair<cgalPoint, size_t > > constraints;
	size_t constrCount = segments2D.size();

	try
	{
		constraints.reserve(constrCount);
	} catch (const std::bad_alloc&)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr, "Not enough memory");
		return false;
	};

	//We create the Constrained Delaunay Triangulation (CDT)
	CDT cdt;

	//We build the constraints
	for(size_t i = 0; i < constrCount; ++i) {
		const CCVector2 * pt = &points2D[segments2D[i]];
		constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i]));
	}
	//The CDT  is built according to the constraints
	cdt.insert(constraints.begin(), constraints.end());

	m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces());
	m_triIndexes = new int[cdt.number_of_faces()*3];

	//The cgal data structure is converted into CC one
	if (m_numberOfTriangles > 0) {
		int faceCount = 0;
		for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) {
			m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info());
			m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info());
			m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info());
		};
	}

	m_globalIterator = m_triIndexes;
	m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles;
	return true;

#else

	if (outputErrorStr)
		strcpy(outputErrorStr, "CGAL library not supported");
	return false;

#endif
}
Пример #2
0
bool Delaunay2dMesh::buildMesh(	const std::vector<CCVector2>& points2D,
								const std::vector<int>& segments2D,
								char* outputErrorStr/*=0*/)
{
#if defined(USE_TRIANGLE_LIB)
	//we use the external library 'Triangle'
	triangulateio in;
	memset(&in,0,sizeof(triangulateio));

	in.numberofpoints = static_cast<int>(points2D.size());
	in.pointlist = (REAL*)(&points2D[0]);
	in.segmentlist = (int*)(&segments2D[0]);
	assert((segments2D.size() & 1) == 0);
	in.numberofsegments = static_cast<int>(segments2D.size()/2);

	triangulateio out;
	memset(&out,0,sizeof(triangulateio));

	try 
	{ 
		triangulate ( "pczBPNIOQY", &in, &out, 0 );
	}
	catch (std::exception& e)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr,e.what());
		return false;
	} 
	catch (...) 
	{
		if (outputErrorStr)
			strcpy(outputErrorStr,"Unknown error");
		return false;
	} 

	m_numberOfTriangles = out.numberoftriangles;
	if (m_numberOfTriangles > 0)
	{
		m_triIndexes = out.trianglelist;

		//remove non existing points
		int* _tri = out.trianglelist;
		for (int i=0; i<out.numberoftriangles; )
		{
			if (	_tri[0] >= in.numberofpoints
				||	_tri[1] >= in.numberofpoints
				||	_tri[2] >= in.numberofpoints)
			{
				int lasTriIndex = (out.numberoftriangles-1) * 3;
				_tri[0] = out.trianglelist[lasTriIndex + 0]; 
				_tri[1] = out.trianglelist[lasTriIndex + 1]; 
				_tri[2] = out.trianglelist[lasTriIndex + 2]; 
				--out.numberoftriangles;
			}
			else
			{
				_tri += 3;
				++i;
			}
		}

		//Reduce memory size
		if (out.numberoftriangles < static_cast<int>(m_numberOfTriangles))
		{
			assert(out.numberoftriangles > 0);
			realloc(m_triIndexes, sizeof(int)*out.numberoftriangles*3);
			m_numberOfTriangles = out.numberoftriangles;
		}
	}

	trifree(out.segmentmarkerlist);
	trifree(out.segmentlist);

	m_globalIterator = m_triIndexes;
	m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles;

	return true;

#elif defined(USE_CGAL_LIB)

	//CGAL boilerplate
	typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
	//We define a vertex_base with info. The "info" (size_t) allow us to keep track of the original point index.
	typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, K> Vb;
	typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
	typedef CGAL::No_intersection_tag  Itag; //This tag could ben changed if we decide to handle intersection
	typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
	typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> CDT;
	typedef CDT::Point cgalPoint;

	std::vector< std::pair<cgalPoint, size_t > > constraints;
	size_t constrCount = segments2D.size();

	try
	{
		constraints.reserve(constrCount);
	} catch (const std::bad_alloc&)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr, "Not enough memory");
		return false;
	};

	//We create the Constrained Delaunay Triangulation (CDT)
	CDT cdt;

	//We build the constraints
	for(size_t i = 0; i < constrCount; ++i) {
		const CCVector2 * pt = &points2D[segments2D[i]];
		constraints.push_back(std::make_pair(cgalPoint(pt->x, pt->y), segments2D[i]));
	}
	//The CDT  is built according to the constraints
	cdt.insert(constraints.begin(), constraints.end());

	m_numberOfTriangles = static_cast<unsigned >(cdt.number_of_faces());
	m_triIndexes = new int[cdt.number_of_faces()*3];

	//The cgal data structure is converted into CC one
	if (m_numberOfTriangles > 0) {
		int faceCount = 0;
		for (CDT::Face_iterator face = cdt.faces_begin(); face != cdt.faces_end(); ++face, faceCount+=3) {
			m_triIndexes[0+faceCount] = static_cast<int>(face->vertex(0)->info());
			m_triIndexes[1+faceCount] = static_cast<int>(face->vertex(1)->info());
			m_triIndexes[2+faceCount] = static_cast<int>(face->vertex(2)->info());
		};
	}

	m_globalIterator = m_triIndexes;
	m_globalIteratorEnd = m_triIndexes + 3*m_numberOfTriangles;
	return true;

#else

	if (outputErrorStr)
		strcpy(outputErrorStr, "Triangle library not supported");
	return false;

#endif
}