Hi Allen,

I attached the code.

Andreas

This may be slightly off topic, but....

I use VRED to preview/review/check geometry that I dump out of OpenSG applications. In the latest version of VRED there is a feature where upon load it detects corrupted/invalid geometry and removes that geometry. This is nice, but unfortunately it is finding the some of my geometry is corrupted and I don't know where to start to track it down. I tried using the verify geo operation from OpenSG, but it doesn't find any problems.

Does anyone know the algorithm VRED is using to check for corruption and if so any ideas how I could duplicate it in OpenSG to find the bad geometry myself (probably through a debugger)?

Thanks,
Allen


-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users



static OSG::UInt32 _geo_errors;
static std::set<osg::GeometryPtr> _corrupted_geos;


/*!
 * \brief
 * \param
 * \return
 */
bool vrNodeUtils::verifyIndexMap(GeometryPtr &geo, bool &repair)
{
    repair = false;

    if(geo == NullFC)
        return true;

    if(geo->getIndices() == NullFC)
        return true;

    if(!geo->getIndexMapping().empty())
        return true;

    if(geo->getPositions() == NullFC)
        return true;

    UInt32 positions_size = geo->getPositions()->getSize();

    Int32 normals_size = 0;
    if(geo->getNormals() != NullFC)
        normals_size = geo->getNormals()->getSize();

    Int32 colors_size = 0;
    if(geo->getColors() != NullFC)
        colors_size = geo->getColors()->getSize();
    
    Int32 secondary_colors_size = 0;
    if(geo->getSecondaryColors() != NullFC)
        secondary_colors_size = geo->getSecondaryColors()->getSize();
    
    Int32 texccords_size = 0;
    if(geo->getTexCoords() != NullFC)
        texccords_size = geo->getTexCoords()->getSize();
    
    Int32 texccords1_size = 0;
    if(geo->getTexCoords1() != NullFC)
        texccords1_size = geo->getTexCoords1()->getSize();
    
    Int32 texccords2_size = 0;
    if(geo->getTexCoords2() != NullFC)
        texccords2_size = geo->getTexCoords2()->getSize();
    
    Int32 texccords3_size = 0;
    if(geo->getTexCoords3() != NullFC)
        texccords3_size = geo->getTexCoords3()->getSize();

    /*
    printf("sizes: %u %u %u %u %u %u %u %u\n", positions_size, normals_size,
                                   colors_size, secondary_colors_size,
                                   texccords_size, texccords1_size,
                                   texccords2_size, texccords3_size);
    */
    if((positions_size == normals_size || normals_size == 0) &&
       (positions_size == colors_size || colors_size == 0) &&
       (positions_size == secondary_colors_size || secondary_colors_size == 0) 
&&
       (positions_size == texccords_size || texccords_size == 0) &&
       (positions_size == texccords1_size || texccords1_size == 0) &&
       (positions_size == texccords2_size || texccords2_size == 0) &&
       (positions_size == texccords3_size || texccords3_size == 0))
    {
        UInt16 indexmap = 0;
        if(positions_size > 0)
            indexmap |= Geometry::MapPosition;
        if(normals_size > 0)
            indexmap |= Geometry::MapNormal;
        if(colors_size > 0)
            indexmap |= Geometry::MapColor;
        if(secondary_colors_size > 0)
            indexmap |= Geometry::MapSecondaryColor;
        if(texccords_size > 0)
            indexmap |= Geometry::MapTexCoords;
        if(texccords1_size > 0)
            indexmap |= Geometry::MapTexCoords1;
        if(texccords2_size > 0)
            indexmap |= Geometry::MapTexCoords2;
        if(texccords3_size > 0)
            indexmap |= Geometry::MapTexCoords3;

        beginEditCP(geo, Geometry::IndexMappingFieldMask);
            geo->getIndexMapping().push_back(indexmap);
        endEditCP(geo, Geometry::IndexMappingFieldMask);
        repair = true;
        return false;
    }
    else
    {
        return false;
    }

    return true;
}

/*!
 * \brief
 * \param
 * \return
 */
