David Callu | 28 Jan 17:02 2015
Picon

OpenFlight Reader lose relative path

Hi Robert

I currently use OpenFlight plugin to convert .flt to .osgt file and all relative path are replaced by absolute path.
So .osgt created are filesystem dependant.



problem:
OpenFlight plugin search absolute path for any image filename to get an unique ID
for each image and cache them to not read a texture twice.

src/osgPlugins/OpenFlight/PaletteRecords.cpp:l468
        // Need full path for unique key in local texture cache.
        std::string pathname = osgDB::findDataFile(filename,document.getOptions());

the new pathname if valid is use in osgDB::ReadRefImageFile and so absolute path is kept in Image object.


proposed fix:
pass filename instead of pathname to osgDB::ReadRefImageFile.


Cheers
David
Attachment (PaletteRecords.cpp): text/x-c++src, 38 KiB
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Stephan Wenglorz | 26 Jan 23:07 2015
Picon

[VPB] Fix for CMake 3 and building Debug

Hi Robert,

the attached fix corrects a link error when using CMake 3 and building 
Debug on Linux (Debian). -lvpbd could not be found when linking the 
applications against it.

Base is VPB SVN trunk revision 1053.

Cheers,
Stephan
Attachment (VpbMacroUtils.cmake): text/x-cmake, 10 KiB
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Jonathan Greig | 25 Jan 02:09 2015
Picon

osgviewerQt example fix - parent and flags

I was testing out the example and it works fine as a standalone example, but I found that it didn't work as expected when adding the class to some existing code I have to test it out. The osg widget was appearing but it didn't appear to be updating. After tweaking it to pass on the parent QWidget pointer from my code, it worked as expected. I added the WindowFlags to the attached file for good measure. If you look at the Qt Documentation for QWidget ( http://doc.qt.io/qt-5/qwidget.html#QWidget ), you'll see that is exactly where I got this from. When subclassing a widget as such, you should allow the user to pass in the parent at least, considering that has a major effect on how or if Qt may clean up the memory.

Anyway, its a simple fix.

Cheers,
Jonathan
Attachment (osgviewerQt.cpp): text/x-c++src, 6350 bytes
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Dmitry Marakasov | 24 Jan 20:05 2015
Picon

Fix gstreamer detection

Hi!

While packaging osg-3.3.3 I've discovered that gstreamer detection is
broken:

-- Could NOT find GStreamer (missing:  GSTREAMER_BASE_INCLUDE_DIRS GSTREAMER_BASE_LIBRARIES
GSTREAMER_GSTREAMER-APP_INCLUDE_DIRS GSTREAMER_GSTREAMER-APP_LIBRARIES
GSTREAMER_GSTREAMER-PBUTILS_INCLUDE_DIRS GSTREAMER_GSTREAMER-PBUTILS_LIBRARIES) (found
version "1.4.5")

though all required modules are installed.

There are two problems: first, module names are spelled incorrectly in root
CMakeLists.txt (e.g. gstreamer-app instead of app), so variables expected
for them are e.g. GSTREAMER_GSTREAMER-APP_INCLUDE_DIRS instead of
GSTREAMER_APP_INCLUDE_DIRS. 

Second, gstreamer base component is detected as GSTREAMER while checked
later as GSTREAMER_BASE. I've uncommented the detection as
GSTREAMER_BASE, but obviously that should be revisited and only one
detection left. With this patch, gstreamer is detected properly and
the plugins is successfully built and installed.

--

-- 
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
amdmi3@...  ..:  jabber:
amdmi3@...    http://www.amdmi3.ru
Attachment (osg-gstreamer.patch): text/x-diff, 1036 bytes
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Stephan Wenglorz | 21 Jan 23:15 2015
Picon

[VPB] Fix for reading/writing .source files

Hi Robert,

attached is a fix that aligns VPB with the changes made in OSG trunk 
revision 14344. ReaderWriterOSG2 now expects the "file type" option to 
be set via Options::setPluginStringData(), whereas VPB still used 
Options::setOptionString(). This should fix the problem that 
VPBReaderWriter aborts reading of .source files, so OSG tries to load a 
non-existing osgdb_source plugin, as described here:

http://forum.openscenegraph.org/viewtopic.php?t=14387

Base is SVN VPB trunk revision 1052.

Cheers,
Stephan
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Julien Valentin | 16 Jan 13:54 2015
Picon

[TransformFeedback submission (bis)]

Hi, I repost this submission because I think it has been forgotten someway

Here's a small patch adressing win32 problems introduced with my previous changes (missing #define under
win32 added in osg/Program)
Further I add few booleans in GLExtensions h et cpp...

