void
SoBoxSelectionRenderAction::apply(SoNode * node)
{
    SoGLRenderAction::apply(node);
    if (this->hlVisible) {
        if (PRIVATE(this)->searchaction == NULL) {
            PRIVATE(this)->searchaction = new SoSearchAction;
        }
        PRIVATE(this)->searchaction->setType(SoFCSelection::getClassTypeId());
        PRIVATE(this)->searchaction->setInterest(SoSearchAction::ALL);
        PRIVATE(this)->searchaction->apply(node);
        const SoPathList & pathlist = PRIVATE(this)->searchaction->getPaths();
        if (pathlist.getLength() > 0) {
            for (int i = 0; i < pathlist.getLength(); i++ ) {
                SoPath * path = pathlist[i];
                assert(path);
                SoFCSelection * selection = (SoFCSelection *) path->getTail();
                assert(selection->getTypeId().isDerivedFrom(SoFCSelection::getClassTypeId()));
                if (selection->selected.getValue() && selection->style.getValue() == SoFCSelection::BOX) {
                    PRIVATE(this)->basecolor->rgb.setValue(selection->colorSelection.getValue());
                    if (PRIVATE(this)->selectsearch == NULL) {
                        PRIVATE(this)->selectsearch = new SoSearchAction;
                    }
                    PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId());
                    PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST);
                    PRIVATE(this)->selectsearch->apply(selection);
                    SoPath* shapepath = PRIVATE(this)->selectsearch->getPath();
                    if (shapepath) {
                        SoPathList list;
                        list.append(shapepath);
                        this->drawBoxes(path, &list);
                    }
                    PRIVATE(this)->selectsearch->reset();
                }
                else if (selection->isHighlighted() &&
                         selection->selected.getValue() == SoFCSelection::NOTSELECTED &&
                         selection->style.getValue() == SoFCSelection::BOX) {
                    PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue());

                    if (PRIVATE(this)->selectsearch == NULL) {
                      PRIVATE(this)->selectsearch = new SoSearchAction;
                    }
                    PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId());
                    PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST);
                    PRIVATE(this)->selectsearch->apply(selection);
                    SoPath* shapepath = PRIVATE(this)->selectsearch->getPath();
                    if (shapepath) {
                        SoPathList list;
                        list.append(shapepath);
                        PRIVATE(this)->highlightPath = path;
                        PRIVATE(this)->highlightPath->ref();
                        this->drawBoxes(path, &list);
                    }
                    PRIVATE(this)->selectsearch->reset();
                }
            }
        }
        PRIVATE(this)->searchaction->reset();
    }
}
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();
	}
}
Beispiel #3
0
//////////////////////////////////////////////////////////////////////////////
//
//  Description:
//    Convert the passed path to a byte stream.
//    binaryFormat determines whether to copy the data in binary (TRUE) or
//    ascii (FALSE) format.
//
//  Use: public
//
void
SoByteStream::convert(SoPath *path, SbBool binaryFormat)
//
//////////////////////////////////////////////////////////////////////////////
{
    SoPathList pathList;

    pathList.append(path);
    convert(&pathList, binaryFormat);
}
void
SoBoxSelectionRenderAction::apply(SoPath * path)
{
    SoGLRenderAction::apply(path);
    SoNode* node = path->getTail();
    if (node && node->getTypeId() == SoFCSelection::getClassTypeId()) {
        SoFCSelection * selection = (SoFCSelection *) node;

        // This happens when dehighlighting the current shape
        if (PRIVATE(this)->highlightPath == path) {
            PRIVATE(this)->highlightPath->unref();
            PRIVATE(this)->highlightPath = 0;
            // FIXME: Doing a redraw to remove the shown bounding box causes
            // some problems when moving the mouse from one shape to another
            // because this will destroy the box immediately
            selection->touch(); // force a redraw when dehighlighting
        }
        else if (selection->isHighlighted() &&
                 selection->selected.getValue() == SoFCSelection::NOTSELECTED &&
                 selection->style.getValue() == SoFCSelection::BOX) {
            PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue());

            if (PRIVATE(this)->selectsearch == NULL) {
              PRIVATE(this)->selectsearch = new SoSearchAction;
            }
            PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId());
            PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST);
            PRIVATE(this)->selectsearch->apply(selection);
            SoPath* shapepath = PRIVATE(this)->selectsearch->getPath();
            if (shapepath) {
                SoPathList list;
                list.append(shapepath);
                PRIVATE(this)->highlightPath = path;
                PRIVATE(this)->highlightPath->ref();
                this->drawBoxes(path, &list);
            }
            PRIVATE(this)->selectsearch->reset();
        }
    }
}
Beispiel #5
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;
}
Beispiel #6
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);
}
Beispiel #7
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;
    }
}
Beispiel #8
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());
	    }
	}
    }
}
Beispiel #9
0
		void
		Scene::load(const ::std::string& filename, const bool& doBoundingBoxPoints, const bool& doPoints)
		{
			::rl::xml::DomParser parser;
			
			::rl::xml::Document doc = parser.readFile(filename, "", XML_PARSE_NOENT | XML_PARSE_XINCLUDE);
			
			doc.substitute(XML_PARSE_NOENT | XML_PARSE_XINCLUDE);
			
			::rl::xml::Path path(doc);
			
			::rl::xml::Object scenes = path.eval("//scene");
			
			for (int i = 0; i < ::std::min(1, scenes.getNodeNr()); ++i)
			{
				SoInput input;
				
				if (!input.openFile(scenes.getNodeTab(i).getLocalPath(scenes.getNodeTab(i).getAttribute("href").getValue()).c_str() ,true))
				{
					throw Exception("::rl::sg::Scene::load() - failed to open file");
				}
				
				SoVRMLGroup* root = SoDB::readAllVRML(&input);
				
				if (NULL == root)
				{
					throw Exception("::rl::sg::Scene::load() - failed to read file");
				}
				
				SbViewportRegion viewportRegion;
				
				root->ref();
				
				// model
				
				::rl::xml::Object models = path.eval("model", scenes.getNodeTab(i));
				
				for (int j = 0; j < models.getNodeNr(); ++j)
				{
					SoSearchAction modelSearchAction;
					modelSearchAction.setName(models.getNodeTab(j).getAttribute("name").getValue().c_str());
					modelSearchAction.apply(root);
					
					if (NULL == modelSearchAction.getPath())
					{
						continue;
					}
					
					Model* model = this->create();
					
					model->setName(models.getNodeTab(j).getAttribute("name").getValue());
					
					// body
					
					::rl::xml::Object bodies = path.eval("body", models.getNodeTab(j));
					
					for (int k = 0; k < bodies.getNodeNr(); ++k)
					{
						SoSearchAction bodySearchAction;
						bodySearchAction.setName(bodies.getNodeTab(k).getAttribute("name").getValue().c_str());
						bodySearchAction.apply(static_cast< SoFullPath* >(modelSearchAction.getPath())->getTail());
						
						if (NULL == bodySearchAction.getPath())
						{
							continue;
						}
						
						Body* body = model->create();
						
						body->setName(bodies.getNodeTab(k).getAttribute("name").getValue());
						
						SoSearchAction pathSearchAction;
						pathSearchAction.setNode(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail());
						pathSearchAction.apply(root);
						
						SoGetMatrixAction bodyGetMatrixAction(viewportRegion);
						bodyGetMatrixAction.apply(static_cast< SoFullPath* >(pathSearchAction.getPath()));
						SbMatrix bodyMatrix = bodyGetMatrixAction.getMatrix();
						
						if (!this->isScalingSupported)
						{
							SbVec3f bodyTranslation;
							SbRotation bodyRotation;
							SbVec3f bodyScaleFactor;
							SbRotation bodyScaleOrientation;
							SbVec3f bodyCenter;
							bodyMatrix.getTransform(bodyTranslation, bodyRotation, bodyScaleFactor, bodyScaleOrientation, bodyCenter);
							
							for (int l = 0; l < 3; ++l)
							{
								if (::std::abs(bodyScaleFactor[l] - 1.0f) > 1.0e-6f)
								{
									throw Exception("::rl::sg::Scene::load() - bodyScaleFactor not supported");
								}
							}
						}
						
						::rl::math::Transform frame;
						
						for (int m = 0; m < 4; ++m)
						{
							for (int n = 0; n < 4; ++n)
							{
								frame(m, n) = bodyMatrix[n][m];
							}
						}
						
						body->setFrame(frame);
						
						if (static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail()->isOfType(SoVRMLTransform::getClassTypeId()))
						{
							SoVRMLTransform* bodyVrmlTransform = static_cast< SoVRMLTransform* >(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail());
							
							for (int l = 0; l < 3; ++l)
							{
								body->center(l) = bodyVrmlTransform->center.getValue()[l];
							}
						}
						
						SoPathList pathList;
						
						// shape
						
						SoSearchAction shapeSearchAction;
						shapeSearchAction.setInterest(SoSearchAction::ALL);
						shapeSearchAction.setType(SoVRMLShape::getClassTypeId());
						shapeSearchAction.apply(static_cast< SoFullPath* >(bodySearchAction.getPath())->getTail());
						
						for (int l = 0; l < shapeSearchAction.getPaths().getLength(); ++l)
						{
							SoFullPath* path = static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l]);
							
							if (path->getLength() > 1)
							{
								path = static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l]->copy(1, static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l])->getLength() - 1));
							}
							
							pathList.append(path);
							
							SoGetMatrixAction shapeGetMatrixAction(viewportRegion);
							shapeGetMatrixAction.apply(path);
							SbMatrix shapeMatrix = shapeGetMatrixAction.getMatrix();
							
							if (!this->isScalingSupported)
							{
								SbVec3f shapeTranslation;
								SbRotation shapeRotation;
								SbVec3f shapeScaleFactor;
								SbRotation shapeScaleOrientation;
								SbVec3f shapeCenter;
								shapeMatrix.getTransform(shapeTranslation, shapeRotation, shapeScaleFactor, shapeScaleOrientation, shapeCenter);
								
								for (int m = 0; m < 3; ++m)
								{
									if (::std::abs(shapeScaleFactor[m] - 1.0f) > 1.0e-6f)
									{
										throw Exception("::rl::sg::Scene::load() - shapeScaleFactor not supported");
									}
								}
							}
							
							SoVRMLShape* shapeVrmlShape = static_cast< SoVRMLShape* >(static_cast< SoFullPath* >(shapeSearchAction.getPaths()[l])->getTail());
							
							Shape* shape = body->create(shapeVrmlShape);
							
							shape->setName(shapeVrmlShape->getName().getString());
							
							::rl::math::Transform transform;
							
							for (int m = 0; m < 4; ++m)
							{
								for (int n = 0; n < 4; ++n)
								{
									transform(m, n) = shapeMatrix[n][m];
								}
							}
							
							shape->setTransform(transform);
						}
						
						// bounding box
						
						if (doBoundingBoxPoints)
						{
							SoGetBoundingBoxAction getBoundingBoxAction(viewportRegion);
							getBoundingBoxAction.apply(pathList);
							SbBox3f boundingBox = getBoundingBoxAction.getBoundingBox();
							
							for (int l = 0; l < 3; ++l)
							{
								body->max(l) = boundingBox.getMax()[l];
								body->min(l) = boundingBox.getMin()[l];
							}
						}
						
						// convex hull
						
						if (doPoints)
						{
							SoCallbackAction callbackAction;
							callbackAction.addTriangleCallback(SoVRMLGeometry::getClassTypeId(), Scene::triangleCallback, &body->points);
							callbackAction.apply(pathList);
						}
					}
				}
				
				root->unref();
			}
		}