Example #1
0
void ccHObject::applyGLTransformation_recursive(ccGLMatrix* trans/*=NULL*/)
{
    ccGLMatrix* _trans = NULL;

    if (m_glTransEnabled)
    {
        if (!trans)
        {
            //if no transformation is provided (by father)
            //we initiate it with the current one
            trans = _trans = new ccGLMatrix(m_glTrans);
        }
        else
        {
            *trans *= m_glTrans;
        }
    }

    if (trans)
    {
        applyGLTransformation(*trans);
        updateModificationTime();
    }

    for (Container::iterator it = m_children.begin(); it!=m_children.end(); ++it)
        (*it)->applyGLTransformation_recursive(trans);

    if (_trans)
        delete _trans;

    if (m_glTransEnabled)
        razGLTransformation();
}
Example #2
0
ccHObject::ccHObject(QString name/*=QString()*/)
    : ccObject(name)
    , ccDrawableObject()
    , m_parent(0)
    , m_lastModificationTime_ms(0)
    , m_selectionBehavior(SELECTION_AA_BBOX)
{
    setVisible(false);
    lockVisibility(true);
    updateModificationTime();
}
Example #3
0
void ccSubMesh::refreshBB()
{
	m_bBox.clear();
	
	for (unsigned i=0; i<size(); ++i)
	{
		CCLib::GenericTriangle* tri = _getTriangle(i);
		m_bBox.add(*tri->_getA());
		m_bBox.add(*tri->_getB());
		m_bBox.add(*tri->_getC());
	}

	updateModificationTime();
}
Example #4
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;
}
Example #5
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(cos((double)t*sweepStep_rad),
						 sin((double)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,0.0);
		verts->addPoint(P);
		CCVector3 P2(cos(m_angle_rad)*sweepRadius,
						 sin(m_angle_rad)*sweepRadius,
						 0);
		verts->addPoint(P2);
	}

	if (!closed)
	{
		//first section (left side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,-1.0,0.0).u));
		//last section (right side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(-sin(m_angle_rad),cos(m_angle_rad),0.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);
				}
			}
		}
	}

	updateModificationTime();
	showTriNorms(true);

	return true;
}
Example #6
0
ccSubMesh* ccSubMesh::createNewSubMeshFromSelection(bool removeSelectedFaces, IndexMap* indexMap/*=0*/)
{
	ccGenericPointCloud* vertices = getAssociatedCloud();
	assert(vertices && m_associatedMesh);
	if (!vertices || !m_associatedMesh)
	{
		return NULL;
	}

	ccGenericPointCloud::VisibilityTableType* verticesVisibility = vertices->getTheVisibilityArray();
	if (!verticesVisibility || !verticesVisibility->isAllocated())
	{
		ccLog::Error(QString("[Sub-mesh %1] Internal error: vertex visibility table not instantiated!").arg(getName()));
		return NULL;
	}

	//we count the number of remaining faces
	unsigned triNum = m_triIndexes->currentSize();
	unsigned visibleFaces = 0;
	{
		for (unsigned i=0; i<triNum; ++i)
		{
			const unsigned& globalIndex = m_triIndexes->getValue(i);
			const CCLib::TriangleSummitsIndexes* tsi = m_associatedMesh->getTriangleIndexes(globalIndex);
			//triangle is visible?
			if (   verticesVisibility->getValue(tsi->i1) == POINT_VISIBLE
				&& verticesVisibility->getValue(tsi->i2) == POINT_VISIBLE
				&& verticesVisibility->getValue(tsi->i3) == POINT_VISIBLE)
			{
				++visibleFaces;
			}
		}
	}

	//nothing to do
	if (visibleFaces == 0)
	{
		if (indexMap) //we still have to translate global indexes!
		{
			for (unsigned i=0; i<triNum; ++i)
			{
				unsigned globalIndex = m_triIndexes->getValue(i);
				globalIndex = indexMap->getValue(globalIndex);
				m_triIndexes->setValue(i,globalIndex);
			}
		}
		return 0;
	}

	ccSubMesh* newSubMesh = new ccSubMesh(m_associatedMesh);
	if (!newSubMesh->reserve(size()))
	{
		ccLog::Error("[ccSubMesh::createNewSubMeshFromSelection] Not enough memory!");
		return NULL;
	}

	//create sub-mesh
	{
		unsigned lastTri = 0;
		for (unsigned i=0; i<triNum; ++i)
		{
			unsigned globalIndex = m_triIndexes->getValue(i);
			const CCLib::TriangleSummitsIndexes* tsi = m_associatedMesh->getTriangleIndexes(globalIndex);

			if (indexMap) //translate global index?
				globalIndex = indexMap->getValue(globalIndex);

			//triangle is visible?
			if (   verticesVisibility->getValue(tsi->i1) == POINT_VISIBLE
				&& verticesVisibility->getValue(tsi->i2) == POINT_VISIBLE
				&& verticesVisibility->getValue(tsi->i3) == POINT_VISIBLE)
			{
				newSubMesh->addTriangleIndex(globalIndex);
			}
			else if (removeSelectedFaces) //triangle is not visible? It stays in the original mesh!
			{
				//we replace the current triangle by the 'last' valid one
				assert(lastTri <= i);
				m_triIndexes->setValue(lastTri++,globalIndex);
			}
		}

		//resize original mesh
		if (removeSelectedFaces && lastTri < triNum)
		{
			if (lastTri == 0)
				m_triIndexes->clear(true);
			else
				resize(lastTri);
			m_bBox.setValidity(false);
			updateModificationTime();
		}
	}

	if (newSubMesh->size())
	{
		newSubMesh->setName(getName()+QString(".part"));
		newSubMesh->resize(newSubMesh->size());
		newSubMesh->setDisplay(getDisplay());
		newSubMesh->showColors(colorsShown());
		newSubMesh->showNormals(normalsShown());
		newSubMesh->showMaterials(materialsShown());
		newSubMesh->showSF(sfShown());
		newSubMesh->enableStippling(stipplingEnabled());
		newSubMesh->showWired(isShownAsWire());
	}
	else
	{
		assert(false);
		delete newSubMesh;
		newSubMesh = 0;
	}

	return newSubMesh;
}