PS:
Don't know how to "link" 
osg/Program #ifndef GL_ARB_transform_feedback2 
with 
osg/GLExtensions isTransformFeedbackSupported = osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2");

Code:

Index: include/osg/GLExtensions
===================================================================
--- include/osg/GLExtensions	(révision 14654)
+++ include/osg/GLExtensions	(copie de travail)
 <at>  <at>  -315,6 +315,8  <at>  <at> 
         bool isBufferObjectSupported;
         bool isPBOSupported;
         bool isTBOSupported;
+		bool isVAOSupported;
+		bool isTransformFeedbackSupported;

         void (GL_APIENTRY * glGenBuffers) (GLsizei n, GLuint *buffers);
         void (GL_APIENTRY * glBindBuffer) (GLenum target, GLuint buffer);
Index: include/osg/Program
===================================================================
--- include/osg/Program	(révision 14654)
+++ include/osg/Program	(copie de travail)
 <at>  <at>  -16,6 +16,7  <at>  <at> 
 /* file:        include/osg/Program
  * author:      Mike Weiblen 2008-01-02
  *              Holger Helmich 2010-10-21
+ *              Julien Valentin 2015-01-09
 */

 #ifndef OSG_PROGRAM
 <at>  <at>  -31,6 +32,12  <at>  <at> 
 #include <osg/Shader>
 #include <osg/StateAttribute>
 [b]
