Пример #1
0
bool ccPlane::buildUp()
{
	if (!init(4,false,2,1))
	{
		ccLog::Error("[ccPlane::buildUp] Not enough memory");
		return false;
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	verts->addPoint(CCVector3(-m_xWidth*0.5f,-m_yWidth*0.5f, 0));
	verts->addPoint(CCVector3(-m_xWidth*0.5f, m_yWidth*0.5f, 0));
	verts->addPoint(CCVector3( m_xWidth*0.5f, m_yWidth*0.5f, 0));
	verts->addPoint(CCVector3( m_xWidth*0.5f,-m_yWidth*0.5f, 0));

	m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,1.0).u));

	addTriangle(0,2,1);
	addTriangleNormalIndexes(0,0,0);
	addTriangle(0,3,2);
	addTriangleNormalIndexes(0,0,0);

	return true;
}
Пример #2
0
bool ccTorus::buildUp()
{
	if (m_drawPrecision<4)
		return false;

	//invalid parameters?
	if ((m_rectSection && m_rectSectionHeight < ZERO_TOLERANCE) || m_insideRadius >= m_outsideRadius || m_angle_rad < ZERO_TOLERANCE)
		return false;

	//topology
	bool closed = (m_angle_rad >= 2.0*M_PI);

	const unsigned steps = m_drawPrecision;

	unsigned sweepSteps = 4*(closed ? steps : (unsigned)ceil(m_angle_rad*(double)steps/(2.0*M_PI)));
	unsigned sectSteps = (m_rectSection ? 4 : steps);

	//vertices
	unsigned vertCount = (sweepSteps+(closed ? 0 : 1))*sectSteps; //DGM: +1 row for non closed loops
	//faces
	unsigned facesCount = sweepSteps*sectSteps*2;
	//faces normals
	unsigned faceNormCount = (sweepSteps+(closed ? 0 : 1))*sectSteps; //DGM: +1 row for non closed loops
	if (!closed)
		facesCount += (m_rectSection ? 2 : sectSteps)*2;

	if (!init(vertCount+(closed || m_rectSection ? 0 : 2),false,facesCount,faceNormCount+(closed ? 0 : 2)))
	{
		ccLog::Error("[ccTorus::buildUp] Not enough memory");
		return false;
	}

	//2D section
	CCVector3* sectPoints = new CCVector3[sectSteps];
	if (!sectPoints)
	{
		init(0,false,0,0);
		ccLog::Error("[ccTorus::buildUp] Not enough memory");
		return false;
	}

	PointCoordinateType sectionRadius = (m_outsideRadius-m_insideRadius)/2;
	if (m_rectSection)
	{
		//rectangular section
		sectPoints[0].x = (m_outsideRadius-m_insideRadius)/2;
		sectPoints[0].z = m_rectSectionHeight/2;
		sectPoints[1].x = -sectPoints[0].x;
		sectPoints[1].z = sectPoints[0].z;
		sectPoints[2].x = sectPoints[1].x;
		sectPoints[2].z = -sectPoints[1].z;
		sectPoints[3].x = -sectPoints[2].x;
		sectPoints[3].z = sectPoints[2].z;
	}
	else
	{
		//circular section
		for (unsigned i=0;i<sectSteps;++i)
		{
			float sect_angle_rad = (float)i/(float)sectSteps*(float)(2.0*M_PI);
			sectPoints[i].x = cos(sect_angle_rad) * sectionRadius;
			sectPoints[i].z = sin(sect_angle_rad) * sectionRadius;
		}
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	//main sweep
	PointCoordinateType sweepRadius = (m_insideRadius+m_outsideRadius)/(PointCoordinateType)2.0;
	double sweepStep_rad = m_angle_rad/(double)sweepSteps;
	for (unsigned t=0; t<(closed ? sweepSteps : sweepSteps+1); ++t)
	{
		//unit director vector
		CCVector3 sweepU(static_cast<PointCoordinateType>(cos(t*sweepStep_rad)),
						 static_cast<PointCoordinateType>(sin(t*sweepStep_rad)),
						 0);

		//section points
		for (unsigned i=0;i<sectSteps;++i)
		{
			CCVector3 P(sweepU.x * (sweepRadius + sectPoints[i].x),
						sweepU.y * (sweepRadius + sectPoints[i].x),
						sectPoints[i].z);
			verts->addPoint(P);
		}

		//normals
		if (m_rectSection)
		{
			m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,1.0).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex((-sweepU).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,-1.0).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex((-sweepU).u));
		}
		else //circular section
		{
			for (unsigned i=0;i<sectSteps;++i)
			{
				float sectAngle_rad = (float)i/(float)sectSteps*(float)(2.0*M_PI);
				CCVector3 sectU(cos(sectAngle_rad),0.0,sin(sectAngle_rad));
				CCVector3 N(sweepU.x * sectU.x,
					sweepU.y * sectU.x,
					sectU.z);
				m_triNormals->addElement(ccNormalVectors::GetNormIndex(N.u));
			}
		}
	}

	if (!closed && !m_rectSection)
	{
		CCVector3 P(sweepRadius,0,0);
		verts->addPoint(P);
		CCVector3 P2(	static_cast<PointCoordinateType>(cos(m_angle_rad))*sweepRadius,
						static_cast<PointCoordinateType>(sin(m_angle_rad))*sweepRadius,
						 0);
		verts->addPoint(P2);
	}

	if (!closed)
	{
		//first section (left side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0,-1,0).u));
		//last section (right side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(	static_cast<PointCoordinateType>(-sin(m_angle_rad)),
																			static_cast<PointCoordinateType>(cos(m_angle_rad)),
																			0).u));
	}

	delete[] sectPoints;
	sectPoints=0;

	//mesh faces
	{
		assert(m_triVertIndexes);

		for (unsigned t=0;t<sweepSteps;++t)
		{
			unsigned sweepStart = t*sectSteps;
			for (unsigned i=0;i<sectSteps;++i)
			{
				unsigned iNext = (i+1)%sectSteps;
				addTriangle(sweepStart+i,(sweepStart+i+sectSteps)%vertCount,(sweepStart+iNext+sectSteps)%vertCount);
				if (m_rectSection)
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,(sweepStart+i+sectSteps)%faceNormCount);
				else
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,(sweepStart+iNext+sectSteps)%faceNormCount);
				addTriangle(sweepStart+i,(sweepStart+iNext+sectSteps)%vertCount,sweepStart+iNext);
				if (m_rectSection)
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,sweepStart+i);
				else
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+iNext+sectSteps)%faceNormCount,sweepStart+iNext);
			}
		}

		if (!closed)
		{
			unsigned lastSectionShift = sweepSteps*sectSteps;
			if (m_rectSection)
			{
				//rectangular left section
				addTriangle(0,1,2);
				addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				addTriangle(0,2,3);
				addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				//rectangular right section
				addTriangle(lastSectionShift,lastSectionShift+2,lastSectionShift+1);
				addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
				addTriangle(lastSectionShift,lastSectionShift+3,lastSectionShift+2);
				addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
			}
			else
			{
				unsigned lastSectionCenterShift = vertCount;
				//circular 'left' section
				for (unsigned i=0;i<sectSteps;++i)
				{
					unsigned iNext = (i+1)%sectSteps;
					addTriangle(lastSectionCenterShift,i,iNext);
					addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				}
				//circular 'right' section
				for (unsigned i=0;i<sectSteps;++i)
				{
					unsigned iNext = (i+1)%sectSteps;
					addTriangle(lastSectionCenterShift+1,lastSectionShift+iNext,lastSectionShift+i);
					addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
				}
			}
		}
	}

	notifyGeometryUpdate();
	showTriNorms(true);

	return true;
}
Пример #3
0
bool ccExtru::buildUp()
{
	unsigned count = static_cast<unsigned>(m_profile.size());
	if (count < 3)
		return false;

	CCLib::Delaunay2dMesh mesh;

	//DGM: we check that last vertex is different from the first one!
	//(yes it happens ;)
	if (m_profile.back().x == m_profile.front().x &&  m_profile.back().y == m_profile.front().y)
		--count;

	char errorStr[1024];
	if (!mesh.buildMesh(m_profile,count,errorStr))
	{
		ccLog::Warning(QString("[ccPlane::buildUp] Profile triangulation failed (CClib said: '%1'").arg(errorStr));
		return false;
	}

	unsigned numberOfTriangles = mesh.size();
	int* triIndexes = mesh.getTriangleVertIndexesArray();

	if (numberOfTriangles == 0)
		return false;

	//vertices
	unsigned vertCount = 2*count;
	//faces
	unsigned faceCount = 2*numberOfTriangles+2*count;
	//faces normals
	unsigned faceNormCount = 2+count;

	if (!init(vertCount,false,faceCount,faceNormCount))
	{
		ccLog::Error("[ccPlane::buildUp] Not enough memory");
		return false;
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	//bottom & top faces normals
	m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,-1.0).u));
	m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,1.0).u));

	//add profile vertices & normals
	for (unsigned i=0;i<count;++i)
	{
		const CCVector2& P = m_profile[i];
		verts->addPoint(CCVector3(P.x,P.y,0));
		verts->addPoint(CCVector3(P.x,P.y,m_height));

		const CCVector2& PNext = m_profile[(i+1)%count];
		CCVector2 N(-(PNext.y-P.y),PNext.x-P.x);
		N.normalize();
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(N.x,N.y,0.0).u));
	}

	//add faces
	{
		//side faces
		{
			const int* _triIndexes = triIndexes;
			for (unsigned i=0;i<numberOfTriangles;++i,_triIndexes+=3)
			{
				addTriangle(_triIndexes[0]*2,_triIndexes[2]*2,_triIndexes[1]*2);
				addTriangleNormalIndexes(0,0,0);
				addTriangle(_triIndexes[0]*2+1,_triIndexes[1]*2+1,_triIndexes[2]*2+1);
				addTriangleNormalIndexes(1,1,1);
			}
		}

		//thickness
		{
			for (unsigned i=0;i<count;++i)
			{
				unsigned iNext = ((i+1)%count);
				addTriangle(i*2,i*2+1,iNext*2);
				addTriangleNormalIndexes(2+i,2+i,2+i);
				addTriangle(iNext*2,i*2+1,iNext*2+1);
				addTriangleNormalIndexes(2+i,2+i,2+i);
			}
		}
	}

	return true;
}
Пример #4
0
const ccGenericPrimitive& ccGenericPrimitive::operator += (const ccGenericPrimitive& prim)
{
	ccPointCloud* verts = vertices();
	unsigned vertCount = verts->size();
	unsigned facesCount = size();
	unsigned triFacesNormCount = (m_triNormals ? m_triNormals->currentSize() : 0);

	//count new number of vertices & faces
	unsigned newVertCount = vertCount + prim.getAssociatedCloud()->size();
	unsigned newFacesCount = facesCount + prim.size();
	bool primHasVertNorms = prim.getAssociatedCloud()->hasNormals();
	bool primHasFaceNorms = prim.hasTriNormals();

	//reserve memory
	if (verts->reserve(newVertCount)
		&& (!primHasVertNorms || verts->reserveTheNormsTable())
		&& reserve(newFacesCount)
		&& (!primHasFaceNorms || m_triNormalIndexes || reservePerTriangleNormalIndexes()))
	{
		//copy vertices & normals
		ccGenericPointCloud* cloud = prim.getAssociatedCloud();
		unsigned i;
		for (i=0;i<cloud->size();++i)
		{
			verts->addPoint(*cloud->getPoint(i));
			if (primHasVertNorms)
				verts->addNormIndex(cloud->getPointNormalIndex(i));
		}

		//copy face normals
		if (primHasFaceNorms)
		{
			const NormsIndexesTableType* primNorms = prim.getTriNormsTable();
			assert(primNorms);
			unsigned primTriNormCount = primNorms->currentSize();

			NormsIndexesTableType* normsTable = (m_triNormals ? m_triNormals : new NormsIndexesTableType());
			if (!normsTable || !normsTable->reserve(triFacesNormCount+primTriNormCount))
			{
				ccLog::Error("[ccGenericPrimitive::operator +] Not enough memory!");
				return *this;
			}

			//attach table if not done already
			if (!m_triNormals)
			{
				setTriNormsTable(normsTable);
				assert(m_triNormals);
				//primitives must have their normal table as child!
				addChild(m_triNormals);
			}

			for (unsigned i=0; i<primTriNormCount; ++i)
				normsTable->addElement(primNorms->getValue(i));
		}

		//copy faces
		for (i=0;i<prim.size();++i)
		{
			const CCLib::TriangleSummitsIndexes* tsi = prim.getTriangleIndexes(i);
			addTriangle(vertCount+tsi->i1,vertCount+tsi->i2,vertCount+tsi->i3);
			if (primHasFaceNorms)
			{
				const int* normIndexes = prim.m_triNormalIndexes->getValue(i);
				assert(normIndexes);
				addTriangleNormalIndexes(triFacesNormCount+normIndexes[0],triFacesNormCount+normIndexes[1],triFacesNormCount+normIndexes[2]);
			}
		}
	}
	else
	{
		ccLog::Error("[ccGenericPrimitive::operator +] Not enough memory!");
	}

	return *this;
}
Пример #5
0
bool ccCone::buildUp()
{
	if (m_drawPrecision < MIN_DRAWING_PRECISION)
		return false;

	//invalid dimensions?
	if (m_height < ZERO_TOLERANCE || m_bottomRadius + m_topRadius < ZERO_TOLERANCE)
		return false;

	//topology
	bool singlePointBottom = (m_bottomRadius < ZERO_TOLERANCE);
	bool singlePointTop = (m_topRadius < ZERO_TOLERANCE);
	assert(!singlePointBottom || !singlePointTop);

	unsigned steps = m_drawPrecision;

	//vertices
	unsigned vertCount = 2;
	if (!singlePointBottom)
		vertCount += steps;
	if (!singlePointTop)
		vertCount += steps;
	//normals
	unsigned faceNormCounts = steps+2;
	//vertices
	unsigned facesCount = steps;
	if (!singlePointBottom)
		facesCount += steps;
	if (!singlePointTop)
		facesCount += steps;
	if (!singlePointBottom && !singlePointTop)
		facesCount += steps;

	//allocate (& clear) structures
	if (!init(vertCount,false,facesCount,faceNormCounts))
	{
		ccLog::Error("[ccCone::buildUp] Not enough memory");
		return false;
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	//2 first points: centers of the top & bottom surfaces
	CCVector3 bottomCenter = CCVector3(m_xOff,m_yOff,-m_height)/2;
	CCVector3 topCenter = CCVector3(-m_xOff,-m_yOff,m_height)/2;
	{
		//bottom center
		verts->addPoint(bottomCenter);
		CompressedNormType nIndex = ccNormalVectors::GetNormIndex(CCVector3(0,0,-1).u);
		m_triNormals->addElement(nIndex);
		//top center
		verts->addPoint(topCenter);
		nIndex = ccNormalVectors::GetNormIndex(CCVector3(0,0,1).u);
		m_triNormals->addElement(nIndex);
	}
	
	//then, angular sweep for top and/or bottom surfaces
	{
		PointCoordinateType angle_rad_step = static_cast<PointCoordinateType>(2.0*M_PI)/static_cast<PointCoordinateType>(steps);
		//bottom surface
		if (!singlePointBottom)
		{
			for (unsigned i=0; i<steps; ++i)
			{
				CCVector3 P(bottomCenter.x + cos(angle_rad_step*i)*m_bottomRadius,
							bottomCenter.y + sin(angle_rad_step*i)*m_bottomRadius,
							bottomCenter.z);
				verts->addPoint(P);
			}
		}
		//top surface
		if (!singlePointTop)
		{
			for (unsigned i=0; i<steps; ++i)
			{
				CCVector3 P(topCenter.x + cos(angle_rad_step*i)*m_topRadius,
							topCenter.y + sin(angle_rad_step*i)*m_topRadius,
							topCenter.z);
				verts->addPoint(P);
			}
		}
		//side normals
		{
			for (unsigned i=0; i<steps; ++i)
			{
				//slope
				CCVector3 u(-sin(angle_rad_step*i),cos(angle_rad_step*i),0);
				CCVector3 v(bottomCenter.x-topCenter.x + u.y*(m_bottomRadius-m_topRadius),
							bottomCenter.y-topCenter.y - u.x*(m_bottomRadius-m_topRadius),
							bottomCenter.z-topCenter.z);
				CCVector3 N = v.cross(u);
				N.normalize();

				CompressedNormType nIndex = ccNormalVectors::GetNormIndex(N.u);
				m_triNormals->addElement(nIndex);
			}
		}
	}
	
	//mesh faces
	{
		assert(m_triVertIndexes);

		unsigned bottomIndex = 2;
		unsigned topIndex = 2+(singlePointBottom ? 0 : steps);

		//bottom surface
		if (!singlePointBottom)
		{
			for (unsigned i=0;i<steps;++i)
			{
				addTriangle(0,bottomIndex+(i+1)%steps,bottomIndex+i);
				addTriangleNormalIndexes(0,0,0);
			}
		}
		//top surface
		if (!singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				addTriangle(1,topIndex+i,topIndex+(i+1)%steps);
				addTriangleNormalIndexes(1,1,1);
			}
		}

		if (!singlePointBottom && !singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(bottomIndex+i,bottomIndex+iNext,topIndex+i);
				addTriangleNormalIndexes(2+i,2+iNext,2+i);
				addTriangle(topIndex+i,bottomIndex+iNext,topIndex+iNext);
				addTriangleNormalIndexes(2+i,2+iNext,2+iNext);
			}
		}
		else if (!singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(topIndex+i,0,topIndex+iNext);
				addTriangleNormalIndexes(2+i,2+iNext,2+iNext); //TODO: middle normal should be halfbetween?!
			}
		}
		else //if (!singlePointBottom)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(bottomIndex+i,bottomIndex+iNext,1);
				addTriangleNormalIndexes(2+i,2+iNext,2+i); //TODO: last normal should be halfbetween?!
			}
		}
	}

	notifyGeometryUpdate();
	showTriNorms(true);

	return true;
}