예제 #1
0
bool Delaunay2dMesh::buildMesh(	const std::vector<CCVector2>& points2D,
								size_t pointCountToUse/*=0*/,
								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::Triangulation_data_structure_2<Vb> Tds;
	typedef CGAL::Delaunay_triangulation_2<K, Tds> DT;
	typedef DT::Point cgalPoint;

	std::vector< std::pair<cgalPoint, size_t > > pts;
	size_t pointCount = points2D.size();

	//we will use at most 'pointCountToUse' points (if not 0)
	if (pointCountToUse > 0 && pointCountToUse < pointCount)
	{
		pointCount = pointCountToUse;
	}

	if (pointCount < 3)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr, "Not enough points");
		return false;
	}

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

	m_numberOfTriangles = 0;
	if (m_triIndexes)
	{
		delete[] m_triIndexes;
		m_triIndexes = 0;
	}

	for(size_t i = 0; i < pointCount; ++i) {
		const CCVector2 * pt = &points2D[i];
		pts.push_back(std::make_pair(cgalPoint(pt->x, pt->y), i));
	}

	//The delaunay triangulation is built according to the 2D point cloud
	DT dt(pts.begin(), pts.end());

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

	//The cgal data structure is converted into CC one
	if (m_numberOfTriangles > 0) {
		int faceCount = 0;
		for (DT::Face_iterator face = dt.faces_begin(); face != dt.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,
								size_t pointCountToUse/*=0*/,
								char* outputErrorStr/*=0*/)
{
#if defined(USE_TRIANGLE_LIB)

	size_t pointCount = points2D.size();
	//we will use at most 'pointCountToUse' points (if not 0)
	if (pointCountToUse > 0 && pointCountToUse < pointCount)
	{
		pointCount = pointCountToUse;
	}
	if (pointCount < 3)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr, "Not enough points");
		return false;
	}

	//reset
	m_numberOfTriangles = 0;
	if (m_triIndexes)
	{
		delete[] m_triIndexes;
		m_triIndexes = 0;
	}

	//we use the external library 'Triangle'
	triangulateio in;
	memset(&in,0,sizeof(triangulateio));

	in.numberofpoints = static_cast<int>(pointCount);
	in.pointlist = (REAL*)(&points2D[0]);

	//set static variable for 'triunsuitable' (for Triangle lib with '-u' option)
	//s_maxSquareEdgeLength = maxEdgeLength*maxEdgeLength;
	//DGM: doesn't work this way --> triangle lib will simply add new points!
	try 
	{ 
		triangulate ( "zQN", &in, &in, 0 );
	}
	catch (std::exception& e) 
	{
		if (outputErrorStr)
			strcpy(outputErrorStr,e.what());
		return false;
	} 
	catch (...) 
	{
		if (outputErrorStr)
			strcpy(outputErrorStr,"Unknown error");
		return false;
	} 

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

	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::Triangulation_data_structure_2<Vb> Tds;
	typedef CGAL::Delaunay_triangulation_2<K, Tds> DT;
	typedef DT::Point cgalPoint;

	std::vector< std::pair<cgalPoint, size_t > > pts;
	size_t pointCount = points2D.size();

	//we will use at most 'pointCountToUse' points (if not 0)
	if (pointCountToUse > 0 && pointCountToUse < pointCount)
	{
		pointCount = pointCountToUse;
	}

	if (pointCount < 3)
	{
		if (outputErrorStr)
			strcpy(outputErrorStr, "Not enough points");
		return false;
	}

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

	m_numberOfTriangles = 0;
	if (m_triIndexes)
	{
		delete[] m_triIndexes;
		m_triIndexes = 0;
	}

	for(size_t i = 0; i < pointCount; ++i) {
		const CCVector2 * pt = &points2D[i];
		pts.push_back(std::make_pair(cgalPoint(pt->x, pt->y), i));
	}

	//The delaunay triangulation is built according to the 2D point cloud
	DT dt(pts.begin(), pts.end());

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

	//The cgal data structure is converted into CC one
	if (m_numberOfTriangles > 0) {
		int faceCount = 0;
		for (DT::Face_iterator face = dt.faces_begin(); face != dt.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, "Please link CC lib with either Triangle or CGAL");
	return false;

#endif
}