+#ifndef GL_ARB_transform_feedback2
+	#define GL_RASTERIZER_DISCARD 0x8C89
+	#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+	#define GL_SEPARATE_ATTRIBS 0x8C8D
+#endif[/b]
+
 namespace osg {

 class State;
Index: src/osg/GLExtensions.cpp
===================================================================
--- src/osg/GLExtensions.cpp	(révision 14654)
+++ src/osg/GLExtensions.cpp	(copie de travail)
 <at>  <at>  -678,8 +678,9  <at>  <at> 
     setGLExtensionFuncPtr(glTexBuffer, "glTexBuffer","glTexBufferARB" );

     isPBOSupported = OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object");
     isUniformBufferObjectSupported = osg::isGLExtensionSupported(contextID, "GL_ARB_uniform_buffer_object");
     isTBOSupported = osg::isGLExtensionSupported(contextID,"GL_ARB_texture_buffer_object");
+	isVAOSupported = osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_array_object");
+	isTransformFeedbackSupported = osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2");

PS again:reading the specs again
https://www.opengl.org/registry/specs/ARB/transform_feedback2.txt
https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt
I have doubts about portability without AMD/NVIDIA GTX "big" cards.
Would require users feedback from exotic driver...

Thank you!

Cheers,
Julien

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=62345#62345

_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Javier Taibo | 15 Jan 12:34 2015
Picon

Fix to FFMPEG plug-in

  Hi Robert,

  I have found a "bug" in the new audio decoding code (actually I think the bug is in ffmpeg, but anyway it should be wise to protect the OSG plug-in about it). I am attaching a security check in FFmpegDecoderAudio.cpp.

  If anybody is curious about the problem, it happens sometimes when decoding an AAC audio stream. It eventually includes a PCE block inside the AAC audio frame and then ffmpeg audio decoding function signals a "new_frame" with 1024 samples, but a null pointer instead of the audio data. It can be easily detected because in these cases number of channels is 0. Maybe this is the intended behaviour for ffmpeg, but I find it quite weird.


  Regards,

--
Javier Taibo

_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Andreas Henne | 11 Jan 19:03 2015
Picon

Modern OpenGL core profile fixes

Hi,
I am currently porting an application so that it uses the OpenGL core profile, mainly in order to gain access
to modern OpenGL features under OS X. I had to make some changes to osg so that it does not use deprecated functions:

Texture::getModeUsage now only adds the texture mode if FIXED_FUNCTION_AVAILABLE is defined
PolygonMode::apply now can still be used to achieve wireframe rendering in GL3 core profile (previously
it was ignored completely)
State::initializeExtensionProcs now only queries GL_MAX_TEXTURE_COORDS if
FIXED_FUNCTION_AVAILABLE is defined
Texture::applyTexParameters: CLAMP is translated to CLAMP_TO_EDGE if OSG_GL3_AVAILABLE is defined
Texture::applyTexParameters: GL_DEPTH_TEXTURE_MODE_ARB is not set if neither GL1 nor GL2 is available

I also made a change that is completely unrelated to core profile compatibility in State.cpp. Previously,
State created a GLExtensions object in its constructor and deleted it in its destructor. It also called
GLExtensions::Set when creating and deleting the extension object, which in my opinion is problematic
because it may delete an extension object that was not created by the State object. I changed State so that
it simply uses GLExtensions::Get(_contextID, true) to get its extension object and removed the calls to
GLExtensions::Set. I did this because I had a strange and unpredictable problem with the extension
object in another part of my code and wanted to simplify the initialization process.

My patch is based on the current github repository (osg116).

My application also uses osgText, which required much more changes to work with the core profile. Most
notably I had to change the Glyph class so that it uses VBOs. It was also necessary to change the font texture
format, because GL_ALPHA is deprecated. You probably do not want to merge my changes to osgText yet,
because additional testing is required under different platforms. I could submit the files later after
additional testing.

Cheers,
Andreas

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=62285#62285

Attachments: 
http://forum.openscenegraph.org//files/glcorefixes_855.zip
Farshid Lashkari | 6 Jan 22:09 2015
Picon

Fix reading image data from compressed cubemaps

Hi Robert,

I've made a small change to osg::Image::readImageFromCurrentTexture to allow reading data from compressed cubemap textures.

Cheers,
Farshid
Attachment (Image.zip): application/zip, 15 KiB
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Jason Beverage | 5 Jan 18:25 2015
Picon

Fix for STL plugin on windows

Hi Robert,


Here is a fix to the STL plugin that fixes build errors introduced in the last commit.  It's just a simple addition of the stdint.h header.

Thanks!

Jason
// -*-c++-*-

/*
 * $Id$
 *
 * STL importer for OpenSceneGraph.
 *
 * Copyright (c) 2004 Ulrich Hertlein <u.hertlein <at> sandbox.de>
 * Copyright (c) 2012 Piotr Domagalski <piotr <at> domagalski.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <osg/Notify>
#include <osg/Endian>

#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>

#include <osgUtil/TriStripVisitor>
#include <osgUtil/SmoothingVisitor>
#include <osg/TriangleFunctor>

#include <osg/Geode>
#include <osg/Geometry>

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <string.h>
#include <stdint.h>

#include <memory>

struct STLOptionsStruct {
    bool smooth;
    bool separateFiles;
    bool dontSaveNormals;
    bool noTriStripPolygons;
};

STLOptionsStruct parseOptions(const osgDB::ReaderWriter::Options* options)  {

    STLOptionsStruct localOptions;
    localOptions.smooth = false;
    localOptions.separateFiles = false;
    localOptions.dontSaveNormals = false;
    localOptions.noTriStripPolygons = false;

    if (options != NULL)
    {
        std::istringstream iss(options->getOptionString());
        std::string opt;
        while (iss >> opt)
        {
            if (opt == "smooth")
            {
                localOptions.smooth = true;
            }
            else if (opt == "separateFiles")
            {
                localOptions.separateFiles = true;
            }
            else if (opt == "dontSaveNormals")
            {
                localOptions.dontSaveNormals = true;
            }
            else if (opt == "noTriStripPolygons")
            {
                localOptions.noTriStripPolygons = true;
            }
        }
    }

    return localOptions;
}

/**
 * STL importer for OpenSceneGraph.
 */
class ReaderWriterSTL : public osgDB::ReaderWriter
{
public:
    ReaderWriterSTL()
    {
        supportsExtension("stl", "STL binary format");
        supportsExtension("sta", "STL ASCII format");
        supportsOption("smooth", "Run SmoothingVisitor");
        supportsOption("separateFiles", "Save each geode in a different file. Can result in a huge amount of files!");
        supportsOption("dontSaveNormals", "Set all normals to [0 0 0] when saving to a file.");
    }

    virtual const char* className() const
    {
        return "STL Reader";
    }

    virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) const;
    virtual WriteResult writeNode(const osg::Node& node, const std::string& fileName, const Options* =
NULL) const;

private:
    class ReaderObject
    {
    public:
        ReaderObject(bool noTriStripPolygons, bool generateNormals = true):
            _noTriStripPolygons(noTriStripPolygons),
            _generateNormal(generateNormals),
            _numFacets(0)
        {
        }

        virtual ~ReaderObject()
        {
        }

        enum ReadResult
        {
            ReadSuccess,
            ReadError,
            ReadEOF
        };

        virtual ReadResult read(FILE *fp) = 0;

        osg::ref_ptr<osg::Geometry> asGeometry() const
        {
            osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

            geom->setVertexArray(_vertex.get());

            if (_normal.valid())
            {
                // need to convert per triangle normals to per vertex
                osg::ref_ptr<osg::Vec3Array> perVertexNormals = new osg::Vec3Array;
                perVertexNormals->reserveArray(_normal->size() * 3);
                for(osg::Vec3Array::iterator itr = _normal->begin();
                    itr != _normal->end();
                    ++itr)
                {
                    perVertexNormals->push_back(*itr);
                    perVertexNormals->push_back(*itr);
                    perVertexNormals->push_back(*itr);
                }

                geom->setNormalArray(perVertexNormals.get(), osg::Array::BIND_PER_VERTEX);
            }

            if (_color.valid())
            {
                // need to convert per triangle colours to per vertex
                OSG_INFO << "STL file with color" << std::endl;
                osg::ref_ptr<osg::Vec4Array> perVertexColours = new osg::Vec4Array;
                perVertexColours->reserveArray(_color->size() * 3);
                for(osg::Vec4Array::iterator itr = _color->begin();
                    itr != _color->end();
                    ++itr)
                {
                    perVertexColours->push_back(*itr);
                    perVertexColours->push_back(*itr);
                    perVertexColours->push_back(*itr);
                }

                if(perVertexColours->size() == geom->getVertexArray()->getNumElements()) {
                    geom->setColorArray(perVertexColours.get(), osg::Array::BIND_PER_VERTEX);
                }
            }

            geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, _numFacets * 3));

            if(!_noTriStripPolygons) {
                osgUtil::TriStripVisitor tristripper;
                tristripper.stripify(*geom);
            }

            return geom;
        }

        bool isEmpty()
        {
            return _numFacets == 0;
        }

        std::string& getName()
        {
            return _solidName;
        }

    protected:
        bool _noTriStripPolygons;
        bool _generateNormal;
        unsigned int _numFacets;

        std::string _solidName;
        osg::ref_ptr<osg::Vec3Array> _vertex;
        osg::ref_ptr<osg::Vec3Array> _normal;
        osg::ref_ptr<osg::Vec4Array> _color;

        void clear()
        {
            _solidName = "";
            _numFacets = 0;
            _vertex = osg::ref_ptr<osg::Vec3Array>();
            _normal = osg::ref_ptr<osg::Vec3Array>();
            _color = osg::ref_ptr<osg::Vec4Array>();
        }
    };

    class AsciiReaderObject : public ReaderObject
    {
    public:
        AsciiReaderObject(bool noTriStripPolygons)
        : ReaderObject(noTriStripPolygons)
        {
        }

        ReadResult read(FILE *fp);
    };

    class BinaryReaderObject : public ReaderObject
    {
    public:
        BinaryReaderObject(unsigned int expectNumFacets, bool noTriStripPolygons, bool generateNormals = true)
            : ReaderObject(noTriStripPolygons, generateNormals),
            _expectNumFacets(expectNumFacets)
        {
        }

        ReadResult read(FILE *fp);

    protected:
        unsigned int _expectNumFacets;
    };

    class CreateStlVisitor : public osg::NodeVisitor
    {
    public:
        CreateStlVisitor(std::string const & fout, const osgDB::ReaderWriter::Options* options = 0):
            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
            counter(0)
        {
            m_localOptions = parseOptions(options);
            if (m_localOptions.separateFiles)
            {
                OSG_INFO << "ReaderWriterSTL::writeNode: Files are written separately" << std::endl;
                m_fout_ext = osgDB::getLowerCaseFileExtension(fout);
                m_fout = fout.substr(0, fout.rfind(m_fout_ext) - 1);
            }
            else
            {
                m_fout = fout;
                m_f = new osgDB::ofstream(m_fout.c_str());
            }

            if (m_localOptions.dontSaveNormals)
            {
                OSG_INFO << "ReaderWriterSTL::writeNode: Not saving normals" << std::endl;
            }
        }

        std::string i2s(int i)
        {
            char buf[16];  // -2^31 == -2147483648 needs 11 chars + \0  -> 12 (+4 for security ;-)
            sprintf(buf, "%d", i);
            return buf;
        }

        virtual void apply(osg::Geode& node)
        {
            osg::Matrix mat = osg::computeLocalToWorld(getNodePath());

            if (m_localOptions.separateFiles)
            {
                std::string sepFile = m_fout + i2s(counter) + "." + m_fout_ext;
                m_f = new osgDB::ofstream(sepFile.c_str());
            }

            if (node.getName().empty())
                *m_f << "solid " << counter << std::endl;
            else
                *m_f << "solid " << node.getName() << std::endl;

            for (unsigned int i = 0; i < node.getNumDrawables(); ++i)
            {
                osg::TriangleFunctor<PushPoints> tf;
                tf.m_stream = m_f;
                tf.m_mat = mat;
                tf.m_dontSaveNormals = m_localOptions.dontSaveNormals;
                node.getDrawable(i)->accept(tf);
            }

            if (node.getName().empty())
                *m_f << "endsolid " << counter << std::endl;
            else
                *m_f << "endsolid " << node.getName() << std::endl;

            if (m_localOptions.separateFiles)
            {
                m_f->close();
                delete m_f;
            }

            ++counter;
            traverse(node);
        }

        ~CreateStlVisitor()
        {
            if (m_localOptions.separateFiles)
            {
                OSG_INFO << "ReaderWriterSTL::writeNode: " << counter - 1 << " files were written" << std::endl;
            }
            else
            {
                m_f->close();
                delete m_f;
            }
        }

        const std::string& getErrorString() const { return m_ErrorString; }

    private:
        int counter;
        std::ofstream* m_f;
        std::string m_fout;
        std::string m_fout_ext;
        std::string m_ErrorString;
        STLOptionsStruct m_localOptions;

        struct PushPoints
        {
            std::ofstream* m_stream;
            osg::Matrix m_mat;
            bool m_dontSaveNormals;

            inline void operator () (const osg::Vec3& _v1, const osg::Vec3& _v2, const osg::Vec3& _v3, bool treatVertexDataAsTemporary)
            {
                osg::Vec3 v1 = _v1 * m_mat;
                osg::Vec3 v2 = _v2 * m_mat;
                osg::Vec3 v3 = _v3 * m_mat;
                osg::Vec3 vV1V2 = v2 - v1;
                osg::Vec3 vV1V3 = v3 - v1;
                osg::Vec3 vNormal = vV1V2.operator ^(vV1V3);
                if (m_dontSaveNormals)
                    *m_stream << "facet normal 0 0 0" << std::endl;
                else
                    *m_stream << "facet normal " << vNormal[0] << " " << vNormal[1] << " " << vNormal[2] << std::endl;
                *m_stream << "outer loop" << std::endl;
                *m_stream << "vertex " << v1[0] << " " << v1[1] << " " << v1[2] << std::endl;
                *m_stream << "vertex " << v2[0] << " " << v2[1] << " " << v2[2] << std::endl;
                *m_stream << "vertex " << v3[0] << " " << v3[1] << " " << v3[2] << std::endl;
                *m_stream << "endloop" << std::endl;
                *m_stream << "endfacet" << std::endl;
            }
        };
    };
};

