Show
Ignore:
Timestamp:
05/14/09 15:40:02 (6 years ago)
Author:
robert
Message:

Integrated support for relative paths, and http hosted presentations

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/applications/present3D/ReaderWriterP3D.cpp

    r10125 r10207  
    114114    virtual ReadResult readNode(std::istream& fin, const Options* options) const; 
    115115 
    116     ReadResult readNode(osgDB::XmlNode::Input& input, const osgDB::ReaderWriter::Options* options) const; 
     116    ReadResult readNode(osgDB::XmlNode::Input& input, osgDB::ReaderWriter::Options* options) const; 
    117117 
    118118    void parseModel(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const; 
     
    871871        } 
    872872    } 
    873      
     873 
    874874    if (!filenameLeft.empty() && !filenameRight.empty())  
    875875        constructor.addStereoImagePair(filenameLeft,imageDataLeft, 
    876                                        filenameRight, imageDataRight, 
     876                                       filenameRight, imageDataRight, 
    877877                                       positionRead ? positionData : constructor.getImagePositionData()); 
    878878 
     
    13861386#include <iostream> 
    13871387 
     1388 
     1389struct MyFindFileCallback : public osgDB::FindFileCallback 
     1390{ 
     1391    virtual std::string findDataFile(const std::string& filename, const osgDB::Options* options, osgDB::CaseSensitivity caseSensitivity) 
     1392    { 
     1393        osg::notify(osg::NOTICE)<<std::endl<<std::endl<<"find file "<<filename<<std::endl; 
     1394 
     1395        const osgDB::FilePathList& paths = options ? options->getDatabasePathList() : osgDB::getDataFilePathList(); 
     1396 
     1397        for(osgDB::FilePathList::const_iterator itr = paths.begin(); 
     1398            itr != paths.end(); 
     1399            ++itr) 
     1400        { 
     1401            const std::string& path = *itr; 
     1402            std::string newpath = osgDB::concatPaths(path, filename); 
     1403            if (osgDB::containsServerAddress(path)) 
     1404            { 
     1405                osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); 
     1406                osg::notify(osg::NOTICE)<<"  file on server "<<*itr<<", try path "<<newpath<<std::endl; 
     1407                osg::notify(osg::NOTICE)<<"  we have curl rw= "<<rw<<std::endl; 
     1408                if (rw && rw->fileExists(newpath, options)) 
     1409                { 
     1410                    osg::notify(osg::NOTICE)<<"  FOUND on server "<<newpath<<std::endl; 
     1411                    return newpath; 
     1412                } 
     1413            } 
     1414            else 
     1415            { 
     1416                if(osgDB::fileExists(newpath)) 
     1417                { 
     1418                    osg::notify(osg::NOTICE)<<" FOUND "<<newpath<<std::endl; 
     1419                    return newpath; 
     1420                } 
     1421            } 
     1422        } 
     1423 
     1424        return osgDB::Registry::instance()->findDataFileImplementation(filename, options, caseSensitivity); 
     1425    } 
     1426}; 
     1427 
     1428class OSGDB_EXPORT MyReadFileCallback : public virtual osgDB::ReadFileCallback 
     1429{ 
     1430    public: 
     1431 
     1432        osgDB::FilePathList _paths; 
     1433 
     1434        typedef std::map< std::string, osg::ref_ptr<osg::Object> >  ObjectCache; 
     1435 
     1436        enum ObjectType 
     1437        { 
     1438            OBJECT, 
     1439            IMAGE, 
     1440            HEIGHT_FIELD, 
     1441            NODE, 
     1442            SHADER 
     1443        }; 
     1444 
     1445        osgDB::ReaderWriter::ReadResult readLocal(ObjectType type, const std::string& filename, const osgDB::Options* options) 
     1446        { 
     1447            osg::notify(osg::INFO)<<"Trying local file "<<filename<<std::endl; 
     1448 
     1449            switch(type) 
     1450            { 
     1451                case(OBJECT): return osgDB::Registry::instance()->readObjectImplementation(filename,options); 
     1452                case(IMAGE): return osgDB::Registry::instance()->readImageImplementation(filename,options); 
     1453                case(HEIGHT_FIELD): return osgDB::Registry::instance()->readHeightFieldImplementation(filename,options); 
     1454                case(NODE): return osgDB::Registry::instance()->readNodeImplementation(filename,options); 
     1455                case(SHADER): return osgDB::Registry::instance()->readShaderImplementation(filename,options); 
     1456            } 
     1457            return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; 
     1458        } 
     1459 
     1460         
     1461        osgDB::ReaderWriter::ReadResult readFileCache(ObjectType type, const std::string& filename, const osgDB::Options* options) 
     1462        { 
     1463 
     1464            osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; 
     1465            if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); 
     1466            if (!fileCache) return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1467 
     1468            osg::notify(osg::INFO)<<"Trying fileCache "<<filename<<std::endl; 
     1469 
     1470            osgDB::ReaderWriter::ReadResult result; 
     1471            if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) 
     1472            { 
     1473                if (fileCache->existsInCache(filename)) 
     1474                { 
     1475                    switch(type) 
     1476                    { 
     1477                        case(OBJECT): 
     1478                            result = fileCache->readObject(filename, 0); 
     1479                            break; 
     1480                        case(IMAGE): 
     1481                            result = fileCache->readImage(filename, 0); 
     1482                            break; 
     1483                        case(HEIGHT_FIELD): 
     1484                            result = fileCache->readHeightField(filename, 0); 
     1485                            break; 
     1486                        case(NODE): 
     1487                            result = fileCache->readNode(filename,0); 
     1488                            break; 
     1489                        case(SHADER): 
     1490                            result = fileCache->readShader(filename, 0); 
     1491                            break; 
     1492                    } 
     1493 
     1494                    if (result.success()) 
     1495                    { 
     1496                        osg::notify(osg::INFO)<<"   File read from FileCache."<<std::endl; 
     1497                        return result; 
     1498                    } 
     1499 
     1500                    osg::notify(osg::NOTICE)<<"   File in FileCache, but not successfully read"<<std::endl; 
     1501                } 
     1502                else 
     1503                { 
     1504                    osg::notify(osg::INFO)<<"   File does not exist in FileCache: "<<fileCache->createCacheFileName(filename)<<std::endl; 
     1505                } 
     1506            } 
     1507 
     1508            return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1509 
     1510        } 
     1511 
     1512        osgDB::ReaderWriter::ReadResult readServer(ObjectType type, const std::string& filename, const osgDB::Options* options) 
     1513        { 
     1514            osg::notify(osg::INFO)<<"Trying server file "<<filename<<std::endl; 
     1515 
     1516            osgDB::ReaderWriter::ReadResult result; 
     1517            osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); 
     1518            if (!rw) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; 
     1519 
     1520            switch(type) 
     1521            { 
     1522                case(OBJECT): 
     1523                    result = rw->readObject(filename,options); 
     1524                    break; 
     1525                case(IMAGE): 
     1526                    result = rw->readImage(filename,options); 
     1527                    break; 
     1528                case(HEIGHT_FIELD): 
     1529                    result = rw->readHeightField(filename,options); 
     1530                    break; 
     1531                case(NODE): 
     1532                    result = rw->readNode(filename,options); 
     1533                    break; 
     1534                case(SHADER): 
     1535                    result = rw->readShader(filename,options); 
     1536                    break; 
     1537            } 
     1538 
     1539            if (result.success()) 
     1540            { 
     1541                osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; 
     1542                if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); 
     1543 
     1544                if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) 
     1545                { 
     1546                    switch(type) 
     1547                    { 
     1548                        case(OBJECT): 
     1549                            fileCache->writeObject(*result.getObject(),filename,options); 
     1550                            break; 
     1551                        case(IMAGE): 
     1552                            result.getImage()->setFileName(filename); 
     1553                            fileCache->writeImage(*result.getImage(),filename,options); 
     1554                            break; 
     1555                        case(HEIGHT_FIELD): 
     1556                            fileCache->writeHeightField(*result.getHeightField(),filename,options); 
     1557                            break; 
     1558                        case(NODE): 
     1559                            fileCache->writeNode(*result.getNode(),filename,options); 
     1560                            break; 
     1561                        case(SHADER): 
     1562                            fileCache->writeShader(*result.getShader(),filename,options); 
     1563                            break; 
     1564                    } 
     1565                } 
     1566 
     1567                return result; 
     1568            } 
     1569            return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1570        } 
     1571 
     1572 
     1573        osgDB::ReaderWriter::ReadResult read(const osgDB::FilePathList& filePathList, ObjectType type, const std::string& filename, const osgDB::Options* options, bool checkLocalFiles) 
     1574        { 
     1575            // go look in http paths 
     1576            for(osgDB::FilePathList::const_iterator itr = filePathList.begin(); 
     1577                itr != filePathList.end(); 
     1578                ++itr) 
     1579            { 
     1580                const std::string& path = *itr; 
     1581                std::string newpath = path.empty() ? filename : osgDB::concatPaths(path, filename); 
     1582                osgDB::ReaderWriter::ReadResult result; 
     1583                if (osgDB::containsServerAddress(newpath)) 
     1584                { 
     1585                    if (checkLocalFiles) result = readFileCache(type, newpath, options); 
     1586                    else result = readServer(type, newpath, options); 
     1587                } 
     1588                else if (checkLocalFiles && osgDB::fileExists(newpath)) 
     1589                { 
     1590                    result = readLocal(type, newpath, options); 
     1591                } 
     1592 
     1593                if (result.success()) 
     1594                { 
     1595                    osg::notify(osg::INFO)<<"   inserting object into file cache "<<filename<<", "<<result.getObject()<<std::endl; 
     1596                    _objectCache[filename] = result.getObject(); 
     1597 
     1598                    options->setPluginStringData("filename",newpath); 
     1599                    return result; 
     1600                } 
     1601            } 
     1602            return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1603        } 
     1604 
     1605        osgDB::ReaderWriter::ReadResult read(ObjectType type, const std::string& filename, const osgDB::Options* options) 
     1606        { 
     1607            osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; 
     1608            if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); 
     1609            if (fileCache && !fileCache->isFileAppropriateForFileCache(filename)) fileCache = 0; 
     1610 
     1611            osg::notify(osg::INFO)<<"reading file "<<filename<<std::endl; 
     1612            ObjectCache::iterator itr = _objectCache.find(filename); 
     1613            if (itr != _objectCache.end()) 
     1614            { 
     1615                // object is in cache, just retrieve it. 
     1616                if (itr->second.valid()) 
     1617                { 
     1618                    osg::notify(osg::INFO)<<"File retrieved from cache, filename="<<filename<<std::endl; 
     1619                    return itr->second.get(); 
     1620                } 
     1621                else 
     1622                { 
     1623                    osg::notify(osg::INFO)<<"File failed to load previously, won't attempt a second time "<<filename<<std::endl; 
     1624                    return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1625                } 
     1626            } 
     1627 
     1628            { 
     1629                bool checkLocalFiles = true; 
     1630                osgDB::ReaderWriter::ReadResult result = read(_paths, type, filename, options, checkLocalFiles); 
     1631                if (result.success()) return result; 
     1632 
     1633                if (options && !(options->getDatabasePathList().empty())) 
     1634                { 
     1635                    result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); 
     1636                    if (result.success()) return result; 
     1637                } 
     1638 
     1639                result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); 
     1640                if (result.success()) return result; 
     1641            } 
     1642 
     1643            { 
     1644                bool checkLocalFiles = false; 
     1645                osgDB::ReaderWriter::ReadResult result = read(_paths, type, filename, options, checkLocalFiles); 
     1646                if (result.success()) return result; 
     1647 
     1648                if (options && !(options->getDatabasePathList().empty())) 
     1649                { 
     1650                    result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); 
     1651                    if (result.success()) return result; 
     1652                } 
     1653 
     1654                result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); 
     1655                if (result.success()) return result; 
     1656            } 
     1657 
     1658            _objectCache[filename] = 0; 
     1659 
     1660            return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; 
     1661        } 
     1662 
     1663        virtual osgDB::ReaderWriter::ReadResult readObject(const std::string& filename, const osgDB::Options* options) 
     1664        { 
     1665            return read(OBJECT, filename, options); 
     1666        } 
     1667 
     1668        virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) 
     1669        { 
     1670            return read(IMAGE, filename, options); 
     1671        } 
     1672 
     1673        virtual osgDB::ReaderWriter::ReadResult readHeightField(const std::string& filename, const osgDB::Options* options) 
     1674        { 
     1675            return read(HEIGHT_FIELD, filename, options); 
     1676        } 
     1677 
     1678        virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::Options* options) 
     1679        { 
     1680            return read(NODE, filename, options); 
     1681        } 
     1682 
     1683        virtual osgDB::ReaderWriter::ReadResult readShader(const std::string& filename, const osgDB::Options* options) 
     1684        { 
     1685            return read(SHADER, filename, options); 
     1686        } 
     1687 
     1688    protected: 
     1689        virtual ~MyReadFileCallback() {} 
     1690 
     1691        ObjectCache _objectCache; 
     1692}; 
     1693 
    13881694osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(const std::string& file, 
    13891695                                                           const osgDB::ReaderWriter::Options* options) const 
     
    13941700    std::string fileName = osgDB::findDataFile( file ); 
    13951701    if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; 
     1702 
     1703    // code for setting up the database path so that internally referenced file are searched for on relative paths. 
     1704    osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 
     1705    local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); 
     1706    //local_opt->setFindFileCallback(new MyFindFileCallback); 
     1707    local_opt->setReadFileCallback(new MyReadFileCallback); 
    13961708 
    13971709    osgDB::XmlNode::Input input; 
     
    13991711    input.readAllDataIntoBuffer(); 
    14001712 
    1401     return readNode(input, options); 
     1713    return readNode(input, local_opt); 
    14021714} 
    14031715 
     
    14081720    input.readAllDataIntoBuffer(); 
    14091721 
    1410     return readNode(input, options); 
    1411 } 
    1412  
    1413 osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Input& input, const osgDB::ReaderWriter::Options* options) const 
     1722    osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 
     1723    //local_opt->setFindFileCallback(new MyFindFileCallback); 
     1724    local_opt->setReadFileCallback(new MyReadFileCallback); 
     1725 
     1726    return readNode(input, local_opt); 
     1727} 
     1728 
     1729osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Input& input, osgDB::ReaderWriter::Options* options) const 
    14141730{ 
    14151731    bool readOnlyHoldingPage = options ? options->getOptionString()=="holding_slide" : false; 
     
    14231739 
    14241740    doc->read(input); 
     1741 
     1742 
     1743    osg::notify(osg::NOTICE)<<"P3D parsing"<<std::endl; 
    14251744 
    14261745    // doc->write(std::cout); 
     
    14511770    } 
    14521771 
    1453     osgPresentation::SlideShowConstructor constructor; 
     1772    osgPresentation::SlideShowConstructor constructor(options); 
    14541773 
    14551774    osgDB::FilePathList previousPaths = osgDB::getDataFilePathList(); 
    14561775 
    14571776    bool readSlide = false; 
     1777 
     1778 
     1779    for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); 
     1780        itr != root->children.end(); 
     1781        ++itr) 
     1782    { 
     1783        osgDB::XmlNode* cur = itr->get(); 
     1784 
     1785        if (cur->name=="env") 
     1786        { 
     1787            char* str = strdup(cur->contents.c_str()); 
     1788            osg::notify(osg::INFO)<<"putenv("<<str<<")"<<std::endl; 
     1789            putenv(str); 
     1790        } 
     1791    } 
     1792 
     1793    std::string pathToPresentation; 
     1794    MyReadFileCallback* readFileCallback = options ? dynamic_cast<MyReadFileCallback*>(options->getReadFileCallback()) : 0; 
     1795 
     1796    if (options && !(options->getDatabasePathList().empty())) 
     1797    { 
     1798        pathToPresentation = options->getDatabasePathList().front(); 
     1799 
     1800       if (readFileCallback) readFileCallback->_paths.push_front(pathToPresentation); 
     1801    } 
     1802 
     1803 
     1804    for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); 
     1805        itr != root->children.end(); 
     1806        ++itr) 
     1807    { 
     1808        osgDB::XmlNode* cur = itr->get(); 
     1809 
     1810        if (cur->name == "path") 
     1811        { 
     1812            std::string newpath = expandEnvVarsInFileName(cur->contents); 
     1813 
     1814            // now check if an absolue or http path 
     1815            std::string::size_type colonPos = newpath.find_first_of(':'); 
     1816            std::string::size_type backslashPos = newpath.find_first_of('/'); 
     1817            std::string::size_type forwardslashPos = newpath.find_first_of('\\'); 
     1818            bool relativePath = colonPos == std::string::npos && 
     1819                                backslashPos != 0 && 
     1820                                forwardslashPos != 0; 
     1821 
     1822            if (relativePath && !pathToPresentation.empty()) 
     1823            { 
     1824                newpath = osgDB::concatPaths(pathToPresentation, newpath); 
     1825                osg::notify(osg::NOTICE)<<"relative path = "<<cur->contents<<", newpath="<<newpath<<std::endl; 
     1826            } 
     1827            else 
     1828            { 
     1829                osg::notify(osg::NOTICE)<<"absolute path = "<<cur->contents<<", newpath="<<newpath<<std::endl; 
     1830            } 
     1831 
     1832            if (readFileCallback) readFileCallback->_paths.push_back(newpath); 
     1833            else options->getDatabasePathList().push_back(newpath); 
     1834        } 
     1835    } 
     1836 
    14581837 
    14591838    for(osgDB::XmlNode::Children::iterator itr = root->children.begin();