Пример #1
0
ccSubMesh::ccSubMesh(ccMesh* parentMesh)
    : ccGenericMesh("Sub-mesh")
	, m_associatedMesh(parentMesh)
	, m_triIndexes(new ReferencesContainer())
	, m_globalIterator(0)
{
	m_triIndexes->link();

	showColors(parentMesh ? parentMesh->colorsShown() : true);
	showNormals(parentMesh ? parentMesh->normalsShown() : true);
	showSF(parentMesh ? parentMesh->sfShown() : true);
}
Пример #2
0
ccSubMesh::ccSubMesh(ccMesh* parentMesh)
	: ccGenericMesh("Sub-mesh")
	, m_associatedMesh(0)
	, m_triIndexes(new ReferencesContainer())
	, m_globalIterator(0)
{
	m_triIndexes->link();

	setAssociatedMesh(parentMesh); //must be called so as to set the right dependency!

	showColors(parentMesh ? parentMesh->colorsShown() : true);
	showNormals(parentMesh ? parentMesh->normalsShown() : true);
	showSF(parentMesh ? parentMesh->sfShown() : true);
}
Пример #3
0
ccGenericPrimitive::ccGenericPrimitive(QString name/*=QString()*/, const ccGLMatrix* transMat /*= 0*/)
	: ccMesh(new ccPointCloud("vertices"))
	, m_drawPrecision(0)
{
	setName(name);
	showNormals(true);

	ccPointCloud* vert = vertices();
	assert(vert);
	addChild(vert);
	vert->setEnabled(false);

	if (transMat)
		m_transformation = *transMat;
}
Пример #4
0
ccDrawableObject::ccDrawableObject()
{
    setVisible(true);
    setSelected(false);
    showColors(false);
    showNormals(false);
    showSF(false);
	lockVisibility(false);
	showNameIn3D(false);
    m_currentDisplay=0;

    enableTempColor(false);
    setTempColor(ccColor::white,false);
    razGLTransformation();
}
Пример #5
0
ccGenericPrimitive::ccGenericPrimitive(QString name/*=QString()*/, const ccGLMatrix* transMat/*=0*/)
	: ccMesh(new ccPointCloud("vertices"))
	, m_drawPrecision(0)
{
	setName(name);
	showNormals(true);

	ccPointCloud* vert = vertices();
	assert(vert);
	addChild(vert);
	vert->setEnabled(false);
	//we don't want the user to transform the vertices for instance (as they are only temporary)
	vert->setLocked(true);

	if (transMat)
		m_transformation = *transMat;
}
Пример #6
0
bool ccSphere::buildUp()
{
	if (m_drawPrecision<4)
		return false;

	const unsigned steps = m_drawPrecision;

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

	//vertices
	unsigned count = steps*(steps-1)+2;
	//faces
	unsigned faces = steps*((steps-2)*2+2);

	if (!init(count,true,faces,0))
	{
		ccLog::Error("[ccSphere::buildUp] Not enough memory");
		return false;
	}

	//2 first points: poles
	verts->addPoint(CCVector3(0.0,0.0,m_radius));
	verts->addNorm(0.0,0.0,1.0);

	verts->addPoint(CCVector3(0.0,0.0,-m_radius));
	verts->addNorm(0.0,0.0,-1.0);

	//then, angular sweep
	float angle_rad_step = M_PI/(float)steps;
	CCVector3 N0,N,P;
	{
		for (unsigned j=1;j<steps;++j)
		{
			float theta = (float)j * angle_rad_step;
			float cos_theta = cos(theta);
			float sin_theta = sin(theta);

			N0.x = sin_theta;
			N0.y = 0;
			N0.z = cos_theta;
		
			for (unsigned i=0;i<steps;++i)
			{
				float phi = (float)i * 2.0f * angle_rad_step;
				float cos_phi = cos(phi);
				float sin_phi = sin(phi);

				N.x = N0.x*cos_phi;
				N.y = N0.x*sin_phi;
				N.z = N0.z;
				N.normalize();

				P = N * m_radius;

				verts->addPoint(P);
				verts->addNorm(N.u);
			}
		}
	}

	//faces
	{
		assert(m_triIndexes);

		//north pole
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned A = 2+i;
				unsigned B = (i+1<steps ? A+1 : 2);
				addTriangle(A,B,0);
			}
		}

		//slices
		for (unsigned j=1;j+1<steps;++j)
		{
			unsigned shift = 2+(j-1)*steps;		
			for (unsigned i=0;i<steps;++i)
			{
				unsigned A = shift+i;
				unsigned B = (i+1<steps ? A+1 : shift);
				assert(B<count);
				addTriangle(A,A+steps,B);
				addTriangle(B+steps,B,A+steps);
			}
		}

		//south pole
		{
			unsigned shift = 2+(steps-2)*steps;
			for (unsigned i=0;i<steps;++i)
			{
				unsigned A = shift+i;
				unsigned B = (i+1<steps ? A+1 : shift);
				assert(B<count);
				addTriangle(A,1,B);
			}
		}
	}

	updateModificationTime();
	showNormals(true);

	return true;
}
Пример #7
0
bool ccDish::buildUp()
{
	if (m_drawPrecision < MIN_DRAWING_PRECISION)
		return false;

	if (m_height <= 0 || m_baseRadius <= 0 || m_secondRadius < 0) //invalid parameters
		return false;

	//section angular span
	double startAngle_rad = 0.0;
	const double endAngle_rad = M_PI/2.0;

	PointCoordinateType realRadius = m_baseRadius;
	if (m_secondRadius == 0 && m_height<m_baseRadius) //partial spherical mode
	{
		realRadius = (m_height*m_height+m_baseRadius*m_baseRadius)/(2*m_height);
		startAngle_rad = acos(m_baseRadius/realRadius);
		assert(startAngle_rad<endAngle_rad);
	}

	const unsigned steps = m_drawPrecision;
	double angleStep_rad = 2.0*M_PI/steps;
	unsigned sectionSteps = static_cast<unsigned>(ceil((endAngle_rad-startAngle_rad)*m_drawPrecision/(2.0*M_PI)));
	double sectionAngleStep_rad = (endAngle_rad-startAngle_rad)/sectionSteps;

	//vertices
	unsigned vertCount = steps*sectionSteps+1; //+1 for noth pole
	//faces
	unsigned faceCount = steps*((sectionSteps-1)*2+1);

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

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

	//first point: north pole
	verts->addPoint(CCVector3(0,0,m_height));
	verts->addNorm(CCVector3(0,0,1));

	//then, angular sweep
	{
		for (unsigned j=1; j<=sectionSteps; ++j)
		{
			PointCoordinateType theta = static_cast<PointCoordinateType>(endAngle_rad - j * sectionAngleStep_rad); //we start from north pole!
			PointCoordinateType cos_theta = cos(theta);
			PointCoordinateType sin_theta = sin(theta);

			CCVector3 N0(cos_theta, 0, sin_theta);
		
			for (unsigned i=0; i<steps; ++i) //then we make a full revolution
			{
				PointCoordinateType phi = static_cast<PointCoordinateType>(i * angleStep_rad);
				PointCoordinateType cos_phi = cos(phi);
				PointCoordinateType sin_phi = sin(phi);

				CCVector3 N(N0.x * cos_phi, N0.x * sin_phi, N0.z);
				N.normalize();

				CCVector3 P = N * realRadius;

				if (m_secondRadius > 0) //half-ellipsoid mode
				{
					P.y *= (m_secondRadius / m_baseRadius);
					P.z *= (m_height / m_baseRadius);
				}
				else //spherical section mode
				{
					P.z += m_height-realRadius;
				}

				verts->addPoint(P);
				verts->addNorm(N);
			}
		}
	}

	//faces
	{
		//north pole
		{
			for (unsigned i=0; i<steps; ++i)
			{
				unsigned A = 1+i;
				unsigned B = (i+1<steps ? A+1 : 1);
				addTriangle(A,B,0);
			}
		}

		//slices
		for (unsigned j=1; j<sectionSteps; ++j)
		{
			unsigned shift = 1+(j-1)*steps;		
			for (unsigned i=0; i<steps; ++i)
			{
				unsigned A = shift+i;
				unsigned B = (i+1<steps ? A+1 : shift);
				assert(B < vertCount);
				addTriangle(A,A+steps,B);
				addTriangle(B+steps,B,A+steps);
			}
		}
	}

	notifyGeometryUpdate();
	showNormals(true);

	return true;
}
Пример #8
0
bool ccGenericMesh::computeNormals()
{
    if (!m_associatedCloud || !m_associatedCloud->isA(CC_POINT_CLOUD)) //TODO
        return false;

    unsigned triCount = size();
    if (triCount==0)
    {
        ccLog::Error("[ccGenericMesh::computeNormals] Empty mesh!");
        return false;
    }
    unsigned vertCount=m_associatedCloud->size();
    if (vertCount<3)
    {
        ccLog::Error("[ccGenericMesh::computeNormals] Not enough vertices! (<3)");
        return false;
    }

    ccPointCloud* cloud = static_cast<ccPointCloud*>(m_associatedCloud);

    //we instantiate a temporary structure to store each vertex normal (uncompressed)
    NormsTableType* theNorms = new NormsTableType;
    if (!theNorms->reserve(vertCount))
    {
        theNorms->release();
        return false;
    }
    theNorms->fill(0);

    //allocate compressed normals array on vertices cloud
    bool normalsWereAllocated = cloud->hasNormals();
    if (!normalsWereAllocated && !cloud->resizeTheNormsTable())
    {
        theNorms->release();
        return false;
    }

    //for each triangle
    placeIteratorAtBegining();
    {
        for (unsigned i=0; i<triCount; ++i)
        {
            CCLib::TriangleSummitsIndexes* tsi = getNextTriangleIndexes();

            assert(tsi->i1<vertCount && tsi->i2<vertCount && tsi->i3<vertCount);
            const CCVector3 *A = cloud->getPoint(tsi->i1);
            const CCVector3 *B = cloud->getPoint(tsi->i2);
            const CCVector3 *C = cloud->getPoint(tsi->i3);

            //compute face normal (right hand rule)
            CCVector3 N = (*B-*A).cross(*C-*A);
            //N.normalize(); //DGM: no normalization = weighting by surface!

            //we add this normal to all triangle vertices
            PointCoordinateType* N1 = theNorms->getValue(tsi->i1);
            CCVector3::vadd(N1,N.u,N1);
            PointCoordinateType* N2 = theNorms->getValue(tsi->i2);
            CCVector3::vadd(N2,N.u,N2);
            PointCoordinateType* N3 = theNorms->getValue(tsi->i3);
            CCVector3::vadd(N3,N.u,N3);
        }
    }

    //for each vertex
    {
        for (unsigned i=0; i<vertCount; i++)
        {
            PointCoordinateType* N = theNorms->getValue(i);
            CCVector3::vnormalize(N);
            cloud->setPointNormal(i,N);
            theNorms->forwardIterator();
        }
    }

    showNormals(true);
    if (!normalsWereAllocated)
        cloud->showNormals(true);

    //theNorms->clear();
    theNorms->release();
    theNorms=0;

    return true;
}
Пример #9
0
void ccDrawableObject::toggleNormals()
{
	showNormals(!normalsShown());
}
Пример #10
0
bool ccSphere::buildUp()
{
	if (m_drawPrecision<4)
		return false;

	const unsigned steps = m_drawPrecision;

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

	//vertices
	unsigned count = steps*(steps-1)+2;
	//faces
	unsigned faces = steps*((steps-2)*2+2);

	if (!init(count,true,faces,0))
	{
		ccLog::Error("[ccSphere::buildUp] Not enough memory");
		return false;
	}

	//2 first points: poles
	verts->addPoint(CCVector3(0,0,m_radius));
	verts->addNorm(CCVector3(0,0,1));

	verts->addPoint(CCVector3(0,0,-m_radius));
	verts->addNorm(CCVector3(0,0,-1));

	//then, angular sweep
	PointCoordinateType angle_rad_step = static_cast<PointCoordinateType>(M_PI)/static_cast<PointCoordinateType>(steps);
	CCVector3 N0,N,P;
	{
		for (unsigned j=1; j<steps; ++j)
		{
			PointCoordinateType theta = static_cast<PointCoordinateType>(j) * angle_rad_step;
			PointCoordinateType cos_theta = cos(theta);
			PointCoordinateType sin_theta = sin(theta);

			N0.x = sin_theta;
			N0.y = 0;
			N0.z = cos_theta;
		
			for (unsigned i=0; i<steps; ++i)
			{
				PointCoordinateType phi = static_cast<PointCoordinateType>(2*i) * angle_rad_step;
				PointCoordinateType cos_phi = cos(phi);
				PointCoordinateType sin_phi = sin(phi);

				N.x = N0.x*cos_phi;
				N.y = N0.x*sin_phi;
				N.z = N0.z;
				N.normalize();

				P = N * m_radius;

				verts->addPoint(P);
				verts->addNorm(N);
			}
		}
	}

	//faces
	{
		assert(m_triVertIndexes);

		//north pole
		{
			for (unsigned i=0; i<steps; ++i)
			{
				unsigned A = 2+i;
				unsigned B = (i+1<steps ? A+1 : 2);
				addTriangle(A,B,0);
			}
		}

		//slices
		for (unsigned j=1; j+1<steps; ++j)
		{
			unsigned shift = 2+(j-1)*steps;		
			for (unsigned i=0; i<steps; ++i)
			{
				unsigned A = shift+i;
				unsigned B = (i+1<steps ? A+1 : shift);
				assert(B<count);
				addTriangle(A,A+steps,B);
				addTriangle(B+steps,B,A+steps);
			}
		}

		//south pole
		{
			unsigned shift = 2+(steps-2)*steps;
			for (unsigned i=0; i<steps; ++i)
			{
				unsigned A = shift+i;
				unsigned B = (i+1<steps ? A+1 : shift);
				assert(B<count);
				addTriangle(A,1,B);
			}
		}
	}

	notifyGeometryUpdate();
	showNormals(true);

	return true;
}