// Register with Registry to instantiate the above reader/writer.
REGISTER_OSGPLUGIN(stl, ReaderWriterSTL)

struct StlHeader
{
    char text[80];
    unsigned int numFacets;
};
const unsigned int sizeof_StlHeader = 84;

struct StlVector
{
    float x, y, z;
};
struct StlFacet
{
    StlVector normal;
    StlVector vertex[3];
    unsigned short color;
};
const unsigned int sizeof_StlFacet = 50;

const unsigned short StlHasColor = 0x8000;
const unsigned short StlColorSize = 0x1f;        // 5 bit
const float StlColorDepth = float(StlColorSize); // 2^5 - 1

// Check if the file comes from magics, and retrieve the corresponding data
// Magics files have a header with a "COLOR=" field giving the color of the whole model
bool fileComesFromMagics(FILE *fp, osg::Vec4& magicsColor)
{
    char header[80];
    const float magicsColorDepth = 255.f;

    ::rewind(fp);

    size_t bytes_read = fread((void*) &header, sizeof(header), 1, fp);
    if (bytes_read!=sizeof(header)) return false;

    ::fseek(fp, sizeof_StlHeader, SEEK_SET);

    std::string magicsColorPattern ("COLOR=");
    std::string headerStr = std::string(header);
    if(size_t colorFieldPos = headerStr.find(magicsColorPattern) != std::string::npos)
    {
        int colorIndex = colorFieldPos + magicsColorPattern.size() - 1;
        float r = (uint8_t)header[colorIndex] / magicsColorDepth;
        float g = (uint8_t)header[colorIndex + 1] / magicsColorDepth;
        float b = (uint8_t)header[colorIndex + 2] / magicsColorDepth;
        float a = (uint8_t)header[colorIndex + 3] / magicsColorDepth;
        magicsColor = osg::Vec4(r, g, b, a);
        return true;
    }

    return false;
}

