void getNodePath(TreeNode* root, TreeNode* p, TreeNode* q, vector<pair<TreeNode*,int>>& path, int& found){ if(root){ path.push_back({root,found}); if(root==p) ++found; if(root==q) ++found; if(found<2) getNodePath(root->left,p,q,path,found); if(found<2) getNodePath(root->right,p,q,path,found); if(found<2) path.pop_back(); } }
MtpObjectHandle MtpStorage::beginSendObject(const char* path, MtpObjectFormat format, MtpObjectHandle parent, uint64_t size, time_t modified) { MTPD("MtpStorage::beginSendObject(), path: '%s', parent: %u, format: %04x\n", path, parent, format); iter it = mtpmap.find(parent); if (it == mtpmap.end()) { MTPE("parent node not found, returning error\n"); return kInvalidObjectHandle; } Tree* tree = it->second; std::string pathstr(path); size_t slashpos = pathstr.find_last_of('/'); if (slashpos == std::string::npos) { MTPE("path has no slash, returning error\n"); return kInvalidObjectHandle; } std::string parentdir = pathstr.substr(0, slashpos); std::string basename = pathstr.substr(slashpos + 1); if (parent != 0 && parentdir != getNodePath(tree)) { MTPE("beginSendObject into path '%s' but parent tree has path '%s', returning error\n", parentdir.c_str(), getNodePath(tree).c_str()); return kInvalidObjectHandle; } MTPD("MtpStorage::beginSendObject() parentdir: %s basename: %s\n", parentdir.c_str(), basename.c_str()); // note: for directories, the mkdir call is done later in MtpServer, here we just reserve a handle bool isDir = format == MTP_FORMAT_ASSOCIATION; Node* node = addNewNode(isDir, tree, basename); handleCurrentlySending = node->Mtpid(); // suppress inotify for this node while sending return node->Mtpid(); }
int MtpStorage::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) { struct stat st; uint64_t size = 0; MTPD("MtpStorage::getObjectInfo, handle: %u\n", handle); Node* node = findNode(handle); if (!node) { // Item is not on this storage device return -1; } info.mStorageID = getStorageID(); MTPD("info.mStorageID: %u\n", info.mStorageID); info.mParent = node->getMtpParentId(); MTPD("mParent: %u\n", info.mParent); // TODO: do we want to lstat again here, or read from the node properties? if (lstat(getNodePath(node).c_str(), &st) == 0) size = st.st_size; MTPD("size is: %llu\n", size); info.mCompressedSize = (size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size); info.mDateModified = st.st_mtime; if (S_ISDIR(st.st_mode)) { info.mFormat = MTP_FORMAT_ASSOCIATION; } else { info.mFormat = MTP_FORMAT_UNDEFINED; } info.mName = strdup(node->getName().c_str()); MTPD("MtpStorage::getObjectInfo found, Exiting getObjectInfo()\n"); return 0; }
MtpObjectHandleList* MtpStorage::getObjectList(MtpStorageID storageID, MtpObjectHandle parent) { MTPD("MtpStorage::getObjectList, parent: %u\n", parent); //append object id (numerical #s) of database to int array MtpObjectHandleList* list = new MtpObjectHandleList(); if (parent == MTP_PARENT_ROOT) { MTPD("parent == MTP_PARENT_ROOT\n"); parent = 0; } if (mtpmap.find(parent) == mtpmap.end()) { MTPE("parent handle not found, returning empty list\n"); return list; } Tree* tree = mtpmap[parent]; if (!tree->wasAlreadyRead()) { std::string path = getNodePath(tree); MTPD("reading directory on demand for tree %p (%u), path: %s\n", tree, tree->Mtpid(), path.c_str()); readDir(path, tree); } mtpmap[parent]->getmtpids(list); MTPD("returning %u objects in %s.\n", list->size(), tree->getName().c_str()); return list; }
void FindNamedNode::apply( osg::Node& node ) { bool match = ( ( ( _method == EXACT_MATCH ) && ( node.getName() == _name ) ) || ( ( _method == CONTAINS ) && ( node.getName().find( _name ) != std::string::npos ) ) ); if( match ) { // Copy the NodePath, so we can alter it if necessary. osg::NodePath np = getNodePath(); if( !_includeTargetNode ) // Calling code has requested that the target node // be removed from the node paths. np.pop_back(); NodeAndPath nap( &node, np ); _napl.push_back( nap ); } traverse( node ); }
// 借助辅助内存,实现高效算法,保存访问的路径,即两个链表 bool getNodePath(TreeNode* root, TreeNode* node, list<TreeNode*>& path) { if (root == NULL) { return false; } path.push_back(root); if (root == node) { return true; } bool found = false; // 很多孩子节点,故需要while一个一个遍历,依次递归访问 vector<TreeNode*>::iterator it = root->children.begin(); while (!found && it < root->children.end()) { found = getNodePath(*it, node, path); it++; } if (!found) { path.pop_back(); } return found; }
void CollectVerticesVisitor::applyDrawable( osg::Drawable* drawable ) { osg::Geometry* geom = drawable->asGeometry(); if( geom == NULL ) return; const osg::Vec3Array* in = dynamic_cast< const osg::Vec3Array* >( geom->getVertexArray() ); if( in == NULL ) { osg::notify( osg::WARN ) << "CollectVerticesVisitor: Non-Vec3Array vertex array encountered." << std::endl; return; } const osg::Matrix m = osg::computeLocalToWorld( getNodePath() ); unsigned int idx; for( idx=0; idx < geom->getNumPrimitiveSets(); idx++ ) { osg::PrimitiveSet* ps = geom->getPrimitiveSet( idx ); unsigned int jdx; for( jdx=0; jdx < ps->getNumIndices(); jdx++ ) { unsigned int index = ps->index( jdx ); verts_->push_back( (*in)[ index ] * m ); } } /* osg::Vec3Array::const_iterator iter; for( iter = in->begin(); iter != in->end(); iter++ ) { verts_->push_back( *iter * m ); } */ }
int dc_fstat64(int fd, struct stat64 *buf) #endif { struct vsp_node *node; int rc; char *path; off64_t size; #ifdef DC_CALL_TRACE showTraceBack(); #endif node = get_vsp_node( fd ); if( node == NULL ) { dc_debug(DC_INFO, "Using system native fstat64 for %d.", fd); return system_fstat64(fd, buf); } /* pnfs can not show file size if file opened for write and not closed */ if( node->flags & O_WRONLY ) { size = dc_real_lseek( node, 0, SEEK_CUR ); } path = getNodePath(node); m_unlock(&node->mux); rc = dc_stat64( (const char *) path , buf); free(path); if( node->flags & O_WRONLY ) { buf->st_size = size; } return rc; }
void WriterNodeVisitor::apply( osg::Geode &node ) { pushStateSet(node.getStateSet()); //_nameStack.push_back(node.getName()); unsigned int count = node.getNumDrawables(); ListTriangle listTriangles; bool texcoords = false; for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *g = node.getDrawable( i )->asGeometry(); if ( g != NULL ) { pushStateSet(g->getStateSet()); createListTriangle(g, listTriangles, texcoords, i); // May set _succeded to false popStateSet(g->getStateSet()); if (!succeeded()) break; } } if (succeeded() && count > 0) { #if DISABLE_3DS_ANIMATION osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) ); buildFaces(node, mat, listTriangles, texcoords); // May set _succeded to false #else buildFaces(node, osg::Matrix(), listTriangles, texcoords); // May set _succeded to false #endif } popStateSet(node.getStateSet()); //_nameStack.pop_back(); if (succeeded()) traverse(node); }
int MtpStorage::renameObject(MtpObjectHandle handle, std::string newName) { MTPD("MtpStorage::renameObject, handle: %u, new name: '%s'\n", handle, newName.c_str()); if (handle == MTP_PARENT_ROOT) { MTPE("parent == MTP_PARENT_ROOT, cannot rename root\n"); return -1; } else { for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) { Node* node = i->second->findNode(handle); if (node != NULL) { std::string oldName = getNodePath(node); std::string parentdir = oldName.substr(0, oldName.find_last_of('/')); std::string newFullName = parentdir + "/" + newName; MTPD("old: '%s', new: '%s'\n", oldName.c_str(), newFullName.c_str()); if (rename(oldName.c_str(), newFullName.c_str()) == 0) { node->rename(newName); return 0; } else { MTPE("MtpStorage::renameObject failed, handle: %u, new name: '%s'\n", handle, newName.c_str()); return -1; } } } } // handle not found on this storage return -1; }
void PhysicsVisitor::apply( osg::Geode& node ) { // retrieve the node mask which is used for physics material and later for other properies // only the first byte is relevant for pyhsics material description _attribute = node.getNodeMask() & 0xFF; // this means no need for building static collision geom // this is not the same as MAT_NOCOL, as MAT_NOCOL collisions are detected if ( _attribute == Physics::NO_BUILD ) return; // get the accumulated world matrix for this node osg::Matrixf mat = computeLocalToWorld( getNodePath() ); unsigned int numDrawables = node.getNumDrawables(); for ( unsigned int cnt = 0; cnt < numDrawables; ++cnt ) { osg::Drawable* p_drawable = node.getDrawable( cnt ); osg::Geometry* p_geom = p_drawable->asGeometry(); // evaluate the geom and generate an appropriate collision geometry if ( p_geom ) { osg::Array* p_verts = p_geom->getVertexArray(); osg::IndexArray* p_indices = p_geom->getVertexIndices(); unsigned int numPrims = p_geom->getNumPrimitiveSets(); { for ( unsigned int primcnt = 0; primcnt < numPrims; ++primcnt ) { osg::PrimitiveSet* p_set = p_geom->getPrimitiveSet( primcnt ); switch( p_set->getMode() ) { case osg::PrimitiveSet::POINTS: case osg::PrimitiveSet::LINES: case osg::PrimitiveSet::LINE_STRIP: case osg::PrimitiveSet::LINE_LOOP: return; case osg::PrimitiveSet::TRIANGLES: buildTrianlges( p_set, p_verts, mat, p_indices ); break; case osg::PrimitiveSet::TRIANGLE_STRIP: buildTrianlgeStrip( p_set, p_verts, mat, p_indices ); break; case osg::PrimitiveSet::TRIANGLE_FAN: case osg::PrimitiveSet::QUADS: case osg::PrimitiveSet::QUAD_STRIP: case osg::PrimitiveSet::POLYGON: default: log_error << "Physics Serializer: unsupported primitive set for physics geometry! currently only TRIANGLES and TRIANGLE_STRIP types are supported." << std::endl; } } } } } }
int MtpStorage::getObjectFilePath(MtpObjectHandle handle, MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat) { MTPD("MtpStorage::getObjectFilePath handle: %u\n", handle); Node* node = findNode(handle); if (!node) { // Item is not on this storage device return -1; } // TODO: do we want to lstat here, or just read the info from the node? struct stat st; if (lstat(getNodePath(node).c_str(), &st) == 0) outFileLength = st.st_size; else outFileLength = 0; outFilePath = getNodePath(node).c_str(); MTPD("outFilePath: %s\n", outFilePath.string()); outFormat = node->isDir() ? MTP_FORMAT_ASSOCIATION : MTP_FORMAT_UNDEFINED; return 0; }
TreeNode* getLastCommonParent( TreeNode* root, TreeNode* node1, TreeNode* node2 ) { if (root == NULL || node1 == NULL || node2 == NULL) { return NULL; } list<TreeNode*> path1; getNodePath(root, node1, path1); list<TreeNode*> path2; getNodePath(root, node2, path2); return getLastCommonNode(path1, path2); }
generic_string FileBrowser::getSelectedItemPath() const { generic_string itemPath; HTREEITEM hItemNode = _treeView.getSelection(); if (hItemNode) { itemPath = getNodePath(hItemNode); } return itemPath; }
void AddQueries::apply( osg::Geode& node ) { traverse( node ); osgwTools::CountsVisitor cv; node.accept( cv ); const unsigned int numVertices = cv.getVertices(); const osg::BoundingBox& bb = node.getBoundingBox(); addDataToNodePath( getNodePath(), numVertices, bb ); }
void apply(osg::Transform &node) { osg::MatrixTransform* bone = node.asMatrixTransform(); if (!bone) return; mCache[Misc::StringUtils::lowerCase(bone->getName())] = std::make_pair(getNodePath(), bone); traverse(node); }
void OBJWriterNodeVisitor::apply(osg::Geometry& geometry) { osg::Matrix m = osg::computeLocalToWorld(getNodePath()); pushStateSet(geometry.getStateSet()); processGeometry(&geometry,m); popStateSet(geometry.getStateSet()); }
void apply(osg::Transform &node) { osg::MatrixTransform* bone = node.asMatrixTransform(); if (!bone) return; mCache[bone->getName()] = std::make_pair(getNodePath(), bone); traverse(node); }
virtual void apply(osg::Drawable &drawable) { if (!mTriangleMesh) mTriangleMesh.reset(new btTriangleMesh); osg::Matrixf worldMat = osg::computeLocalToWorld(getNodePath()); osg::TriangleFunctor<GetTriangleFunctor> functor; functor.setTriMesh(mTriangleMesh.get()); functor.setMatrix(worldMat); drawable.accept(functor); }
virtual void apply(osg::Node& node) { if (node.getNumParents()==0 || &node==_haltTraversalAtNode) { _nodePaths.push_back(getNodePath()); } else { traverse(node); } }
void ComputeTriMeshVisitor::applyDrawable( osg::Drawable * drawable ) { osg::TriangleFunctor< ComputeTriMeshFunc > functor; drawable->accept( functor ); osg::Matrix m = osg::computeLocalToWorld( getNodePath() ); osg::Vec3Array::iterator iter; for( iter = functor.vertices->begin(); iter != functor.vertices->end(); ++iter ) { mesh->push_back( *iter * m ); } }
virtual void apply( osg::Node& node ) { if( ( node.getNumParents() == 0 ) || ( &node == m_stopNode.get() ) ) { _finalNodePath = getNodePath(); } else { osg::NodeVisitor::traverse( node ); } }
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { vector<pair<TreeNode*,int>> path; int found = 0; getNodePath(root,p,q,path,found); TreeNode* res = 0; for(const auto& e : path){ if(e.second==0){ res = e.first; }else{ break; } } return res; }
void Writer3DCNodeVisitor::apply( osg::Geode &node ) { osg::Matrix matrix = osg::computeLocalToWorld(getNodePath()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *geometry = node.getDrawable( i )->asGeometry(); if ( geometry ) { osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()); osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray()); osg::Vec3Array* colours = dynamic_cast<osg::Vec3Array*>(geometry->getColorArray()); if ( vertices ) { for (unsigned int ii=0;ii<vertices->size();ii++) { // update nodes with world coords osg::Vec3d v = vertices->at(ii) * matrix; _fout << v[0] << ' ' << v[1] << ' ' << v[2]; if ( colours ) { v=colours->at(ii); _fout << ' ' << (int)v[0]*255.0 << ' ' << (int)v[1]*255.0 << ' ' << (int)v[2]*255.0; } else { _fout << " 255 255 255"; } if ( normals ) { v = normals->at(ii); _fout << ' ' << v[0] << ' ' << v[1] << ' ' << v[2]; } else { _fout << " 0.0 0.0 1.0"; } _fout << std::endl; } } } } }
void WriterNodeVisitor::apply(osg::MatrixTransform &node) { pushStateSet(node.getStateSet()); Lib3dsMeshInstanceNode * parent = _cur3dsNode; #if DISABLE_3DS_ANIMATION osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) ); #else osg::Matrix mat( node.getMatrix() ); #endif apply3DSMatrixNode(node, &mat, "mtx"); if (succeeded()) traverse(node); _cur3dsNode = parent; popStateSet(node.getStateSet()); }
int MtpStorage::addInotify(Tree* tree) { if (inotify_fd < 0) { MTPE("inotify_fd not set or error: %i\n", inotify_fd); return -1; } std::string path = getNodePath(tree); MTPD("adding inotify for tree %x, dir: %s\n", tree, path.c_str()); int wd = inotify_add_watch(inotify_fd, path.c_str(), WATCH_FLAGS); if (wd < 0) { MTPE("inotify_add_watch failed: %s\n", strerror(errno)); return -1; } inotifymap[wd] = tree; return 0; }
void FileBrowser::openSelectFile() { // Get the selected item HTREEITEM selectedNode = _treeView.getSelection(); if (not selectedNode) return; generic_string fullPath = getNodePath(selectedNode); // test the path - if it's a file, open it, otherwise just fold or unfold it if (not ::PathFileExists(fullPath.c_str())) return; if (::PathIsDirectory(fullPath.c_str())) return; ::SendMessage(_hParent, NPPM_DOOPEN, 0, (LPARAM)(fullPath.c_str())); }
void WriterNodeVisitor::apply( osg::Billboard &node ) { // TODO Does not handle Billboards' points yet pushStateSet(node.getStateSet()); Lib3dsMeshInstanceNode * parent = _cur3dsNode; unsigned int count = node.getNumDrawables(); ListTriangle listTriangles; bool texcoords = false; OSG_NOTICE << "Warning: 3DS writer is incomplete for Billboards (rotation not implemented)." << std::endl; #if DISABLE_3DS_ANIMATION osg::Matrix m( osg::computeLocalToWorld(getNodePath()) ); #endif for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *g = node.getDrawable( i )->asGeometry(); if ( g != NULL ) { listTriangles.clear(); _cur3dsNode = parent; pushStateSet(g->getStateSet()); createListTriangle(g, listTriangles, texcoords, i); popStateSet(g->getStateSet()); // May set _succeded to false if (!succeeded()) break; osg::Matrix pointLocalMat(osg::Matrix::translate(node.getPosition(i))); // TODO handle rotation #if DISABLE_3DS_ANIMATION osg::Matrix currentBillboardWorldMat(pointLocalMat * m); apply3DSMatrixNode(node, &pointLocalMat, "bil"); // Add a 3DS matrix node (with local matrix) buildFaces(node, currentBillboardWorldMat, listTriangles, texcoords); // May set _succeded to false #else apply3DSMatrixNode(node, &pointLocalMat, "bil"); // Add a 3DS matrix node (with local matrix) buildFaces(node, osg::Matrix(), listTriangles, texcoords); // May set _succeded to false #endif if (!succeeded()) break; } } if (succeeded()) traverse(node); _cur3dsNode = parent; popStateSet(node.getStateSet()); }
void FindGroupByRecIndex::apply(osg::Node &searchNode) { if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { NodeUserData* holder = dynamic_cast<NodeUserData*>(searchNode.getUserDataContainer()->getUserObject(0)); if (holder && holder->mIndex == mRecIndex) { osg::Group* group = searchNode.asGroup(); if (!group) group = searchNode.getParent(0); mFound = group; mFoundPath = getNodePath(); return; } } traverse(searchNode); }
void DXFWriterNodeVisitor::apply( osg::Geode &node ) { pushStateSet(node.getStateSet()); osg::Matrix m = osg::computeLocalToWorld(getNodePath()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *g = node.getDrawable( i )->asGeometry(); if ( g != NULL ) { pushStateSet(g->getStateSet()); processGeometry(g,m); popStateSet(g->getStateSet()); } } popStateSet(node.getStateSet()); }