/*! Find push targets in subtree.
 */
Action::ResultE TransformPushGraphOp::traverseTargetsEnter(Node * const node)
{
    NodeCore *core = node->getCore();
    
    if(core == NULL)
    {
        // warn about broken subtree, but do not prevent push, just skip it
        FWARNING(("TransformPushGraphOp::traverseTargetsEnter: "
                  "Found node without core!\n"));
        return Action::Skip;
    }
    
    if(isInExcludeList(node) || isInPreserveList(node))
    {
        // prevent the push as the transform can not be moved into this branch.
        _pushPossible = false;
        
        return Action::Quit;
    }
    
    if(core->getType().isDerivedFrom(Transform::getClassType()))
    {
        _pushTargets.push_back(node);
        
        return Action::Skip;
    }
       
    if(core->getType().isDerivedFrom(Geometry ::getClassType()))
    {
        Geometry *geo = dynamic_cast<Geometry *>(core);
        
        if(geo != NULL && validTargetGeo(geo))
        {
            // found a push target in this branch, store it and stop searching
            _pushTargets.push_back(node);
        
            return Action::Skip;
        }
        else
        {
            // prevent the push as the transform can not be moved into this branch.
            _pushPossible = false;
        
            return Action::Quit;
        }
    }
    
    if(core->getType().isDerivedFrom(Group::getClassType()))
    {
        // keep searching children for push targets
        return Action::Continue;
    }
    
    // unknown core type, be conservative and prevent the push
    _pushPossible = false;
    
    return Action::Quit;
}
void DrawableStatsAttachment::invalidate(FieldContainer *obj)
{
    if(obj == NULL)
        return;

    AttachmentContainer *cont = dynamic_cast<AttachmentContainer *>(obj);

    // Called on a non-AttachmentContainer?
    if(cont == NULL)
        return;

    // Find the attachment
    DrawableStatsAttachment *st = get(cont);

    if(st == NULL) // Found the end of the chain
        return;

    // Invalidate it
    st->reset();

    // Traverse upwards
    if(st->getMFParents()->size())
    {
        // Can't have more than 1
        FieldContainer *p = 
            dynamic_cast<FieldContainer *>(st->getParents(0)); 

        // Is this attached to a NodeCore?
        NodeCore *c = dynamic_cast<NodeCore *>(p);
        if(c != NULL)
        {
            MFParentFieldContainerPtr::const_iterator pnI;

            for(  pnI  = c->getMFParents()->begin();
                  pnI != c->getMFParents()->end  ();
                ++pnI)
            {
                Node *node = dynamic_cast<Node *>(*pnI);

                invalidate(node);
            }
        }

        // Is this attached to a Node?
        Node *n = dynamic_cast<Node *>(p);

        if(n != NULL)
        {
            Node *par = n->getParent();

            invalidate(par);
        }
    }
}
Ejemplo n.º 3
0
/* remove this, if there is a general methode to find containers */
FieldContainer *VRMLFile::findFCByName(const Char8 *szName,
                                             Node  *pNode)
{
    MFUnrecNodePtr::const_iterator i;

    FieldContainer *pFC       = NULL;

#if 0
    Name           *pNodename = NULL;
    NodeCore       *pCore     = NULL;
    // check if name matches nodename

    pNodename =
        dynamic_cast<NamePtr>(
            pNode->findAttachment(Name::getClassType().getGroupId()));

    if(pNodename != NullFC)
    {
        if(strcmp(szName, pNodename->getFieldPtr()->getValue().c_str())==0)
            return pNode;
    }
    // check if name matches corename

    pCore = pNode->getCore();

    if(pCore != NullFC)
    {
        pNodename = dynamic_cast<NamePtr>(
            pCore->findAttachment(Name::getClassType().getGroupId()));

        if(pNodename != NullFC)
        {
            if(strcmp(szName, pNodename->getFieldPtr()->getValue().c_str())==0)
                return pCore;
        }
    }

    // matching for children
    for(i  = pNode->getMFChildren()->begin();
        i != pNode->getMFChildren()->end();
        i++)
    {
        pFC = findFCByName(szName, *i);

        if(pFC != NullFC)
        {
            return pFC;
        }
    }
#endif

    return pFC;
}
void NodeCoreBase::execSyncV(      FieldContainer    &oFrom,
                                        ConstFieldMaskArg  whichField,
                                        AspectOffsetStore &oOffsets,
                                        ConstFieldMaskArg  syncMode,
                                  const UInt32             uiSyncInfo)
{
    NodeCore *pThis = static_cast<NodeCore *>(this);

    pThis->execSync(static_cast<NodeCore *>(&oFrom),
                    whichField,
                    oOffsets,
                    syncMode,
                    uiSyncInfo);
}
Ejemplo n.º 5
0
void NodeCore::kill(NodeCore &ref)
{
	StLock<Mutex> _(*this);
	assert(hasReference(ref));
	ref.kill();
	removeReference(ref);
}
ChunkMaterial *getChunkMaterial(Node *node)
{
    NodeCore            *pCore = node->getCore();
    ChunkMaterialRefPtr  cm;
    
    if((pCore != NULL) && 
       (pCore->getType().isDerivedFrom(MaterialGroup::getClassType())))
    {
        MaterialGroupRefPtr g = dynamic_cast<MaterialGroup *>(pCore);
        cm = dynamic_cast<ChunkMaterial *>(g->getMaterial());
    }
    else if((pCore != NULL) &&
            (pCore->getType().isDerivedFrom(Geometry::getClassType())))
    {
        GeometryRefPtr g = dynamic_cast<Geometry *>(pCore);
        cm = dynamic_cast<ChunkMaterial *>(g->getMaterial());
    }
    
    return cm;
}
/*! Find push targets in subtree.
 */