osgDB::ReaderWriter::ReadResult ReaderWriterSTL::readNode(const std::string& file, const
osgDB::ReaderWriter::Options* options) const
{
    std::string ext = osgDB::getLowerCaseFileExtension(file);
    if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

    std::string fileName = osgDB::findDataFile(file, options);
    if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

    STLOptionsStruct localOptions = parseOptions (options);

    if (sizeof(unsigned int) != 4)
    {
        OSG_NOTICE<<"Waring: STL reading not supported as unsigned int is not 4 bytes on this system."<<std::endl;
        return ReadResult::ERROR_IN_READING_FILE;
    }

    OSG_INFO << "ReaderWriterSTL::readNode(" << fileName.c_str() << ")" << std::endl;

    // determine ASCII vs. binary mode
    FILE* fp = osgDB::fopen(fileName.c_str(), "rb");
    if (!fp)
    {
        return ReadResult::FILE_NOT_FOUND;
    }

    // assumes "unsigned int" is 4 bytes...
    StlHeader header;
    if (fread((void*) &header, sizeof(header), 1, fp) != 1)
    {
        fclose(fp);
        return ReadResult::ERROR_IN_READING_FILE;
    }
    bool isBinary = false;

    // calculate expected file length from number of facets
    unsigned int expectFacets = header.numFacets;
    if (osg::getCpuByteOrder() == osg::BigEndian)
    {
        osg::swapBytes4((char*) &expectFacets);
    }
    off_t expectLen = sizeof_StlHeader + expectFacets * sizeof_StlFacet;

    struct stat stb;
    if (fstat(fileno(fp), &stb) < 0)
    {
        OSG_FATAL << "ReaderWriterSTL::readNode: Unable to stat '" << fileName << "'" << std::endl;
        fclose(fp);
        return ReadResult::ERROR_IN_READING_FILE;
    }

    if (stb.st_size == expectLen)
    {
        isBinary = true;
    }
    else if (strstr(header.text, "solid") != 0)
    {
        isBinary = false;
    }
    else
    {
        OSG_FATAL << "ReaderWriterSTL::readNode(" << fileName.c_str() << ") unable to determine file format"
<< std::endl;
        fclose(fp);
        return ReadResult::ERROR_IN_READING_FILE;
    }

    if (!isBinary)
    {
        fclose(fp);
        fp = osgDB::fopen(fileName.c_str(), "r");
    }

    osg::ref_ptr<osg::Group> group = new osg::Group;

    // read
    rewind(fp);

    ReaderObject *readerObject;

    if (isBinary)
        readerObject = new BinaryReaderObject(expectFacets, localOptions.noTriStripPolygons);
    else
        readerObject = new AsciiReaderObject(localOptions.noTriStripPolygons);

    std::auto_ptr<ReaderObject> readerPtr(readerObject);

    while (1)
    {
        ReaderObject::ReadResult result;

        if ((result = readerPtr->read(fp)) == ReaderObject::ReadError)
        {
            fclose(fp);
            return ReadResult::FILE_NOT_HANDLED;
        }

        if (!readerPtr->isEmpty())
        {
            osg::ref_ptr<osg::Geometry> geom = readerPtr->asGeometry();
            osg::ref_ptr<osg::Geode> geode = new osg::Geode;
            geode->addDrawable(geom.get());
            geode->setName(readerPtr->getName());
            group->addChild(geode.get());
        }

        if (result == ReaderObject::ReadEOF)
            break;
    }

    fclose(fp);

    if (localOptions.smooth)
    {
        osgUtil::SmoothingVisitor smoother;
        group->accept(smoother);
    }

    return group.get();
}