Action::ResultE vrNodeUtils::verifyGeometryCB(NodePtr &node)
{
    GeometryPtr geo = GeometryPtr::dcast(node->getCore());

    if(geo == NullFC)
        return Action::Continue;

    if(geo->getPositions() == NullFC)
        return Action::Continue;

    UInt32 errors = _geo_errors;

    UInt32 positions_size = geo->getPositions()->getSize();

    Int32 normals_size = 0;
    if(geo->getNormals() != NullFC)
        normals_size = geo->getNormals()->getSize();

    Int32 colors_size = 0;
    if(geo->getColors() != NullFC)
        colors_size = geo->getColors()->getSize();
    
    Int32 secondary_colors_size = 0;
    if(geo->getSecondaryColors() != NullFC)
        secondary_colors_size = geo->getSecondaryColors()->getSize();
    
    Int32 texccords_size = 0;
    if(geo->getTexCoords() != NullFC)
        texccords_size = geo->getTexCoords()->getSize();
    
    Int32 texccords1_size = 0;
    if(geo->getTexCoords1() != NullFC)
        texccords1_size = geo->getTexCoords1()->getSize();
    
    Int32 texccords2_size = 0;
    if(geo->getTexCoords2() != NullFC)
        texccords2_size = geo->getTexCoords2()->getSize();
    
    Int32 texccords3_size = 0;
    if(geo->getTexCoords3() != NullFC)
        texccords3_size = geo->getTexCoords3()->getSize();

    UInt32 pos_errors = 0;
    UInt32 norm_errors = 0;
    UInt32 col_errors = 0;
    UInt32 col2_errors = 0;
    UInt32 tex0_errors = 0;
    UInt32 tex1_errors = 0;
    UInt32 tex2_errors = 0;
    UInt32 tex3_errors = 0;

    PrimitiveIterator it;
    for(it = geo->beginPrimitives(); it != geo->endPrimitives(); ++it)
    {
        for(UInt32 v=0; v < it.getLength(); ++v)
        {
            if(it.getPositionIndex(v) >= positions_size)
                ++pos_errors;
            if(it.getNormalIndex(v) >= normals_size)
                ++norm_errors;
            if(it.getColorIndex(v) >= colors_size)
                ++col_errors;
            if(it.getSecondaryColorIndex(v) >= secondary_colors_size)
                ++col2_errors;
            if(it.getTexCoordsIndex(v) >= texccords_size)
                ++tex0_errors;
            if(it.getTexCoordsIndex1(v) >= texccords1_size)
                ++tex1_errors;
            if(it.getTexCoordsIndex2(v) >= texccords2_size)
                ++tex2_errors;
            if(it.getTexCoordsIndex3(v) >= texccords3_size)
                ++tex3_errors;
        }
    }


    if(norm_errors > 0)
    {
        norm_errors = 0;
        printf("removed corrupted normals!\n");
        beginEditCP(geo);
            geo->setNormals(NullFC);
        endEditCP(geo);
    }

    if(col_errors > 0)
    {
        col_errors = 0;
        printf("removed corrupted colors!\n");
        beginEditCP(geo);
            geo->setColors(NullFC);
        endEditCP(geo);
    }

    if(tex0_errors > 0)
    {
        tex0_errors = 0;
        printf("removed corrupted tex coords0!\n");
        beginEditCP(geo);
            geo->setTexCoords(NullFC);
        endEditCP(geo);
    }

    _geo_errors += (pos_errors + norm_errors + col_errors +
                    col2_errors + tex0_errors + tex1_errors +
                    tex2_errors + tex3_errors);
    
    // found some errors.
    if(_geo_errors > errors)
        _corrupted_geos.insert(geo);
    
    // ok we found no errors now check for missing index map.
    bool repair = false;
    if(!verifyIndexMap(geo, repair))
    {
        // wird nur auf der console ausgegeben!
        if(repair)
            fprintf(stderr, "vrNodeUtils::verifyGeometryCB : added missing 
index map!\n");
        else
            fprintf(stderr, "vrNodeUtils::verifyGeometryCB : couldn't add 
missing index map!\n");
    }

    return Action::Continue;
}

/*!
 * \brief
 * \param
 * \return
 */
UInt32 vrNodeUtils::verifyGeometry(NodePtr &node, vector<GeometryPtr> 
&corrupted_geos)
{
    if(node == NullFC)
        return 0;

    corrupted_geos.clear();
    _corrupted_geos.clear();
    
    _geo_errors = 0;
    traverse(node, osgTypedFunctionFunctor1CPtrRef<Action::ResultE, 
NodePtr>(verifyGeometryCB));
    
    if(_geo_errors > 0)
    {
        corrupted_geos.reserve(_corrupted_geos.size());
        for(set<GeometryPtr>::iterator it = _corrupted_geos.begin();
            it != _corrupted_geos.end(); ++it)
        {
            corrupted_geos.push_back(*it);
        }
    }
    
    return _geo_errors;
}

/*!
 * \brief Replaces corrupted geometrie nodes with group nodes.
 * \param root node
 * \return true if something was repaired.
 */
bool vrNodeUtils::repairGeometry(OSG::NodePtr &node)
{
    if(node == NullFC)
        return false;
    
    vector<GeometryPtr> corrupted_geos;
    UInt32 geo_errors = vrNodeUtils::verifyGeometry(node, corrupted_geos);
    if(geo_errors > 0)
    {
        vrLog::error("Found corrupted geometries with %u errors!", geo_errors);
        for(UInt32 i=0;i<corrupted_geos.size();++i)
        {
            // now replace corruped geometry core with a group core.
            for(UInt32 j=0;j<corrupted_geos[i]->getParents().size();++j)
            {
                NodePtr parent = corrupted_geos[i]->getParents()[j];
                if(parent != NullFC)
                {
                    string nname = vrNodeUtils::getName(parent);
                    nname += "_CORRUPTED";
                    vrNodeUtils::setName(parent, nname.c_str());
                    beginEditCP(parent, Node::CoreFieldMask);
                        parent->setCore(Group::create());
                    endEditCP(parent, Node::CoreFieldMask);
                }
            }
        }
        vrLog::error("Removed %u corrupted geometry nodes!", 
corrupted_geos.size());
        return true;
    }
    
    return false;
}

Reply via email to