00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include <set>
00043
00044 #include "OSGConfig.h"
00045
00046 #include <OSGLog.h>
00047
00048 #include <OSGGLU.h>
00049
00050 #include "OSGGeometry.h"
00051 #include "OSGGeoPropPtrs.h"
00052 #include "OSGTriangleIterator.h"
00053 #include "OSGGeoFunctions.h"
00054 #include "OSGFaceIterator.h"
00055
00056
00057 #include "OSGHalfEdgeGraph.h"
00058
00059 OSG_USING_NAMESPACE
00060
00061 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00062 #pragma warning(disable : 383)
00063 #endif
00064 #ifdef __sgi
00065 #pragma set woff 1209
00066 #endif
00067
00068
00069
00070
00071
00078 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcVertexNormals(GeometryPtr geo)
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 {
00211 GeoNormalsPtr norms;
00212 typedef std::set<UInt32> IndexSet;
00213 IndexSet used_indices;
00214
00215 if(geo->getNormals() == NullFC)
00216 {
00217 norms = GeoNormals3f::create();
00218 }
00219 else
00220 {
00221 norms = geo->getNormals();
00222 }
00223 beginEditCP(norms);
00224
00225 norms->resize(geo->getPositions()->getSize());
00226
00227
00228
00229 if(norms->getParents().size() > 1)
00230 {
00231 for(TriangleIterator t = geo->beginTriangles(); t != geo->endTriangles();
00232 ++t)
00233 {
00234 used_indices.insert(t.getPositionIndex(0));
00235 used_indices.insert(t.getPositionIndex(1));
00236 used_indices.insert(t.getPositionIndex(2));
00237 }
00238
00239 for (IndexSet::iterator i = used_indices.begin();
00240 i != used_indices.end();
00241 ++i)
00242 {
00243 norms->setValue(Vec3f(0, 0, 0), *i);
00244 }
00245 }
00246 else
00247 {
00248 for(unsigned i = 0; i < geo->getPositions()->getSize(); i++)
00249 {
00250 norms->setValue(Vec3f(0, 0, 0), i);
00251 }
00252 }
00253
00254 for(TriangleIterator t = geo->beginTriangles(); t != geo->endTriangles();
00255 ++t)
00256 {
00257 Pnt3f p0 = t.getPosition(0);
00258 Pnt3f p1 = t.getPosition(1);
00259 Pnt3f p2 = t.getPosition(2);
00260 Plane p(p0, p1, p2);
00261
00262 Int32 i0 = t.getPositionIndex(0);
00263 Int32 i1 = t.getPositionIndex(1);
00264 Int32 i2 = t.getPositionIndex(2);
00265 norms->setValue( norms->getValue(i0) + p.getNormal(), i0 );
00266 norms->setValue( norms->getValue(i1) + p.getNormal(), i1 );
00267 norms->setValue( norms->getValue(i2) + p.getNormal(), i2 );
00268 }
00269 if(norms->getParents().size() > 1)
00270 {
00271 std::set < UInt32 >::iterator i = used_indices.begin();
00272 std::set < UInt32 >::iterator end = used_indices.end();
00273
00274 while(i != end)
00275 {
00276 Vec3f n = norms->getValue(*i);
00277 n.normalize();
00278 norms->setValue(n, *i);
00279
00280 ++i;
00281 }
00282 }
00283 else
00284 {
00285 for(unsigned i = 0; i < geo->getPositions()->getSize(); i++)
00286 {
00287 Vec3f n = norms->getValue(i);
00288 n.normalize();
00289 norms->setValue(n, i);
00290 }
00291 }
00292 endEditCP(norms);
00293
00294 beginEditCP(geo);
00295 {
00296 geo->setNormals(norms);
00297
00298 MFUInt16 &im = geo->getIndexMapping();
00299 if(im.size() > 0)
00300 {
00301 Int16 pi, ni;
00302 pi = geo->calcMappingIndex(Geometry::MapPosition);
00303 ni = geo->calcMappingIndex(Geometry::MapNormal);
00304
00305 if(ni >= 0)
00306 {
00307 im[ni] = im[ni] &~Geometry::MapNormal;
00308 }
00309 if(pi >= 0)
00310 {
00311 im[pi] = im[pi] | Geometry::MapNormal;
00312 }
00313 }
00314 }
00315 endEditCP(geo);
00316 }
00317 #ifdef __sgi
00318 #pragma reset woff 1209
00319 #endif
00320
00321 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00322
00325 template<class type>
00326 struct vecless
00327 {
00328 bool operator () (const type &a, const type &b) const
00329 {
00330 UInt32 i;
00331 bool ret = false;
00332
00333 for(i = 0; i < type::_iSize; i++)
00334 {
00335 if(osgabs(a[i] - b[i]) < Eps)
00336 continue;
00337
00338 if(a[i] > b[i])
00339 {
00340 ret = false;
00341 break;
00342 }
00343 ret = true;
00344 break;
00345 }
00346 return ret;
00347 }
00348 };
00349
00353 template<class type>
00354 struct memless
00355 {
00356 bool operator () (const type &a, const type &b) const
00357 {
00358 if(a.second && b.second)
00359 {
00360 if(a.second == b.second)
00361 {
00362 return (memcmp(a.first, b.first, a.second) < 0) ? true : false;
00363 }
00364 else
00365 {
00366 FFATAL(("a.memSize != b.memSize in memless::operator()\n"));
00367 }
00368 }
00369 else
00370 {
00371 FFATAL(("memSize is NULL in memless::operator()\n"));
00372 }
00373 return false;
00374 }
00375 };
00376 #endif // remove from all but dev docs
00377
00378
00385 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcVertexNormals(GeometryPtr geo,
00386 Real32 creaseAngle)
00387 {
00388 GeoNormalsPtr norms;
00389 GeoPositionsPtr positions;
00390
00391 if(creaseAngle >= Pi)
00392 {
00393 calcVertexNormals(geo);
00394 return;
00395 }
00396
00397
00398 if(geo->getPositions() == NullFC)
00399 {
00400 FINFO(("Geo without positions in calcVertexNormals()\n"));
00401 return;
00402 }
00403 else
00404 {
00405 positions = geo->getPositions();
00406 }
00407
00408 if(positions->size() < 3)
00409 {
00410 FINFO(("Geo with less than 3 positions in calcVertexNormals()\n"));
00411 return;
00412 }
00413
00414
00415 if(geo->getNormals() == NullFC)
00416 {
00417 norms = GeoNormals3f::create();
00418 }
00419 else
00420 {
00421 norms = geo->getNormals();
00422 }
00423
00424
00425 beginEditCP(geo);
00426 {
00427 geo->setNormals(norms);
00428 }
00429
00430 endEditCP(geo);
00431
00432
00433 MFUInt16 &im = geo->getIndexMapping();
00434 Int16 ni = geo->calcMappingIndex(Geometry::MapNormal);
00435 GeoIndicesPtr ip = geo->getIndices();
00436
00437
00438 if(ip == NullFC || ip->size() == 0)
00439 {
00440 FINFO(("Geo without indices in calcVertexNormals()\n"));
00441 return;
00442 }
00443
00444 UInt32 nind = ip->size() / (im.size() ? im.size() : 1);
00445 int imsize = 0;
00446 if(ni < 0 || im[ni] != Geometry::MapNormal)
00447 {
00448
00449 if(ni >= 0)
00450 {
00451 im[ni] = im[ni] &~Geometry::MapNormal;
00452 }
00453
00454
00455 if(im.size() == 0)
00456 {
00457 UInt32 map = Geometry::MapPosition;
00458
00459 if(geo->getTexCoords() != NullFC)
00460 map |= Geometry::MapTexCoords;
00461
00462 if(geo->getColors() != NullFC)
00463 map |= Geometry::MapColor;
00464
00465 im.push_back(map);
00466 }
00467
00468 ni = im.size();
00469 im.push_back(Geometry::MapNormal);
00470
00471
00472 imsize = im.size();
00473
00474 beginEditCP(ip);
00475 ip->resize(nind * imsize);
00476
00477 for(UInt32 i = nind - 1; i > 0; --i)
00478 {
00479 for(Int16 j = imsize - 2; j >= 0; --j)
00480 {
00481 UInt32 val;
00482 ip->getValue(val, i * (imsize - 1) + j);
00483 ip->setValue(val, i * imsize + j);
00484 }
00485
00486 ip->setValue(i, i * imsize + imsize - 1);
00487 }
00488
00489 ip->setValue(0, imsize - 1);
00490 endEditCP(ip);
00491 }
00492 else
00493 {
00494 imsize = im.size();
00495 beginEditCP(ip);
00496 for(UInt32 i = 0; i < nind; ++i)
00497 {
00498 ip->setValue(i, i * imsize + ni);
00499 }
00500
00501 endEditCP(ip);
00502 }
00503
00504
00505
00506 if(creaseAngle == 0)
00507 {
00508 beginEditCP(norms);
00509 beginEditCP(ip);
00510
00511 norms->resize(nind);
00512
00513 for(TriangleIterator ti = geo->beginTriangles();
00514 ti != geo->endTriangles(); ++ti)
00515 {
00516 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0);
00517 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0);
00518 d1.crossThis(d2);
00519
00520 d1.normalize();
00521
00522 norms->setValue(d1, ti.getNormalIndex(0));
00523 norms->setValue(d1, ti.getNormalIndex(1));
00524 norms->setValue(d1, ti.getNormalIndex(2));
00525 }
00526
00527 endEditCP(norms);
00528 endEditCP(ip);
00529 return;
00530 }
00531
00532
00533 #if 0
00534
00535
00536
00537 std::vector < Vec3f > faceNormals;
00538 std::multimap<Pnt3f, UInt32, vecless<Pnt3f> > pntMap;
00539
00540 TriangleIterator ti;
00541
00542 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti)
00543 {
00544 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0);
00545 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0);
00546 d1.crossThis(d2);
00547
00548 d1.normalize();
00549 faceNormals.push_back(d1);
00550
00551 pntMap.insert(std::pair< Pnt3f, UInt32 >
00552 (ti.getPosition(0), faceNormals.size() - 1));
00553 pntMap.insert(std::pair< Pnt3f, UInt32 >
00554 (ti.getPosition(1), faceNormals.size() - 1));
00555 pntMap.insert(std::pair< Pnt3f, UInt32 >
00556 (ti.getPosition(2), faceNormals.size() - 1));
00557 }
00558
00559
00560 beginEditCP(norms);
00561 beginEditCP(ip);
00562
00563 norms->resize(nind);
00564
00565 Real32 cosCrease = osgcos(creaseAngle);
00566
00567 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti)
00568 {
00569 Int32 tind = ti.getIndex();
00570 Vec3f mynorm = faceNormals[tind];
00571
00572 std::multimap<Pnt3f, UInt32, vecless<Pnt3f> >::iterator st, en;
00573
00574 for(UInt16 i = 0; i < 3; ++i)
00575 {
00576
00577
00578
00579
00580 std::set<Vec3f, vecless<Vec3f> > normset;
00581
00582 st = pntMap.lower_bound(ti.getPosition(i));
00583 en = pntMap.upper_bound(ti.getPosition(i));
00584
00585 for(; st != en; st++)
00586 {
00587 if(mynorm.dot(faceNormals[(*st).second]) > cosCrease)
00588 {
00589 normset.insert(faceNormals[(*st).second]);
00590 }
00591 }
00592
00593 Vec3f norm(0, 0, 0);
00594 typedef std::set<Vec3f, vecless<Vec3f> >::iterator NormSetIt;
00595
00596 for(NormSetIt it = normset.begin(); it != normset.end(); ++it)
00597 {
00598 norm += (*it);
00599 }
00600
00601 norm.normalize();
00602 norms->setValue(norm, ti.getNormalIndex(i));
00603 }
00604 }
00605
00606 endEditCP(ip);
00607 endEditCP(norms);
00608
00609 #else
00610
00611
00612
00613
00614 std::vector < Vec3f > faceNormals;
00615 std::vector < std::vector < UInt32 > > pntFaceDic;
00616
00617 TriangleIterator ti;
00618 UInt32 i, pN = positions->size();
00619
00620 pntFaceDic.resize(pN);
00621 for(ti = geo->beginTriangles(), i = 0; ti != geo->endTriangles(); ++ti, ++i)
00622 {
00623 Int32 v0 = ti.getPositionIndex(0);
00624 Int32 v1 = ti.getPositionIndex(1);
00625 Int32 v2 = ti.getPositionIndex(2);
00626
00627 if(v0 != v1 && v0 != v2)
00628 {
00629 Vec3f d1 = ti.getPosition(1) - ti.getPosition(0);
00630 Vec3f d2 = ti.getPosition(2) - ti.getPosition(0);
00631 d1.crossThis(d2);
00632
00633 if(d1.squareLength() >= 0)
00634 {
00635 d1.normalize();
00636 faceNormals.push_back(d1);
00637
00638 pntFaceDic[ti.getPositionIndex(0)].push_back(i);
00639 pntFaceDic[ti.getPositionIndex(1)].push_back(i);
00640 pntFaceDic[ti.getPositionIndex(2)].push_back(i);
00641 }
00642 else
00643 {
00644 faceNormals.push_back(Vec3f(0, 0, 0));
00645 }
00646 }
00647 else
00648 {
00649 faceNormals.push_back(Vec3f(0, 0, 0));
00650 }
00651 }
00652
00653
00654 beginEditCP(norms);
00655 beginEditCP(ip);
00656
00657 norms->clear();
00658
00659 Real32 cosCrease = osgcos(creaseAngle);
00660 Vec3f norm;
00661 std::vector < UInt32 > normset;
00662 std::vector < std::map < std::vector < UInt32 > , UInt32 > > normDic;
00663 std::map < std::vector < UInt32 > , UInt32 >::iterator ndI;
00664
00665 UInt32 normalIndex = 0;
00666
00667 normDic.resize(pN);
00668
00669 for(ti = geo->beginTriangles(); ti != geo->endTriangles(); ++ti)
00670 {
00671 Int32 tind = ti.getIndex();
00672 Vec3f faceNorm(faceNormals[tind]);
00673
00674 if(faceNorm.squareLength() != 0.0)
00675 {
00676 for(UInt16 i = 0; i < 3; ++i)
00677 {
00678
00679
00680
00681
00682 UInt32 p = ti.getPositionIndex(i);
00683 UInt32 pf, f, fN = pntFaceDic[p].size();
00684 UInt32 n, nN;
00685
00686 normset.clear();
00687 for(f = 0; f < fN; f++)
00688 {
00689 if(((pf = pntFaceDic[p][f]) == tind) ||
00690 (faceNorm.dot(faceNormals[pf]) > cosCrease))
00691 normset.push_back(pf);
00692 }
00693
00694 if((nN = normset.size()))
00695 {
00696
00697
00698 ndI = normDic[p].find(normset);
00699 if(ndI == normDic[p].end())
00700 {
00701 norm = faceNormals[normset[0]];
00702 for(n = 1; n < nN; ++n)
00703 norm += faceNormals[normset[n]];
00704 norm.normalize();
00705 normalIndex = norms->size();
00706 norms->push_back(norm);
00707 normDic[p][normset] = normalIndex;
00708 }
00709 else
00710 {
00711 normalIndex = ndI->second;
00712 }
00713 }
00714 else
00715 {
00716
00717 FWARNING(("Empty normset for %d faces pos %d: %f/%f/%f\n",
00718 fN, i, ti.getPosition(i).x(),
00719 ti.getPosition(i).y(), ti.getPosition(i).z()
00720 ));
00721 }
00722
00723 ip->setValue(normalIndex, ti.getIndexIndex(i) + ni);
00724 }
00725 }
00726 else
00727 {
00728
00729
00730 normalIndex = norms->size();
00731 norms->push_back(norm);
00732
00733 ip->setValue ( normalIndex, ti.getIndexIndex(0) + ni );
00734 ip->setValue ( normalIndex, ti.getIndexIndex(1) + ni );
00735 ip->setValue ( normalIndex, ti.getIndexIndex(2) + ni );
00736 }
00737 }
00738
00739 endEditCP(ip);
00740 endEditCP(norms);
00741 #endif
00742 }
00743
00744 #ifdef __sgi
00745 #pragma set woff 1209
00746 #endif
00747
00754 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcFaceNormals(GeometryPtr geo)
00755 {
00756 GeoIndicesPtr newIndex = GeoIndicesUI32::create();
00757 GeoNormalsPtr newNormals = GeoNormals3f::create();
00758 Vec3f normal;
00759
00760 FaceIterator faceIter = geo->beginFaces();
00761 GeoIndicesPtr oldIndex = geo->getIndices();
00762
00763 if(oldIndex != NullFC)
00764 {
00765
00766 if(geo->getIndexMapping().size() > 0)
00767 {
00768
00769 beginEditCP(newIndex);
00770
00771 MFUInt16 &oldIndexMap = geo->getIndexMapping();
00772 UInt32 oldIMSize = oldIndexMap.size();
00773 for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i)
00774 {
00775 for(UInt32 k = 0; k < oldIMSize; ++k)
00776 {
00777 newIndex->push_back(oldIndex->getValue(i * oldIMSize + k));
00778 }
00779
00780 newIndex->push_back(0);
00781 }
00782
00783 beginEditCP(newNormals);
00784 for(UInt32 faceCnt = 0; faceIter != geo->endFaces();
00785 ++faceIter, ++faceCnt)
00786 {
00787 if(faceIter.getLength() == 3)
00788 {
00789
00790 normal =
00791 (
00792 faceIter.getPosition(1) -
00793 faceIter.getPosition(0)
00794 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00795 normal.normalize();
00796 }
00797 else
00798 {
00799
00800 normal =
00801 (
00802 faceIter.getPosition(1) -
00803 faceIter.getPosition(0)
00804 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00805 if(normal.length() == 0)
00806 {
00807
00808 normal =
00809 (
00810 faceIter.getPosition(1) -
00811 faceIter.getPosition(2)
00812 ).cross(faceIter.getPosition(3) -
00813 faceIter.getPosition(2));
00814 }
00815
00816 normal.normalize();
00817 }
00818
00819 newNormals->push_back(normal);
00820 UInt32 base;
00821 switch(faceIter.getType())
00822 {
00823 case GL_TRIANGLE_STRIP:
00824 base = faceIter.getIndexIndex(2);
00825 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00826 break;
00827 case GL_TRIANGLE_FAN:
00828 base = faceIter.getIndexIndex(2);
00829 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00830 break;
00831 case GL_QUAD_STRIP:
00832 base = faceIter.getIndexIndex(3);
00833 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00834 break;
00835 default:
00836 for(UInt32 i = 0; i < faceIter.getLength(); ++i)
00837 {
00838 base = faceIter.getIndexIndex(i);
00839 newIndex->setValue(faceCnt,
00840 base + (base / oldIMSize) + oldIMSize);
00841 }
00842 break;
00843 }
00844 }
00845
00846 endEditCP(newNormals);
00847 endEditCP(newIndex);
00848
00849 beginEditCP(geo);
00850
00851 Int16 ni;
00852 ni = geo->calcMappingIndex(Geometry::MapNormal);
00853 if(ni != -1)
00854 {
00855 oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal;
00856 }
00857
00858 oldIndexMap.push_back(Geometry::MapNormal);
00859 geo->setNormals(newNormals);
00860 geo->setIndices(newIndex);
00861 endEditCP(geo);
00862 return;
00863 }
00864 }
00865
00866
00867
00868 newNormals->resize(geo->getPositions()->getSize());
00869 for(; faceIter != geo->endFaces(); ++faceIter)
00870 {
00871 if(faceIter.getLength() == 3)
00872 {
00873
00874 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00875 normal.normalize();
00876 }
00877 else
00878 {
00879
00880 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00881 if(normal.length() == 0)
00882 {
00883
00884 normal =
00885 (
00886 faceIter.getPosition(1) -
00887 faceIter.getPosition(2)
00888 ).cross(faceIter.getPosition(3) - faceIter.getPosition(2));
00889 }
00890
00891 normal.normalize();
00892 }
00893
00894 switch(faceIter.getType())
00895 {
00896 case GL_TRIANGLE_STRIP:
00897 newNormals->setValue(normal, faceIter.getPositionIndex(2));
00898 break;
00899 case GL_TRIANGLE_FAN:
00900 newNormals->setValue(normal, faceIter.getPositionIndex(2));
00901 break;
00902 case GL_QUAD_STRIP:
00903 newNormals->setValue(normal, faceIter.getPositionIndex(3));
00904 break;
00905 default:
00906 for(UInt32 i = 0; i < faceIter.getLength(); ++i)
00907 {
00908 newNormals->setValue(normal, faceIter.getPositionIndex(i));
00909 }
00910 break;
00911 }
00912
00913 beginEditCP(geo);
00914 geo->setNormals(newNormals);
00915 endEditCP(geo);
00916 }
00917 }
00918
00935 OSG_SYSTEMLIB_DLLMAPPING
00936 Int32 OSG::setIndexFromVRMLData(GeometryPtr geoPtr,
00937 std::vector<Int32> &coordIndex,
00938 std::vector<Int32> &normalIndex,
00939 std::vector<Int32> &colorIndex,
00940 std::vector<Int32> &texCoordIndex,
00941 bool convex,
00942 bool ccw,
00943 bool normalPerVertex,
00944 bool colorPerVertex,
00945 bool createNormal,
00946 bool faceSet)
00947 {
00948 Int32 primitiveType = faceSet ? GL_POLYGON : GL_LINE;
00949
00950 return setIndexFromIndexedX3DData ( geoPtr,
00951 coordIndex,
00952 normalIndex,
00953 colorIndex,
00954 texCoordIndex,
00955 primitiveType,
00956 convex,
00957 ccw,
00958 normalPerVertex,
00959 colorPerVertex,
00960 createNormal );
00961 }
00962
00981 OSG_SYSTEMLIB_DLLMAPPING
00982 Int32 OSG::setIndexFromIndexedX3DData ( GeometryPtr geoPtr,
00983 std::vector<Int32> &coordIndex,
00984 std::vector<Int32> &normalIndex,
00985 std::vector<Int32> &colorIndex,
00986 std::vector<Int32> &texCoordIndex,
00987 Int32 primitiveType,
00988 bool OSG_CHECK_ARG(convex),
00989 bool ccw,
00990 bool normalPerVertex,
00991 bool colorPerVertex,
00992 bool OSG_CHECK_ARG(createNormal) )
00993 {
00995 typedef std::vector<Int32> *IndexBagP;
00996
00998 enum IndexType
00999 {
01000 UNKNOWN_IT = 0,
01001 EMPTY_IT,
01002 VERTEX_COORD_IT,
01003 VERTEX_IT,
01004 VERTEX_DUP_IT,
01005 VERTEX_CREATE_IT,
01006 PRIMITIVE_IT,
01007 PRIMITIVE_INDEX_IT,
01008 PRIMITIVE_CREATE_IT
01009 };
01010
01012 static const char *indexTypeStr[] =
01013 {
01014 "UNKNOWN_IT",
01015 "EMPTY_IT",
01016 "VERTEX_COORD_IT",
01017 "VERTEX_IT",
01018 "VERTEX_DUP_IT",
01019 "VERTEX_CREATE_IT",
01020 "PRIMTIVE_IT",
01021 "PRIMITIVE_INDEX_IT",
01022 "PRIMITIVE_CREATE_IT"
01023 };
01024 OSG::GeoPositionsPtr posPtr;
01025 OSG::GeoNormalsPtr normalPtr;
01026 OSG::GeoColorsPtr colorPtr;
01027 OSG::GeoTexCoordsPtr texCoordsPtr;
01028 OSG::GeoPLengthsPtr lensPtr;
01029 OSG::GeoPTypesPtr geoTypePtr;
01030 OSG::GeoIndicesPtr indexPtr;
01031
01032
01033 Int32 index, i, pi, typei, mapi, primitiveN = 0, vN = 0;
01034 Int32 pType = 0, localPType;
01035 Int32 maxPType;
01036 Int32 minPType;
01037 Int32 beginIndex, endIndex, step, len, sysPType = 0;
01038 Int32 piN = 0, ciN = 0, niN = 0, tiN = 0;
01039 Int32 pN = 0, nN = 0, cN = 0, tN = 0, tN1 = 0, tN2 = 0, tN3 = 0;
01040 IndexType indexType[4];
01041 IndexType &coordIT = indexType[0];
01042 IndexType &normalIT = indexType[1];
01043 IndexType &colorIT = indexType[2];
01044 IndexType &textureIT = indexType[3];
01045 Int32 primitiveTypeCount[6];
01046 UInt32 triCount = 0;
01047 Int16 indexMap[4], indexMapID[4];
01048 UInt32 uiNumTextures = 0;
01049
01050 IndexBagP indexBag[4] =
01051 {
01052 &coordIndex,
01053 &normalIndex,
01054 &colorIndex,
01055 &texCoordIndex
01056 };
01057
01058
01059
01060 coordIT = VERTEX_IT;
01061 indexMap[0] = Geometry::MapPosition;
01062
01063
01064
01065 switch (primitiveType) {
01066 case GL_POINTS:
01067 minPType = 1;
01068 maxPType = 1;
01069 break;
01070 case GL_LINES:
01071 minPType = 2;
01072 maxPType = 3;
01073 break;
01074 case GL_LINE_STRIP:
01075 minPType = 2;
01076 maxPType = 3;
01077 break;
01078 case GL_LINE_LOOP:
01079 minPType = 2;
01080 maxPType = 3;
01081 break;
01082 case GL_TRIANGLES:
01083 minPType = 3;
01084 maxPType = 3;
01085 break;
01086 case GL_TRIANGLE_STRIP:
01087 minPType = 3;
01088 maxPType = 3;
01089 break;
01090 case GL_TRIANGLE_FAN:
01091 minPType = 3;
01092 maxPType = 3;
01093 break;
01094 case GL_QUADS:
01095 minPType = 3;
01096 maxPType = 4;
01097 break;
01098 case GL_QUAD_STRIP:
01099 minPType = 3;
01100 maxPType = 4;
01101 break;
01102 case GL_POLYGON:
01103 minPType = 3;
01104 maxPType = 5;
01105 break;
01106 default:
01107 FFATAL (( "Can not fill index; Invalid primitiveType: %d\n",
01108 primitiveType ));
01109 break;
01110 }
01111
01112
01113
01114
01115 posPtr = geoPtr->getPositions();
01116 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize());
01117
01118 normalPtr = geoPtr->getNormals();
01119 nN = ((normalPtr == OSG::NullFC) ? 0 : normalPtr->getSize());
01120
01121 colorPtr = geoPtr->getColors();
01122 cN = ((colorPtr == OSG::NullFC) ? 0 : colorPtr->getSize());
01123
01124 texCoordsPtr = geoPtr->getTexCoords();
01125 tN = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01126
01127 texCoordsPtr = geoPtr->getTexCoords1();
01128 tN1 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01129
01130 texCoordsPtr = geoPtr->getTexCoords2();
01131 tN2 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01132
01133 texCoordsPtr = geoPtr->getTexCoords3();
01134 tN3 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01135
01136 FDEBUG(("vertex attrib count P/N/C/T: %d/%d/%d/%d\n", pN, nN, cN, tN));
01137
01138
01139
01140 primitiveN = index = 0;
01141 for(pType = 0; pType < 6; pType++)
01142 primitiveTypeCount[pType] = 0;
01143
01144 if(!pN)
01145 {
01146 FINFO(("No points in OSG::setIndexFromVRMLData()\n"));
01147 return 0;
01148 }
01149 else
01150 {
01151 piN = coordIndex.size();
01152 if(piN)
01153 {
01154 for(i = 0; i <= piN; i++)
01155 {
01156 index = (i == piN) ? -1 : coordIndex[i];
01157 if((index < 0) && vN)
01158 {
01159 primitiveTypeCount[(vN > maxPType) ? maxPType : vN]++;
01160 primitiveN++;
01161 vN = 0;
01162 }
01163 else
01164 {
01165 if(index >= pN && i != piN)
01166 {
01167 FWARNING(("Point index (%d/%d) out of range", index, pN));
01168 coordIndex[i] = 0;
01169 }
01170
01171 vN++;
01172 }
01173 }
01174 }
01175 else
01176 {
01177 FWARNING(("No coordIndex in OSG::setIndexFromVRMLData()\n"));
01178 return 0;
01179 }
01180 }
01181
01182
01183
01184 normalIT = UNKNOWN_IT;
01185 niN = normalIndex.size();
01186 if(nN)
01187 {
01188 if(normalPerVertex)
01189 {
01190
01191 if(niN >= piN)
01192 {
01193
01194 for(i = 0; i < piN; i++)
01195 {
01196 if(normalIndex[i] != coordIndex[i])
01197 {
01198 normalIT = VERTEX_IT;
01199 break;
01200 }
01201 }
01202
01203 if(normalIT == UNKNOWN_IT)
01204 {
01205
01206 normalIT = VERTEX_DUP_IT;
01207 }
01208 }
01209 else
01210 {
01211
01212 normalIT = VERTEX_COORD_IT;
01213 if(niN)
01214 {
01215 FWARNING(("Not enough normal index (%d,%d)\n", normalIndex.
01216 size(), piN));
01217 normalIndex.clear();
01218 }
01219 }
01220 }
01221 else
01222 {
01223
01224 if(niN >= primitiveN)
01225 {
01226
01227 normalIT = PRIMITIVE_INDEX_IT;
01228 }
01229 else
01230 {
01231 if(nN >= primitiveN)
01232 {
01233
01234 normalIT = PRIMITIVE_IT;
01235 }
01236 else
01237 {
01238 FINFO(("not enough normal index (%d,%d)\n", nN, primitiveN));
01239 }
01240 }
01241 }
01242 }
01243 else
01244 {
01245
01246
01247
01248
01249
01250
01251
01252
01253 normalIT = EMPTY_IT;
01254 }
01255
01256
01257
01258 colorIT = UNKNOWN_IT;
01259 ciN = colorIndex.size();
01260 if(cN)
01261 {
01262 if(colorPerVertex)
01263 {
01264
01265 if(ciN >= piN)
01266 {
01267
01268 for(i = 0; i < piN; i++)
01269 {
01270 if(colorIndex[i] != coordIndex[i])
01271 {
01272 colorIT = VERTEX_IT;
01273 break;
01274 }
01275 }
01276
01277 if(colorIT == UNKNOWN_IT)
01278 {
01279
01280 colorIT = VERTEX_DUP_IT;
01281 }
01282 }
01283 else
01284 {
01285
01286 colorIT = VERTEX_COORD_IT;
01287 if(ciN)
01288 {
01289 FWARNING(("Not enough color index (%d,%d)\n", colorIndex.
01290 size(), piN));
01291 colorIndex.clear();
01292 }
01293 }
01294 }
01295 else
01296 {
01297
01298 if(ciN >= primitiveN)
01299 {
01300
01301 colorIT = PRIMITIVE_INDEX_IT;
01302 }
01303 else
01304 {
01305 if(cN >= primitiveN)
01306 {
01307
01308 colorIT = PRIMITIVE_IT;
01309 }
01310 else
01311 {
01312 FINFO(("not enough color index (%d,%d)\n", cN, primitiveN));
01313 }
01314 }
01315 }
01316 }
01317 else
01318 {
01319 colorIT = EMPTY_IT;
01320 }
01321
01322
01323
01324 textureIT = UNKNOWN_IT;
01325 tiN = texCoordIndex.size();
01326 if(tN)
01327 {
01328 if(tiN >= piN)
01329 {
01330
01331 for(i = 0; i < piN; i++)
01332 {
01333 if(texCoordIndex[i] != coordIndex[i])
01334 {
01335 textureIT = VERTEX_IT;
01336 break;
01337 }
01338 }
01339
01340 if(textureIT == UNKNOWN_IT)
01341 {
01342
01343 textureIT = VERTEX_DUP_IT;
01344 }
01345 }
01346 else
01347 {
01348
01349 textureIT = VERTEX_COORD_IT;
01350 if(ciN)
01351 {
01352 FWARNING(("Not enough texCoord index (%d,%d)\n", texCoordIndex.
01353 size(), piN));
01354 texCoordIndex.clear();
01355 }
01356 }
01357 }
01358 else
01359 {
01360 textureIT = EMPTY_IT;
01361 }
01362
01363 FNOTICE (( "primitiveN: %d, %d, 0/%d 1/%d 2/%d 3/%d 4/%d 5/%d\n",
01364 primitiveType,
01365 primitiveN, primitiveTypeCount[0],
01366 primitiveTypeCount[1], primitiveTypeCount[2],
01367 primitiveTypeCount[3], primitiveTypeCount[4],
01368 primitiveTypeCount[5]));
01369
01370 FNOTICE (( "IndexType: coord: %s, color: %s, normal: %s, texture: %s \n",
01371 indexTypeStr[coordIT], indexTypeStr[colorIT],
01372 indexTypeStr[normalIT], indexTypeStr[textureIT]));
01373
01374
01375
01376 indexPtr = geoPtr->getIndices();
01377 if(indexPtr == OSG::NullFC)
01378 {
01379 indexPtr = OSG::GeoIndicesUI32::create();
01380 }
01381 else
01382 {
01383 OSG::beginEditCP(indexPtr);
01384 indexPtr->clear();
01385 OSG::endEditCP(indexPtr);
01386 }
01387
01388 lensPtr = geoPtr->getLengths();
01389 if(lensPtr == OSG::NullFC)
01390 {
01391 lensPtr = OSG::GeoPLengthsUI32::create();
01392 }
01393 else
01394 {
01395 OSG::beginEditCP(lensPtr);
01396 lensPtr->clear();
01397 OSG::endEditCP(lensPtr);
01398 }
01399
01400 geoTypePtr = geoPtr->getTypes();
01401 if(geoTypePtr == OSG::NullFC)
01402 {
01403 geoTypePtr = OSG::GeoPTypesUI8::create();
01404 }
01405 else
01406 {
01407 OSG::beginEditCP(geoTypePtr);
01408 geoTypePtr->clear();
01409 OSG::endEditCP(geoTypePtr);
01410 }
01411
01412
01413
01414 indexMapID[0] = Geometry::MapPosition;
01415 indexMapID[1] = Geometry::MapNormal;
01416 indexMapID[2] = Geometry::MapColor;
01417 indexMapID[3] = Geometry::MapTexCoords;
01418
01419 for(mapi = i = 1; i <= 3; i++)
01420 {
01421 indexMap[i] = 0;
01422 switch(indexType[i])
01423 {
01424 case UNKNOWN_IT:
01425 case EMPTY_IT:
01426 break;
01427 case VERTEX_COORD_IT:
01428 case VERTEX_DUP_IT:
01429
01430 indexMap[0] |= indexMapID[i];
01431 break;
01432 case VERTEX_IT:
01433 case PRIMITIVE_IT:
01434 case PRIMITIVE_INDEX_IT:
01435
01436 indexMap[mapi++] = indexMapID[i];
01437 break;
01438 default:
01439 break;
01440 }
01441 }
01442
01443
01444
01445 OSG::beginEditCP(geoPtr);
01446 {
01447 geoPtr->setLengths(lensPtr);
01448 geoPtr->setTypes(geoTypePtr);
01449 geoPtr->setIndices(indexPtr);
01450 geoPtr->getIndexMapping().clear();
01451
01452
01453
01454 for(i = 0; ((i <= 3) && indexMap[i]); i++)
01455 {
01456 if(i == 0)
01457 {
01458 if(indexMap[i] & Geometry::MapTexCoords)
01459 {
01460 ++uiNumTextures;
01461
01462 if(tN1 != 0)
01463 {
01464 indexMap[i] |= Geometry::MapTexCoords1;
01465 }
01466
01467 if(tN2 != 0)
01468 {
01469 indexMap[i] |= Geometry::MapTexCoords2;
01470 }
01471
01472 if(tN3 != 0)
01473 {
01474 indexMap[i] |= Geometry::MapTexCoords3;
01475 }
01476 }
01477
01478 geoPtr->getIndexMapping().push_back(indexMap[i]);
01479 }
01480 else
01481 {
01482 geoPtr->getIndexMapping().push_back(indexMap[i]);
01483
01484 if(indexMap[i] & Geometry::MapTexCoords)
01485 {
01486 ++uiNumTextures;
01487
01488 if(tN1 != 0)
01489 {
01490 geoPtr->getIndexMapping().push_back(
01491 Geometry::MapTexCoords1);
01492
01493 ++uiNumTextures;
01494 }
01495
01496 if(tN2 != 0)
01497 {
01498 geoPtr->getIndexMapping().push_back(
01499 Geometry::MapTexCoords2);
01500
01501 ++uiNumTextures;
01502 }
01503
01504 if(tN3 != 0)
01505 {
01506 geoPtr->getIndexMapping().push_back(
01507 Geometry::MapTexCoords3);
01508
01509 ++uiNumTextures;
01510 }
01511 }
01512 }
01513 }
01514 }
01515 OSG::endEditCP(geoPtr);
01516
01517
01518
01519 OSG::beginEditCP(indexPtr);
01520 for(pType = minPType; pType <= maxPType; pType++)
01521 {
01522
01523 if(primitiveTypeCount[pType])
01524 {
01525
01526
01527 if(pType < maxPType)
01528 {
01529 len = primitiveTypeCount[pType] * pType;
01530 switch (pType)
01531 {
01532 case 1:
01533