/***************************************************************
* Function: updateVertexMaskingVector()
*
* 'updateVertexMaskingVector' without input value: checks all
* 'CAVEGeometry' objects and mark vertices of selected geometries
*  in 'mVertexMaskingVector', and vertices clusters of them.
*
***************************************************************/
void CAVEGeodeShape::updateVertexMaskingVector()
{
    mVertexMaskingVector.clear();
    mVertexMaskingVector.resize(mNumVertices, false);

    if (mGeometryVector.size() <= 0) return;
    for (int i = 0; i < mGeometryVector.size(); i++)
    {
	if (mGeometryVector[i]->mDOCollectorIndex >= 0)
	{
	    /* mark single indices contained in mGeometryVector[i] */
	    unsigned int nPrimitiveSets = mGeometryVector[i]->getNumPrimitiveSets();
	    if (nPrimitiveSets > 0)
	    {
		for (int j = 0; j < nPrimitiveSets; j++)
		{
	    	    PrimitiveSet *primSetRef = mGeometryVector[i]->getPrimitiveSet(j);

	    	    /* support primitive set 'DrawElementsUInt', add more types of primitive sets here if needed */
		    DrawElementsUInt* drawElementUIntRef = dynamic_cast <DrawElementsUInt*> (primSetRef);
		    if (drawElementUIntRef)
		    {
			unsigned int nIdices = drawElementUIntRef->getNumIndices();
			if (nIdices > 0)
			{
			    for (int k = 0; k < nIdices; k++)
			    {
				const int index = drawElementUIntRef->index(k);
				mVertexMaskingVector[index] = true;
			    }
			}
		    }
		}
	    }

	    /* mark clustered indices contained in 'mIndexClusterVector' */
	    const int numClusters = mGeometryVector[i]->mIndexClusterVector.size();
	    for (int j = 0; j < numClusters; j++)
	    {
		CAVEGeometry::IndexClusterBase *clusterPtr = mGeometryVector[i]->mIndexClusterVector[j];
		for (int k = 0; k < clusterPtr->mNumIndices; k++)
		{
		    const int index = clusterPtr->mIndexVector[k];
		    mVertexMaskingVector[index] = true;
		}
	    }
	}
    }
}
//Constructor: Making deep copy of 'refGeometry' without copy of 'mDOCollectorIndex'
CAVEGeometry::CAVEGeometry(CAVEGeometry *refGeometry): mDOCollectorIndex(-1)
{
    /* copy primitive set and index clusters */
    unsigned int nPrimitiveSets = refGeometry->getNumPrimitiveSets();
    if (nPrimitiveSets > 0)
    {
        for (int i = 0; i < nPrimitiveSets; i++)
        {
            PrimitiveSet* primSetRef = refGeometry->getPrimitiveSet(i);

            /* support primitive set 'DrawElementsUInt', add more types of primitive sets here if needed */
            DrawElementsUInt* drawElementUIntRef = dynamic_cast <DrawElementsUInt*> (primSetRef);
            if (drawElementUIntRef)
            {
                unsigned int nIdices = drawElementUIntRef->getNumIndices();
                const GLenum &mode = drawElementUIntRef->getMode();

                /* create duplicated primitive set, copy index field and add it to 'this' */
                DrawElementsUInt* drawElementUIntDup = new DrawElementsUInt(mode, 0);
                if (nIdices > 0)
                {
                    for (int j = 0; j < nIdices; j++) drawElementUIntDup->push_back(drawElementUIntRef->index(j));
                }
                addPrimitiveSet(drawElementUIntDup);
            }
        }
    }

    /* copy the field of overlapping index by calling addIndexCluster() function sets */
    const IndexClusterVector &refClusterVector = refGeometry->mIndexClusterVector;
    if (refClusterVector.size() > 0)
    {
        for (IndexClusterVector::const_iterator itrCluster = refClusterVector.begin();
                itrCluster != refClusterVector.end(); itrCluster++)
        {
            IndexClusterBase *clusterPtr = *itrCluster;
            addIndexCluster(clusterPtr);
        }
    }
}