void
SoXipImageOverlayManager::updateSliceMap()
{
	// Removes all the previous entries
	mSliceMap.clear();

	SoSearchAction sa;
	sa.setInterest( SoSearchAction::ALL );
	sa.setType( SoXipShapeList::getClassTypeId() );
	sa.setSearchingAll( TRUE );
	sa.apply( mShapeSwitch );

	SoPathList paths = sa.getPaths();
	for( int i = 0; i < paths.getLength(); ++ i )
	{
		SbString label = ((SoXipShapeList *) paths[i]->getTail())->label.getValue().getString();

		int sliceIndex;
		if( sscanf( label.getString(), "%d", &sliceIndex ) != 1 )
		{
			SoDebugError::post( __FILE__, "Invalid label found '%s'", label.getString() );
			continue  ;
		}
		
		mSliceMap[ sliceIndex ] = (SoXipShapeList *) paths[i]->getTail();
	}
}
Esempio n. 2
0
void
SoAction::apply(const SoPathList &pathList, SbBool obeysRules)
//
////////////////////////////////////////////////////////////////////////
{
    // Check for empty path list
    if (pathList.getLength() == 0)
	return;

    // If path list obeys the rules, just apply the action to it
    if (obeysRules) {
	apply(pathList, pathList, TRUE);
	return;
    }

    //
    // Otherwise, we may have to break it into smaller lists that do
    // obey the rules
    //

    // First, sort the paths
    SoPathList	sortedPathList(pathList);
    sortedPathList.sort();

    // Remove any duplicate paths and any paths that continue through
    // the tail node of another path
    sortedPathList.uniquify();

    int	numPaths = sortedPathList.getLength();

    // If all the remaining paths have the same head, just apply to
    // the sorted path list
    const SoNode *firstHead = sortedPathList[0]->getHead();
    if (sortedPathList[numPaths-1]->getHead() == firstHead)
	apply(sortedPathList, pathList, TRUE);

    // Otherwise, we have to break the path list into smaller ones
    else
	splitPathList(sortedPathList, pathList);
}
Esempio n. 3
0
void
SoAction::splitPathList(const SoPathList &sortedList,
			const SoPathList &origPathList)
