diff --git a/applications/osgfilecache/osgfilecache.cpp b/applications/osgfilecache/osgfilecache.cpp index 97766ddd9..0c42a7e05 100644 --- a/applications/osgfilecache/osgfilecache.cpp +++ b/applications/osgfilecache/osgfilecache.cpp @@ -130,6 +130,40 @@ struct Extents osg::Vec2d _max; }; +class CheckValidVisitor : public osg::NodeVisitor +{ +public: + + CheckValidVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numInvalidGeometries(0) {} + + void apply(osg::Geode& geode) + { + unsigned int local_numInvalidGeometries = 0; + for(unsigned int i=0; i(geode.getDrawable(i)); + if (geometry) + { + if (!geometry->verifyArrays(_errorReports)) ++local_numInvalidGeometries; + } + } + if (local_numInvalidGeometries) + { + _errorReports<<"Geode "<existsInCache(filename)) { osg::notify(osg::NOTICE)<<"reading from FileCache: "<readNode(filename, osgDB::Registry::instance()->getOptions()).takeNode(); + node = _fileCache->readNode(filename, osgDB::Registry::instance()->getOptions()).takeNode(); } else { osg::notify(osg::NOTICE)<<"reading : "<writeNode(*node, filename, osgDB::Registry::instance()->getOptions()); } - return node; } } else { osg::notify(osg::NOTICE)<<"reading : "<accept(cvv); + if (!cvv.valid()) + { + OSG_NOTICE<<"Warning, errors in geometry found in file "<drawImplementation(renderInfo); @@ -2483,6 +2491,245 @@ void Geometry::computeInternalOptimizedGeometry() } } +class CheckArrayValidity +{ +public: + CheckArrayValidity(const osg::Geometry* geometry) + { + numPrimitiveSets = geometry->getNumPrimitiveSets(); + primitiveNum = 0; + maxVertexNumber = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // draw the primitives themselves. + // + for(unsigned int primitiveSetNum=0; primitiveSetNum != numPrimitiveSets; ++primitiveSetNum) + { + const PrimitiveSet* primitiveset = geometry->getPrimitiveSet(primitiveSetNum); + + GLenum mode=primitiveset->getMode(); + + unsigned int primLength; + switch(mode) + { + case(GL_POINTS): primLength=1; break; + case(GL_LINES): primLength=2; break; + case(GL_TRIANGLES): primLength=3; break; + case(GL_QUADS): primLength=4; break; + default: primLength=0; break; // compute later when =0. + } + + // draw primitives by the more flexible "slow" path, + // sending OpenGL glBegin/glVertex.../glEnd(). + switch(primitiveset->getType()) + { + case(PrimitiveSet::DrawArraysPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawArrays* drawArray = static_cast(primitiveset); + + unsigned int primCount=0; + unsigned int indexEnd = drawArray->getFirst()+drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); + vindex maxVertexNumber) maxVertexNumber = (indexEnd-1); + break; + } + case(PrimitiveSet::DrawArrayLengthsPrimitiveType): + { + const DrawArrayLengths* drawArrayLengths = static_cast(primitiveset); + unsigned int vindex=drawArrayLengths->getFirst(); + for(DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); + primItr!=drawArrayLengths->end(); + ++primItr) + { + unsigned int localPrimLength; + if (primLength==0) localPrimLength=*primItr; + else localPrimLength=primLength; + + for(GLsizei primCount=0; + primCount<*primItr; + ++vindex,++primCount) + { + if ((primCount%localPrimLength)==0) + { + primitiveNum++; + } + } + + } + if ((vindex-1) > maxVertexNumber) maxVertexNumber = (vindex-1); + break; + } + case(PrimitiveSet::DrawElementsUBytePrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUByte* drawElements = static_cast(primitiveset); + + unsigned int primCount=0; + for(DrawElementsUByte::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + if ((primCount%primLength)==0) + { + primitiveNum++; + } + unsigned int vindex = *primItr; + if (vindex > maxVertexNumber) maxVertexNumber = vindex; + } + + break; + } + case(PrimitiveSet::DrawElementsUShortPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUShort* drawElements = static_cast(primitiveset); + unsigned int primCount=0; + for(DrawElementsUShort::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + if ((primCount%primLength)==0) + { + primitiveNum++; + } + unsigned int vindex = *primItr; + if (vindex > maxVertexNumber) maxVertexNumber = vindex; + } + + break; + } + case(PrimitiveSet::DrawElementsUIntPrimitiveType): + { + if (primLength==0) primLength=primitiveset->getNumIndices(); + + const DrawElementsUInt* drawElements = static_cast(primitiveset); + unsigned int primCount=0; + for(DrawElementsUInt::const_iterator primItr=drawElements->begin(); + primItr!=drawElements->end(); + ++primCount,++primItr) + { + if ((primCount%primLength)==0) + { + primitiveNum++; + } + unsigned int vindex = *primItr; + if (vindex > maxVertexNumber) maxVertexNumber = vindex; + } + break; + } + default: + { + break; + } + } + } + } + + bool validArray(std::ostream& out, const osg::Geometry::ArrayData& arrayData, const char* arrayName) + { + unsigned int numRequired = 0; + switch(arrayData.binding) + { + case(osg::Geometry::BIND_OFF): numRequired = 0; break; + case(osg::Geometry::BIND_OVERALL): numRequired = 1; break; + case(osg::Geometry::BIND_PER_PRIMITIVE): numRequired = primitiveNum; break; + case(osg::Geometry::BIND_PER_PRIMITIVE_SET): numRequired = numPrimitiveSets; break; + case(osg::Geometry::BIND_PER_VERTEX): numRequired = maxVertexNumber+1; break; + } + + if (arrayData.indices.valid()) + { + unsigned int numIndices= arrayData.indices.valid() ? arrayData.indices->getNumElements() : 0; + if (numIndicesgetNumElements() : 0; + if (numElementsgetNumElements() : 0; + for(unsigned int i=0; iindex(i)>=numVertices) + { + out<<"Vertex indice out of bounds of vertex array"<getNumElements() : 0; + if (numVertices