/**********************************************************************
 *
 * Private
 *
 **********************************************************************/

ReaderWriterSTL::ReaderObject::ReadResult ReaderWriterSTL::AsciiReaderObject::read(FILE* fp)
{
    unsigned int vertexCount = 0;
    unsigned int facetIndex[] = { 0, 0, 0 };
    unsigned int vertexIndex = 0;
    unsigned int normalIndex = 0;

    const int MaxLineSize = 256;
    char buf[MaxLineSize];
    char sx[MaxLineSize], sy[MaxLineSize], sz[MaxLineSize];

    if (!isEmpty())
    {
        clear();
    }

    while (fgets(buf, sizeof(buf), fp))
    {
        // strip '\n' or '\r\n' and trailing whitespace
        unsigned int len = strlen(buf) - 1;

        while (len && (buf[len] == '\n' || buf[len] == '\r' || isspace(buf[len])))
        {
            buf[len--] = '\0';
        }

        if (len == 0 || buf[0] == '\0')
        {
            continue;
        }

        // strip leading whitespace
        char* bp = buf;
        while (isspace(*bp))
        {
            ++bp;
        }

        if (strncmp(bp, "vertex", 6) == 0)
        {
            if (sscanf(bp + 6, "%s %s %s", sx, sy, sz) == 3)
            {
                if (!_vertex.valid())
                    _vertex = new osg::Vec3Array;

                float vx = osg::asciiToFloat(sx);
                float vy = osg::asciiToFloat(sy);
                float vz = osg::asciiToFloat(sz);

                vertexIndex = _vertex->size();
                if (vertexCount < 3)
                {
                    _vertex->push_back(osg::Vec3(vx, vy, vz));
                    facetIndex[vertexCount++] = vertexIndex;
                }
                else
                {
                    /*
                     * There are some invalid ASCII files around (at least one ;-)
                     * that have more than three vertices per facet - add an
                     * additional triangle.
                     */
                    _normal->push_back((*_normal)[normalIndex]);
                    _vertex->push_back((*_vertex)[facetIndex[0]]);
                    _vertex->push_back((*_vertex)[facetIndex[2]]);
                    _vertex->push_back(osg::Vec3(vx, vy, vz));
                    facetIndex[1] = facetIndex[2];
                    facetIndex[2] = vertexIndex;
                    _numFacets++;
                }
            }
        }
        else if (strncmp(bp, "facet", 5) == 0)
        {
            if (sscanf(bp + 5, "%*s %s %s %s", sx, sy, sz) == 3)
            {
                float nx = osg::asciiToFloat(sx);
                float ny = osg::asciiToFloat(sy);
                float nz = osg::asciiToFloat(sz);

                if (!_normal.valid())
                    _normal = new osg::Vec3Array;

                osg::Vec3 normal(nx, ny, nz);
                normal.normalize();

                normalIndex = _normal->size();
                _normal->push_back(normal);

                _numFacets++;
                vertexCount = 0;
            }
        }
        else if (strncmp(bp, "solid", 5) == 0)
        {
            OSG_INFO << "STL loader parsing '" << bp + 6 << "'" << std::endl;
            _solidName = bp + 6;
        }
        else if (strncmp(bp, "endsolid", 8) == 0)
        {
            OSG_INFO << "STL loader done parsing '" << _solidName << "'" << std::endl;
            return ReadSuccess;
        }
    }

    return ReadEOF;
}

