示例#1
0
GenericIndexedMesh* Neighbourhood::triangulateOnPlane(bool duplicateVertices/*=false*/, PointCoordinateType maxEdgeLength/*=0*/)
{
	if (m_associatedCloud->size()<CC_LOCAL_MODEL_MIN_SIZE[TRI])
	{
		//can't compute LSF plane with less than 3 points!
		return 0;
	}

	//project the points on this plane
	GenericIndexedMesh* mesh = 0;
	std::vector<CCVector2> points2D;

	if (projectPointsOn2DPlane<CCVector2>(points2D))
	{
		Delaunay2dMesh* dm = new Delaunay2dMesh();

		//triangulate the projected points
		if (!dm->build(points2D,0))
		{
			delete dm;
			return 0;
		}

		//change the default mesh's reference
		if (duplicateVertices)
		{
			ChunkedPointCloud* cloud = new ChunkedPointCloud();
			unsigned count = m_associatedCloud->size();
			if (!cloud->reserve(count))
			{
				delete dm;
				delete cloud;
				return 0;
			}
			for (unsigned i=0; i<count; ++i)
				cloud->addPoint(*m_associatedCloud->getPoint(i));
			dm->linkMeshWith(cloud,true);
		}
		else
		{
			dm->linkMeshWith(m_associatedCloud,false);
		}

		//remove triangles with too long edges
		if (maxEdgeLength > 0)
		{
			dm->removeTrianglesLongerThan(maxEdgeLength);
			if (dm->size() == 0)
			{
				//no more triangles?
				delete dm;
				dm = 0;
			}
		}
		mesh = static_cast<GenericIndexedMesh*>(dm);
	}

	return mesh;
}
示例#2
0
GenericIndexedMesh* Neighbourhood::triangulateFromQuadric(unsigned nStepX, unsigned nStepY)
{
	if (nStepX<2 || nStepY<2)
		return 0;

	//qaudric fit
	const PointCoordinateType* Q = getQuadric(); //Q: Z = a + b.X + c.Y + d.X^2 + e.X.Y + f.Y^2
	if (!Q)
		return 0;

	const PointCoordinateType& a = Q[0];
	const PointCoordinateType& b = Q[1];
	const PointCoordinateType& c = Q[2];
	const PointCoordinateType& d = Q[3];
	const PointCoordinateType& e = Q[4];
	const PointCoordinateType& f = Q[5];

	const uchar X = m_quadricEquationDirections.x;
	const uchar Y = m_quadricEquationDirections.y;
	const uchar Z = m_quadricEquationDirections.z;

	//gravity center (should be ok if the quadric is ok)
	const CCVector3* G = getGravityCenter();
	assert(G);

	//bounding box
	CCVector3 bbMin, bbMax;
	m_associatedCloud->getBoundingBox(bbMin,bbMax);
	CCVector3 bboxDiag = bbMax - bbMin;

	//Sample points on Quadric and triangulate them!
	PointCoordinateType spanX = bboxDiag.u[X];
	PointCoordinateType spanY = bboxDiag.u[Y];
	PointCoordinateType stepX = spanX/(nStepX-1);
	PointCoordinateType stepY = spanY/(nStepY-1);

	ChunkedPointCloud* vertices = new ChunkedPointCloud();
	if (!vertices->reserve(nStepX*nStepY))
	{
		delete vertices;
		return 0;
	}

	SimpleMesh* quadMesh = new SimpleMesh(vertices,true);
	if (!quadMesh->reserve((nStepX-1)*(nStepY-1)*2))
	{
		delete quadMesh;
		return 0;
	}

	for (unsigned x=0; x<nStepX; ++x)
	{
		CCVector3 P;
		P.x = bbMin[X] + stepX * x - G->u[X];
		for (unsigned y=0; y<nStepY; ++y)
		{
			P.y = bbMin[Y] + stepY * y - G->u[Y];
			P.z = a+b*P.x+c*P.y+d*P.x*P.x+e*P.x*P.y+f*P.y*P.y;

			CCVector3 Pc;
			Pc.u[X] = P.x;
			Pc.u[Y] = P.y;
			Pc.u[Z] = P.z;
			Pc += *G;

			vertices->addPoint(Pc);

			if (x>0 && y>0)
			{
				unsigned iA = (x-1) * nStepY + y-1;
				unsigned iB = iA+1;
				unsigned iC = iA+nStepY;
				unsigned iD = iB+nStepY;

				quadMesh->addTriangle(iA,iC,iB);
				quadMesh->addTriangle(iB,iC,iD);
			}
		}
	}

	return quadMesh;
}
示例#3
0
GenericIndexedMesh* Neighbourhood::triangulateOnPlane(	bool duplicateVertices/*=false*/,
														PointCoordinateType maxEdgeLength/*=0*/,
														char* errorStr/*=0*/)
{
	if (m_associatedCloud->size() < CC_LOCAL_MODEL_MIN_SIZE[TRI])
	{
		//can't compute LSF plane with less than 3 points!
		if (errorStr)
			strcpy(errorStr,"Not enough points");
		return 0;
	}

	//safety check: Triangle lib will crash if the points are all the same!
	if (computeLargestRadius() < ZERO_TOLERANCE)
	{
		return 0;
	}

	//project the points on this plane
	GenericIndexedMesh* mesh = 0;
	std::vector<CCVector2> points2D;

	if (projectPointsOn2DPlane<CCVector2>(points2D))
	{
		Delaunay2dMesh* dm = new Delaunay2dMesh();

		//triangulate the projected points
		if (!dm->buildMesh(points2D,0,errorStr))
		{
			delete dm;
			return 0;
		}

		//change the default mesh's reference
		if (duplicateVertices)
		{
			ChunkedPointCloud* cloud = new ChunkedPointCloud();
			unsigned count = m_associatedCloud->size();
			if (!cloud->reserve(count))
			{
				if (errorStr)
					strcpy(errorStr,"Not enough memory");
				delete dm;
				delete cloud;
				return 0;
			}
			for (unsigned i=0; i<count; ++i)
				cloud->addPoint(*m_associatedCloud->getPoint(i));
			dm->linkMeshWith(cloud,true);
		}
		else
		{
			dm->linkMeshWith(m_associatedCloud,false);
		}

		//remove triangles with too long edges
		if (maxEdgeLength > 0)
		{
			dm->removeTrianglesWithEdgesLongerThan(maxEdgeLength);
			if (dm->size() == 0)
			{
				//no more triangles?
				if (errorStr)
					strcpy(errorStr,"Not triangle left after pruning");
				delete dm;
				dm = 0;
			}
		}
		mesh = static_cast<GenericIndexedMesh*>(dm);
	}

	return mesh;
}