/*! 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); } } }
/* 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); }
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; }
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; }
bool NodeCore::hasReference(NodeCore &p) { assert(p.refCountForDebuggingOnly() > 0); return mReferences.find(&p) != mReferences.end(); }