ReaderWriterSTL::ReaderObject::ReadResult ReaderWriterSTL::BinaryReaderObject::read(FILE* fp)
{
    if (isEmpty())
    {
        clear();
    }

    _numFacets = _expectNumFacets;

    // Check if the file comes from Magics and retrieve the global color from the header
    osg::Vec4 magicsHeaderColor;
    bool comesFromMagics = fileComesFromMagics(fp, magicsHeaderColor);

    // seek to beginning of facets
    ::fseek(fp, sizeof_StlHeader, SEEK_SET);

    StlFacet facet;
    for (unsigned int i = 0; i < _expectNumFacets; ++i)
    {
        if (::fread((void*) &facet, sizeof_StlFacet, 1, fp) != 1)
        {
            OSG_FATAL << "ReaderWriterSTL::readStlBinary: Failed to read facet " << i << std::endl;
            return ReadError;
        }

        // vertices
        if (!_vertex.valid())
            _vertex = new osg::Vec3Array;

        osg::Vec3 v0(facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0].z);
        osg::Vec3 v1(facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1].z);
        osg::Vec3 v2(facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2].z);
        _vertex->push_back(v0);
        _vertex->push_back(v1);
        _vertex->push_back(v2);

        // per-facet normal
        osg::Vec3 normal;
        if (_generateNormal)
        {
            osg::Vec3 d01 = v1 - v0;
            osg::Vec3 d02 = v2 - v0;
            normal = d01 ^ d02;
            normal.normalize();
        }
        else
        {
            normal.set(facet.normal.x, facet.normal.y, facet.normal.z);
        }

        if (!_normal.valid())
            _normal = new osg::Vec3Array;
        _normal->push_back(normal);

        /*
         * color extension
         * RGB555 with most-significat bit indicating if color is present
         *
         * The magics files may use whether per-face or per-object colors
         * for a given face, according to the value of the last bit (0 = per-face, 1 = per-object)
         * Moreover, magics uses RGB instead of BGR (as the other softwares)
         */
        if (!_color.valid())
        {
            _color = new osg::Vec4Array;
        }

        // Case of a Magics file
        if(comesFromMagics)
        {
            if(facet.color & StlHasColor) // The last bit is 1, the per-object color is used
            {
                _color->push_back(magicsHeaderColor);
            }
            else // the last bit is 0, the facet has its own unique color
            {
                float b = ((facet.color >> 10) & StlColorSize) / StlColorDepth;
                float g = ((facet.color >> 5) & StlColorSize) / StlColorDepth;
                float r = (facet.color & StlColorSize) / StlColorDepth;
                _color->push_back(osg::Vec4(r, g, b, 1.0f));
            }
        }
        // Case of a generic file
        else if (facet.color & StlHasColor) // The color is valid if the last bit is 1
            {
                float r = ((facet.color >> 10) & StlColorSize) / StlColorDepth;
                float g = ((facet.color >> 5) & StlColorSize) / StlColorDepth;
                float b = (facet.color & StlColorSize) / StlColorDepth;
                _color->push_back(osg::Vec4(r, g, b, 1.0f));
            }
    }

    return ReadEOF;
}