//
////////////////////////////////////////////////////////////////////////
{
    int		numPaths, curStart, i;
    SoNode	*curHead;

    numPaths = sortedList.getLength();

    // Create a list to hold one of the split lists
    SoPathList	splitList(numPaths);

    // Split list while there are still paths to examine
    curStart = 0;
    while (curStart < numPaths) {

	// Gather all paths with same head
	curHead = sortedList[curStart]->getHead();
	splitList.append(sortedList[curStart]);

	for (i = curStart + 1; i < numPaths; i++) {
	    if (sortedList[i]->getHead() != curHead)
		break;
	    splitList.append(sortedList[i]);
	}

	// Apply action to split list. Indicate that it's the last
	// path list if there are no more paths after these.
	apply(splitList, origPathList, i >= numPaths);

	// Prepare for next set of paths
	splitList.truncate(0);
	curStart = i;
    }
}
Esempio n. 4
0
//////////////////////////////////////////////////////////////////////////////
//
//  Description:
//    Convert the passed byte stream to a path list.
//    The caller should delete the returned path list when done with it.
//
//  Use: static, public
//
SoPathList *
SoByteStream::unconvert(void *data, uint32_t numBytes)
//
//////////////////////////////////////////////////////////////////////////////
{
    if (data == NULL) {
	SoDebugError::post("SoByteStream::unconvert", "data is NULL");
	return NULL;
    }
    if (numBytes == 0) {
	SoDebugError::post("SoByteStream::unconvert", "numBytes is 0");
	return NULL;
    }

    SoInput in;
    SoPathList *pathList = new SoPathList;
    SoPath  *path = NULL;

    in.setBuffer((void *) data, (size_t) numBytes);
    
    // Try to read paths
    while ((SoDB::read(&in, path) != FALSE) && (path != NULL))
    	pathList->append(path);

    // If that failed, try reading the scene as a node
    if (pathList->getLength() == 0) {
	in.setBuffer((void *) data, (size_t) numBytes); // reset
	SoSeparator *sep = SoDB::readAll(&in);		// read again
	if (sep != NULL) {
	    path = new SoPath(sep);
	    pathList->append(path);
	}
    }

    return pathList;
}
Esempio n. 5
0
void
IfWeeder::findMaterialsAndShapes(SoNode *root)
{
    // Since we know the structure of the given scene graph (which is
    // after fixing has occurred), we can be efficient here. Just
    // search for all materials in the scene. For each material, the
    // shapes affected by it must be under the separator that is the
    // material's parent node. So just search for all shapes under
    // that separator, making sure that the path to the shape comes
    // after the material.

    // First, create a dictionary so we can tell when we've found a
    // multiple instance of a material
    SbDict materialDict;

    // Search for all materials in the scene
    SoSearchAction sa;
    sa.setType(SoMaterial::getClassTypeId());
    sa.setInterest(SoSearchAction::ALL);
    sa.apply(root);

    // Set up another search action to find all shapes using a
    // material. Note that we have to search for all node types that
    // should be considered shapes.
    SoSearchAction sa2;
    sa2.setInterest(SoSearchAction::ALL);

    // These are the shape types
    SoTypeList shapeTypes;
    IfTypes::getShapeTypes(&shapeTypes);

    // Process each material, adding new ones to the list
    materialList = new SbPList;
    for (int i = 0; i < sa.getPaths().getLength(); i++) {

	const SoPath *path = (const SoPath *) sa.getPaths()[i];

	ASSERT(path->getLength() > 1);
	ASSERT(path->getTail()->getTypeId() == SoMaterial::getClassTypeId());

	SoMaterial  *material = (SoMaterial *) path->getTail();

	// Add to the dictionary if necessary, or use the existing
	// entry
	void *entryPtr;
	IfWeederMaterialEntry *entry;
	if (materialDict.find((unsigned long) material, entryPtr)) {
	    entry = (IfWeederMaterialEntry *) entryPtr;
	    if (! entry->canWeed)
		continue;
	}
	else {
	    entry = new IfWeederMaterialEntry;
	    entry->material = material;
	    entry->canWeed  = TRUE;
	    materialDict.enter((unsigned long) material, entry);
	    materialList->append(entry);
	}

	// If any node above the material in the path is an opaque
	// group, we can't really weed this material
	int j;
	for (j = path->getLength() - 2; j >= 0; j--) {
	    if (IfTypes::isOpaqueGroupType(path->getNode(j)->getTypeId())) {
		entry->canWeed = FALSE;
		break;
	    }
	}
	if (! entry->canWeed)
	    continue;

	ASSERT(path->getNodeFromTail(1)->
	       isOfType(SoSeparator::getClassTypeId()));

	SoSeparator *parent = (SoSeparator *) path->getNodeFromTail(1);
	int materialIndex = path->getIndexFromTail(0);

	// Find all shapes using the material, adding them to the list
	// of shapes in the material's entry. Store all the paths to
	// them in this list
	SoPathList pathsToShapes;
	for (int type = 0; type < shapeTypes.getLength(); type++) {
	    sa2.setType(shapeTypes[type]);
	    sa2.apply(parent);
	    for (j = 0; j < sa2.getPaths().getLength(); j++)
		pathsToShapes.append(sa2.getPaths()[j]);
	}

	for (j = 0; j < pathsToShapes.getLength(); j++) {

	    const SoPath *shapePath = (const SoPath *) pathsToShapes[j];

	    // We can't weed the material at all if a shape other than
	    // the one we created is found
	    SoType tailType = shapePath->getTail()->getTypeId();
	    if (tailType != SoIndexedTriangleStripSet::getClassTypeId() &&
		tailType != SoIndexedFaceSet::getClassTypeId()) {
		entry->canWeed = FALSE;
		break;
	    }

	    // Make sure the shape comes after the material and does
	    // not get its materials from a vertex property
	    // node.
	    else if (shapePath->getIndex(1) > materialIndex) {
		SoIndexedShape *is = (SoIndexedShape *) shapePath->getTail();

		// ??? If the shape's materialIndex field has the
		// ??? default value, we assume that it might have to
		// ??? access all the material values. To check, we would
		// ??? have to look at the coordIndex values if the
		// ??? material binding is not OVERALL. This change could
		// ??? not be done in time for the release. See bug 311071.
		if (is->materialIndex.getNum() == 1 &&
		    is->materialIndex[0] < 0) {
		    entry->canWeed = FALSE;
		    break;
		}

		SoVertexProperty *vp =
		    (SoVertexProperty *) is->vertexProperty.getValue();
		if (vp == NULL || vp->orderedRGBA.getNum() == 0)
		    entry->shapes.append(shapePath->getTail());
	    }
	}
    }
}