Hello Michael,

On 11/14/2011 08:59 AM, Michael Raab wrote:
there seem to be some problems inside the geometry functions. Here are the 
first (that I can reproduce easily):

it sounds like you have code to reproduce these problems, any chance you can share it so we don't have to go and reinvent a reproducer?

1.) osg::calcFaceNormals(geo) seems to forget to clear old normals from the 
index mapping, which means the number of indices grows with each call of 
osg::calcFaceNormals (by the number of normals); IndexMapping size grows by 1 
with each calcfaceNormals() call

can you give the attached patch a try?

2.) osg::calcVertexTangents() creates not enough tangents and binormals, e.g. 
for a simple plane only 3 tangents are created...

Ok, I haven't looked at this one yet (so everyone feel free to send a patch... ;) ). Thanks for the bug reports.

        Cheers,
                Carsten
Index: Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp
===================================================================
RCS file: /cvsroot/opensg/OpenSG/Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp,v
retrieving revision 1.75
diff -u -r1.75 OSGGeoFunctions.cpp
--- Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp	12 Oct 2011 08:57:24 -0000	1.75
+++ Source/System/NodeCores/Drawables/Geometry/OSGGeoFunctions.cpp	14 Nov 2011 18:09:08 -0000
@@ -754,8 +754,8 @@
 
 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcFaceNormals(GeometryPtr geo)
 {
-    if(geo->getPositions() == NullFC ||
-       geo->getPositions()->size() == 0)
+    if(geo->getPositions()         == NullFC ||
+       geo->getPositions()->size() == 0        )
     {
         FINFO(("Geo without positions in calcFaceNormals()\n"));
         return;
@@ -765,7 +765,6 @@
     GeoNormalsPtr newNormals = GeoNormals3f::create();
     Vec3f normal;
 
-    FaceIterator faceIter = geo->beginFaces();
     GeoIndicesPtr oldIndex = geo->getIndices();
 
     if(oldIndex != NullFC)
@@ -774,10 +773,32 @@
         if(geo->getMFIndexMapping()->size() > 0)
         {
             //MULTI INDEXED
-            beginEditCP(newIndex);
+            MFUInt16 &oldIndexMap = *geo->editMFIndexMapping();
+            UInt32    oldIMSize   = oldIndexMap.size();
+            UInt32    newIMSize   = oldIndexMap.size();
+            Int16     oldNIdx     =  geo->calcMappingIndex(Geometry::MapNormal);
+            Int16     newNIdx     = -1;
+
+            if(oldNIdx < 0)
+            {
+                // no pre-existing normals, add new index for normals
+                newNIdx   = oldIndexMap.size();
+                newIMSize = oldIMSize + 1;
+            }
+            else if(geo->getIndexMapping(oldNIdx) != Geometry::MapNormal)
+            {
+                // index for normal also indexes other property,
+                // add new index only for normals
+                newNIdx   = oldIndexMap.size();
+                newIMSize = oldIMSize + 1;
+            }
+            else
+            {
+                // normals indexed with unique index, reuse it
+                newNIdx = oldNIdx;
+            }
 
-            MFUInt16    &oldIndexMap = (*geo->editMFIndexMapping());
-            UInt32 oldIMSize = oldIndexMap.size();
+            beginEditCP(newIndex);
             for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i)
             {
                 for(UInt32 k = 0; k < oldIMSize; ++k)
@@ -785,12 +806,18 @@
                     newIndex->push_back(oldIndex->getValue(i * oldIMSize + k));
                 }
 
-                newIndex->push_back(0);                                 //placeholder for normal index
+                if(newIMSize != oldIMSize)
+                {
+                    // placeholder for new normal
+                    newIndex->push_back(0);
+                }
             }
 
+            FaceIterator faceIter = geo->beginFaces();
+            FaceIterator faceEnd  = geo->endFaces  ();
+
             beginEditCP(newNormals);
-            for(UInt32 faceCnt = 0; faceIter != geo->endFaces();
-                            ++faceIter, ++faceCnt)
+            for(UInt32 faceCnt = 0; faceIter != faceEnd; ++faceIter, ++faceCnt)
             {
                 if(faceIter.getLength() == 3)
                 {
@@ -830,22 +857,21 @@
                 {
                 case GL_TRIANGLE_STRIP:
                     base = faceIter.getIndexIndex(2);                   //get last point's position in index field
-                    newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+                    newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
                     break;
                 case GL_TRIANGLE_FAN:
                     base = faceIter.getIndexIndex(2);                   //get last point's position in index field
-                    newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+                    newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
                     break;
                 case GL_QUAD_STRIP:
                     base = faceIter.getIndexIndex(3);                   //get last point's position in index field
-                    newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
+                    newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
                     break;
                 default:
                     for(UInt32 i = 0; i < faceIter.getLength(); ++i)
                     {
                         base = faceIter.getIndexIndex(i);
-                        newIndex->setValue(faceCnt,
-                                                                   base + (base / oldIMSize) + oldIMSize);
+                        newIndex->setValue(faceCnt, (base / oldIMSize) * newIMSize + newNIdx);
                     }
                     break;
                 }
@@ -855,17 +881,22 @@
             endEditCP(newIndex);
 
             beginEditCP(geo);
+            geo->setNormals(newNormals);
+            geo->setIndices(newIndex);
 
-            Int16 ni;
-            ni = geo->calcMappingIndex(Geometry::MapNormal);
-            if(ni != -1)
+            if(oldNIdx < 0)
             {
-                oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal;
+                // no pre-existing normals, add new mapping
+                oldIndexMap.push_back(Geometry::MapNormal);
+            }
+            else if(oldIMSize != newIMSize)
+            {
+                // normal index was used to index other property as well,
+                // unshare them
+                oldIndexMap[oldNIdx] &= ~Geometry::MapNormal;
+                oldIndexMap.push_back(Geometry::MapNormal);   
             }
 
-            oldIndexMap.push_back(Geometry::MapNormal);
-            geo->setNormals(newNormals);
-            geo->setIndices(newIndex);
             endEditCP(geo);
             return;
         }
@@ -874,7 +905,11 @@
     //SINGLE INDEXED or NON INDEXED
     //UInt32 pointCnt = 0;
     newNormals->resize(geo->getPositions()->getSize());
-    for(; faceIter != geo->endFaces(); ++faceIter)
+
+    FaceIterator faceIter = geo->beginFaces();
+    FaceIterator faceEnd  = geo->endFaces  ();
+
+    for(; faceIter != faceEnd; ++faceIter)
     {
         if(faceIter.getLength() == 3)
         {
------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to