osgDB::ReaderWriter::WriteResult ReaderWriterSTL::writeNode(const osg::Node& node, const
std::string& fileName, const Options* opts) const
{
    std::string ext = osgDB::getLowerCaseFileExtension(fileName);
    if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;

    if (ext != "stl")
    {
        OSG_FATAL << "ReaderWriterSTL::writeNode: Only STL ASCII files supported" << std::endl;
        return WriteResult::FILE_NOT_HANDLED;
    }

    CreateStlVisitor createStlVisitor(fileName, opts);
    const_cast<osg::Node&>(node).accept(createStlVisitor);

    if (createStlVisitor.getErrorString().empty())
    {
        return WriteResult::FILE_SAVED;
    }
    else
    {
        OSG_FATAL << "Error: " << createStlVisitor.getErrorString() << std::endl;
        return WriteResult::ERROR_IN_WRITING_FILE;
    }
}

/* vim: set ts=4 sw=4 expandtab: */
_______________________________________________
osg-submissions mailing list
osg-submissions@...
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
Julien Valentin | 28 Dec 16:45 2014
Picon

[Merge my changes?]

Hi,
For long now (3.2 release) I had to branch from the osg trunk in order to hack few stuff.

You can see the whole changes here:
https://github.com/openscenegraph/osg/pull/15/files

The diff is not very clean so,
To sum up changes, I had:
-some extensions in GL2Extensions
- GL_TEXTURE_BUFFER as target in osg::StateSet
- a VBO based transform feed back example
-correct some serializers( in osgVolume)

Is it enough to merge with these few changes with 3.3 trunk or would you like a proper diff patch?

Thank you!

Cheers,
Julien

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=62194#62194

Gmane