Action::ResultE MaterialGroupPushGraphOp::traverseTargetsEnter(Node * const node)
{
    NodeCore *core = node->getCore();
    
    if(core == NULL)
    {
        // warn about broken subtree, but do not prevent push, just skip it
        FWARNING(("MaterialGroupPushGraphOp::traverseTargetsEnter: "
                  "Found node without core!\n"));
        return Action::Skip;
    }
    
    if(isInExcludeList(node) || isInPreserveList(node))
    {
        // prevent the push as the mat group can not be moved into this branch.
        _pushPossible = false;
        
        return Action::Quit;
    }
    
    if(core->getType().isDerivedFrom(MaterialDrawable::getClassType()))
    {
        // found a push target in this branch, store it and stop searching
        _pushTargets.push_back(node);
        
        return Action::Skip;
    }
    
    if( core->getType().isDerivedFrom(Group        ::getClassType()) &&
       !core->getType().isDerivedFrom(MaterialGroup::getClassType())   )
    {
        // keep searching children for push targets
        return Action::Continue;
    }
    
    // unknown core type, be conservative and prevent the push
    _pushPossible = false;
    
    return Action::Quit;
}
Ejemplo n.º 8
0
NodeTransitPtr deepCloneTree(      
    const OSG::Node                                        *rootNode,
    const std::vector<const OSG::ReflexiveContainerType *> &shareTypes,
    const std::vector<const OSG::ReflexiveContainerType *> &ignoreTypes,
    const std::vector<OSG::UInt16>                         &shareGroupIds,
    const std::vector<OSG::UInt16>                         &ignoreGroupIds)
{
    NodeUnrecPtr rootClone(NULL);

    if(rootNode != NULL)
    {
        NodeUnrecPtr  childClone;
        NodeCore     *core       = rootNode->getCore();

        rootClone = Node::create();
        rootClone->setTravMask(rootNode->getTravMask());

        deepCloneAttachments(rootNode,      rootClone,
                             shareTypes,    ignoreTypes,
                             shareGroupIds, ignoreGroupIds);

        if(core != NULL)
        {
                  NodeCoreUnrecPtr    coreClone(NULL);
            const FieldContainerType &coreType   = core->getType();

            // test if core type should NOT be ignored
            if(!TypePredicates::typeInGroupIds (
                    ignoreGroupIds.begin(),
                    ignoreGroupIds.end(), coreType) &&
               !TypePredicates::typeDerivedFrom(
                    ignoreTypes.begin(),
                    ignoreTypes.end(),    coreType)   )
            {
                // test if core should be shared
                if(TypePredicates::typeInGroupIds (
                       shareGroupIds.begin(),
                       shareGroupIds.end(), coreType) ||
                   TypePredicates::typeDerivedFrom(
                       shareTypes.begin(),
                       shareTypes.end(),    coreType)   )
                {
                    // share core
                    coreClone = core;
                }
                else
                {
                    // clone core
                    coreClone = 
                        dynamic_pointer_cast<NodeCore>(
                            deepClone(core,
                                      shareTypes,    ignoreTypes,
                                      shareGroupIds, ignoreGroupIds));
                }
            }

            rootClone->setCore(coreClone);
        }

        for(UInt32 i = 0; i < rootNode->getNChildren(); ++i)
        {
            childClone = deepCloneTree(rootNode->getChild(i),
                                       shareTypes,    ignoreTypes,
                                       shareGroupIds, ignoreGroupIds);

            rootClone->addChild(childClone);
        }
    }

    return NodeTransitPtr(rootClone);
}
Action::ResultE GeometryMergeGraphOp::traverseLeave(
        Node * const node, Action::ResultE res)
{
    if(isInExcludeList(node))
        return Action::Skip;

    NodeCore *core = node->getCore();
    
    // skip cores with a dependency on the children number/order
    // TODO: find a way to make this extendable
    if(core == NULL                                               ||
       core->getType().isDerivedFrom(DistanceLOD::getClassType()) ||
       core->getType().isDerivedFrom(ScreenLOD  ::getClassType()) ||
       core->getType().isDerivedFrom(Switch     ::getClassType()) ||
       core->getType().isDerivedFrom(MultiCore  ::getClassType())   )
    {
        return Action::Continue;
    }
    
    typedef std::vector<NodeUnrecPtr> NodeStore;
    NodeStore addStore;     // nodes to add as children to current one
    NodeStore subStore;     // nodes (children) to remove from current one
    
    typedef std::vector<Node *    > MergeGroup; // geometries that can be merged
    typedef std::vector<MergeGroup> MergeList;  // list of merge groups
    
    MergeList                            ml;
    Node::MFChildrenType::const_iterator childIt  =
            node->getMFChildren()->begin();
    Node::MFChildrenType::const_iterator childEnd =
            node->getMFChildren()->end  ();
    
    // group geometry children that are mergeable
    for(; childIt != childEnd; ++childIt)
    {
        if((*childIt)->getCore()->getType() != Geometry::getClassType())
            continue;
        
        if(isInExcludeList(*childIt) || isInPreserveList(*childIt))
            continue;
        
        Geometry *geo = dynamic_cast<Geometry *>((*childIt)->getCore());
        Material *mat = geo->getMaterial();
        
        MergeList::iterator mlIt  = ml.begin();
        MergeList::iterator mlEnd = ml.end  ();
        
        bool done = false;
        
        for(; mlIt != mlEnd && !done; ++mlIt)
        {
            Geometry *mlGeo =
                    dynamic_cast<Geometry *>(mlIt->front()->getCore());
            Material *mlMat = mlGeo->getMaterial();
            
            if(compareContainerEqual(mlMat, mat) &&
               mergeableGeo         (mlGeo, geo)   )
            {
                mlIt->push_back(*childIt);
                done = true;
            }
        }
        
        if(!done)
        {
            ml       .push_back(MergeGroup());
            ml.back().push_back(*childIt    );
        }
    }
    
    // merge geometry in the same group and replace obsolete children with
    // new geometry
    MergeList::iterator mlIt  = ml.begin();
    MergeList::iterator mlEnd = ml.end  ();
    
    for(; mlIt != mlEnd; ++mlIt)
    {
        // only one geometry in merge group -> nothing to do
        if(mlIt->size() <= 1)
            continue;
        
        FINFO(("GeometryMergeGraphOp::traverseLeave: Merging [%" PRISize "] "
               "Geometries.\n", mlIt->size()));
        
        GeometryUnrecPtr     geo1;
        GeometryUnrecPtr     geo2;
        NodeUnrecPtr         newNode = Node::create();
        MergeGroup::iterator mgIt    = mlIt->begin();
        MergeGroup::iterator mgEnd   = mlIt->end  ();
        
        geo1 = dynamic_cast<Geometry *>((*mgIt)->getCore());

        // remove the first geo as well
        subStore.push_back(*mgIt);

        ++mgIt;
        
        for(UInt32 i = 0; mgIt != mgEnd; ++mgIt, ++i)
        {
            geo2 = dynamic_cast<Geometry *>((*mgIt)->getCore());
            
            if(i > _mergeThreshold && (mgIt + 1) != mgEnd)
            {
                newNode->setCore(geo1);
                addStore.push_back(newNode);
                
                i       = 0;
                newNode = Node::create();
                geo1    = dynamic_cast<Geometry *>((*mgIt)->getCore());
                ++mgIt;
            }
            
            geo1 = mergeGeo(geo1, geo2);
            geo1->setMaterial(geo2->getMaterial());
            
            subStore.push_back(*mgIt);
        }
        
       newNode->setCore(geo1);
       addStore.push_back(newNode);
    }
    
    // add newly created geometries to current node
    NodeStore::const_iterator storeIt  = subStore.begin();
    NodeStore::const_iterator storeEnd = subStore.end  ();
    
    for(; storeIt != storeEnd; ++storeIt)
       node->subChild(*storeIt);
    
    storeIt  = addStore.begin();
    storeEnd = addStore.end  ();
    
    for(; storeIt != storeEnd; ++storeIt)
       node->addChild(*storeIt);
    
    return Action::Continue;
}
Ejemplo n.º 10
0
bool NodeCore::hasReference(NodeCore &p)
{
	assert(p.refCountForDebuggingOnly() > 0);
	return mReferences.find(&p) != mReferences.end();
}