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 if(geo->getPositions() == NullFC ||
00757 geo->getPositions()->size() == 0)
00758 {
00759 FINFO(("Geo without positions in calcFaceNormals()\n"));
00760 return;
00761 }
00762
00763 GeoIndicesPtr newIndex = GeoIndicesUI32::create();
00764 GeoNormalsPtr newNormals = GeoNormals3f::create();
00765 Vec3f normal;
00766
00767 FaceIterator faceIter = geo->beginFaces();
00768 GeoIndicesPtr oldIndex = geo->getIndices();
00769
00770 if(oldIndex != NullFC)
00771 {
00772
00773 if(geo->getIndexMapping().size() > 0)
00774 {
00775
00776 beginEditCP(newIndex);
00777
00778 MFUInt16 &oldIndexMap = geo->getIndexMapping();
00779 UInt32 oldIMSize = oldIndexMap.size();
00780 for(UInt32 i = 0; i < oldIndex->getSize() / oldIMSize; ++i)
00781 {
00782 for(UInt32 k = 0; k < oldIMSize; ++k)
00783 {
00784 newIndex->push_back(oldIndex->getValue(i * oldIMSize + k));
00785 }
00786
00787 newIndex->push_back(0);
00788 }
00789
00790 beginEditCP(newNormals);
00791 for(UInt32 faceCnt = 0; faceIter != geo->endFaces();
00792 ++faceIter, ++faceCnt)
00793 {
00794 if(faceIter.getLength() == 3)
00795 {
00796
00797 normal =
00798 (
00799 faceIter.getPosition(1) -
00800 faceIter.getPosition(0)
00801 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00802 normal.normalize();
00803 }
00804 else
00805 {
00806
00807 normal =
00808 (
00809 faceIter.getPosition(1) -
00810 faceIter.getPosition(0)
00811 ).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00812 if(normal.length() == 0)
00813 {
00814
00815 normal =
00816 (
00817 faceIter.getPosition(1) -
00818 faceIter.getPosition(2)
00819 ).cross(faceIter.getPosition(3) -
00820 faceIter.getPosition(2));
00821 }
00822
00823 normal.normalize();
00824 }
00825
00826 newNormals->push_back(normal);
00827 UInt32 base;
00828 switch(faceIter.getType())
00829 {
00830 case GL_TRIANGLE_STRIP:
00831 base = faceIter.getIndexIndex(2);
00832 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00833 break;
00834 case GL_TRIANGLE_FAN:
00835 base = faceIter.getIndexIndex(2);
00836 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00837 break;
00838 case GL_QUAD_STRIP:
00839 base = faceIter.getIndexIndex(3);
00840 newIndex->setValue(faceCnt, base + (base / oldIMSize) + oldIMSize);
00841 break;
00842 default:
00843 for(UInt32 i = 0; i < faceIter.getLength(); ++i)
00844 {
00845 base = faceIter.getIndexIndex(i);
00846 newIndex->setValue(faceCnt,
00847 base + (base / oldIMSize) + oldIMSize);
00848 }
00849 break;
00850 }
00851 }
00852
00853 endEditCP(newNormals);
00854 endEditCP(newIndex);
00855
00856 beginEditCP(geo);
00857
00858 Int16 ni;
00859 ni = geo->calcMappingIndex(Geometry::MapNormal);
00860 if(ni != -1)
00861 {
00862 oldIndexMap[ni] = oldIndexMap[ni] &~Geometry::MapNormal;
00863 }
00864
00865 oldIndexMap.push_back(Geometry::MapNormal);
00866 geo->setNormals(newNormals);
00867 geo->setIndices(newIndex);
00868 endEditCP(geo);
00869 return;
00870 }
00871 }
00872
00873
00874
00875 newNormals->resize(geo->getPositions()->getSize());
00876 for(; faceIter != geo->endFaces(); ++faceIter)
00877 {
00878 if(faceIter.getLength() == 3)
00879 {
00880
00881 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00882 normal.normalize();
00883 }
00884 else
00885 {
00886
00887 normal = (faceIter.getPosition(1) - faceIter.getPosition(0)).cross(faceIter.getPosition(2) - faceIter.getPosition(0));
00888 if(normal.length() == 0)
00889 {
00890
00891 normal =
00892 (
00893 faceIter.getPosition(1) -
00894 faceIter.getPosition(2)
00895 ).cross(faceIter.getPosition(3) - faceIter.getPosition(2));
00896 }
00897
00898 normal.normalize();
00899 }
00900
00901 switch(faceIter.getType())
00902 {
00903 case GL_TRIANGLE_STRIP:
00904 newNormals->setValue(normal, faceIter.getPositionIndex(2));
00905 break;
00906 case GL_TRIANGLE_FAN:
00907 newNormals->setValue(normal, faceIter.getPositionIndex(2));
00908 break;
00909 case GL_QUAD_STRIP:
00910 newNormals->setValue(normal, faceIter.getPositionIndex(3));
00911 break;
00912 default:
00913 for(UInt32 i = 0; i < faceIter.getLength(); ++i)
00914 {
00915 newNormals->setValue(normal, faceIter.getPositionIndex(i));
00916 }
00917 break;
00918 }
00919
00920 beginEditCP(geo);
00921 geo->setNormals(newNormals);
00922 endEditCP(geo);
00923 }
00924 }
00925
00942 OSG_SYSTEMLIB_DLLMAPPING
00943 Int32 OSG::setIndexFromVRMLData(GeometryPtr geoPtr,
00944 std::vector<Int32> &coordIndex,
00945 std::vector<Int32> &normalIndex,
00946 std::vector<Int32> &colorIndex,
00947 std::vector<Int32> &texCoordIndex,
00948 bool convex,
00949 bool ccw,
00950 bool normalPerVertex,
00951 bool colorPerVertex,
00952 bool createNormal,
00953 bool faceSet)
00954 {
00955 Int32 primitiveType = faceSet ? GL_POLYGON : GL_LINE_STRIP;
00956
00957 return setIndexFromIndexedX3DData ( geoPtr,
00958 coordIndex,
00959 normalIndex,
00960 colorIndex,
00961 texCoordIndex,
00962 primitiveType,
00963 convex,
00964 ccw,
00965 normalPerVertex,
00966 colorPerVertex,
00967 createNormal );
00968 }
00969
00988 OSG_SYSTEMLIB_DLLMAPPING
00989 Int32 OSG::setIndexFromIndexedX3DData ( GeometryPtr geoPtr,
00990 std::vector<Int32> &coordIndex,
00991 std::vector<Int32> &normalIndex,
00992 std::vector<Int32> &colorIndex,
00993 std::vector<Int32> &texCoordIndex,
00994 Int32 primitiveType,
00995 bool OSG_CHECK_ARG(convex),
00996 bool ccw,
00997 bool normalPerVertex,
00998 bool colorPerVertex,
00999 bool OSG_CHECK_ARG(createNormal) )
01000 {
01002 typedef std::vector<Int32> *IndexBagP;
01003
01005 enum IndexType
01006 {
01007 UNKNOWN_IT = 0,
01008 EMPTY_IT,
01009 VERTEX_COORD_IT,
01010 VERTEX_IT,
01011 VERTEX_DUP_IT,
01012 VERTEX_CREATE_IT,
01013 PRIMITIVE_IT,
01014 PRIMITIVE_INDEX_IT,
01015 PRIMITIVE_CREATE_IT
01016 };
01017
01019 static const char *indexTypeStr[] =
01020 {
01021 "UNKNOWN_IT",
01022 "EMPTY_IT",
01023 "VERTEX_COORD_IT",
01024 "VERTEX_IT",
01025 "VERTEX_DUP_IT",
01026 "VERTEX_CREATE_IT",
01027 "PRIMTIVE_IT",
01028 "PRIMITIVE_INDEX_IT",
01029 "PRIMITIVE_CREATE_IT"
01030 };
01031 OSG::GeoPositionsPtr posPtr;
01032 OSG::GeoNormalsPtr normalPtr;
01033 OSG::GeoColorsPtr colorPtr;
01034 OSG::GeoTexCoordsPtr texCoordsPtr;
01035 OSG::GeoPLengthsPtr lensPtr;
01036 OSG::GeoPTypesPtr geoTypePtr;
01037 OSG::GeoIndicesPtr indexPtr;
01038
01039
01040 Int32 index, i, pi, typei, mapi, primitiveN = 0, vN = 0;
01041 Int32 pType = 0, localPType;
01042 Int32 maxPType;
01043 Int32 minPType;
01044 Int32 beginIndex, endIndex, step, len, sysPType = 0;
01045 Int32 piN = 0, ciN = 0, niN = 0, tiN = 0;
01046 Int32 pN = 0, nN = 0, cN = 0, tN = 0, tN1 = 0, tN2 = 0, tN3 = 0,
01047 tN4 = 0, tN5 = 0, tN6 = 0, tN7 = 0;
01048 IndexType indexType[4];
01049 IndexType &coordIT = indexType[0];
01050 IndexType &normalIT = indexType[1];
01051 IndexType &colorIT = indexType[2];
01052 IndexType &textureIT = indexType[3];
01053 Int32 primitiveTypeCount[6];
01054 UInt32 triCount = 0;
01055 Int16 indexMap[4], indexMapID[4];
01056 UInt32 uiNumTextures = 0;
01057
01058 IndexBagP indexBag[4] =
01059 {
01060 &coordIndex,
01061 &normalIndex,
01062 &colorIndex,
01063 &texCoordIndex
01064 };
01065
01066
01067
01068 coordIT = VERTEX_IT;
01069 indexMap[0] = Geometry::MapPosition;
01070
01071
01072
01073 switch (primitiveType) {
01074 case GL_POINTS:
01075 minPType = 1;
01076 maxPType = 1;
01077 break;
01078 case GL_LINES:
01079 minPType = 2;
01080 maxPType = 3;
01081 break;
01082 case GL_LINE_STRIP:
01083 minPType = 2;
01084 maxPType = 3;
01085 break;
01086 case GL_LINE_LOOP:
01087 minPType = 2;
01088 maxPType = 3;
01089 break;
01090 case GL_TRIANGLES:
01091 minPType = 3;
01092 maxPType = 3;
01093 break;
01094 case GL_TRIANGLE_STRIP:
01095 minPType = 3;
01096 maxPType = 3;
01097 break;
01098 case GL_TRIANGLE_FAN:
01099 minPType = 3;
01100 maxPType = 3;
01101 break;
01102 case GL_QUADS:
01103 minPType = 3;
01104 maxPType = 4;
01105 break;
01106 case GL_QUAD_STRIP:
01107 minPType = 3;
01108 maxPType = 4;
01109 break;
01110 case GL_POLYGON:
01111 minPType = 3;
01112 maxPType = 5;
01113 break;
01114 default:
01115 FFATAL (( "Can not fill index; Invalid primitiveType: %d\n",
01116 primitiveType ));
01117 break;
01118 }
01119
01120
01121
01122
01123 posPtr = geoPtr->getPositions();
01124 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize());
01125
01126 normalPtr = geoPtr->getNormals();
01127 nN = ((normalPtr == OSG::NullFC) ? 0 : normalPtr->getSize());
01128
01129 colorPtr = geoPtr->getColors();
01130 cN = ((colorPtr == OSG::NullFC) ? 0 : colorPtr->getSize());
01131
01132 texCoordsPtr = geoPtr->getTexCoords();
01133 tN = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01134
01135 texCoordsPtr = geoPtr->getTexCoords1();
01136 tN1 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01137
01138 texCoordsPtr = geoPtr->getTexCoords2();
01139 tN2 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01140
01141 texCoordsPtr = geoPtr->getTexCoords3();
01142 tN3 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01143
01144 texCoordsPtr = geoPtr->getTexCoords4();
01145 tN4 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01146
01147 texCoordsPtr = geoPtr->getTexCoords5();
01148 tN5 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01149
01150 texCoordsPtr = geoPtr->getTexCoords6();
01151 tN6 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01152
01153 texCoordsPtr = geoPtr->getTexCoords7();
01154 tN7 = ((texCoordsPtr == OSG::NullFC) ? 0 : texCoordsPtr->getSize());
01155
01156 FDEBUG(("vertex attrib count P/N/C/T: %d/%d/%d/%d\n", pN, nN, cN, tN));
01157
01158
01159
01160 primitiveN = index = 0;
01161 for(pType = 0; pType < 6; pType++)
01162 primitiveTypeCount[pType] = 0;
01163
01164 if(!pN)
01165 {
01166 FINFO(("No points in OSG::setIndexFromVRMLData()\n"));
01167 return 0;
01168 }
01169 else
01170 {
01171 piN = coordIndex.size();
01172 if(piN)
01173 {
01174 for(i = 0; i <= piN; i++)
01175 {
01176 index = (i == piN) ? -1 : coordIndex[i];
01177 if((index < 0) && vN)
01178 {
01179 primitiveTypeCount[(vN > maxPType) ? maxPType : vN]++;
01180 primitiveN++;
01181 vN = 0;
01182 }
01183 else
01184 {
01185 if(index >= pN && i != piN)
01186 {
01187 FWARNING(("Point index (%d/%d) out of range", index, pN));
01188 coordIndex[i] = 0;
01189 }
01190
01191 vN++;
01192 }
01193 }
01194 }
01195 else
01196 {
01197 FWARNING(("No coordIndex in OSG::setIndexFromVRMLData()\n"));
01198 return 0;
01199 }
01200 }
01201
01202
01203
01204 normalIT = UNKNOWN_IT;
01205 niN = normalIndex.size();
01206 if(nN)
01207 {
01208 if(normalPerVertex)
01209 {
01210
01211 if(niN >= piN)
01212 {
01213
01214 for(i = 0; i < piN; i++)
01215 {
01216 if(normalIndex[i] != coordIndex[i])
01217 {
01218 normalIT = VERTEX_IT;
01219 break;
01220 }
01221 }
01222
01223 if(normalIT == UNKNOWN_IT)
01224 {
01225
01226 normalIT = VERTEX_DUP_IT;
01227 }
01228 }
01229 else
01230 {
01231
01232 normalIT = VERTEX_COORD_IT;
01233 if(niN)
01234 {
01235 FWARNING(("Not enough normal index (%d,%d)\n", normalIndex.
01236 size(), piN));
01237 normalIndex.clear();
01238 }
01239 }
01240 }
01241 else
01242 {
01243
01244 if(niN >= primitiveN)
01245 {
01246
01247 normalIT = PRIMITIVE_INDEX_IT;
01248 }
01249 else
01250 {
01251 if(nN >= primitiveN)
01252 {
01253
01254 normalIT = PRIMITIVE_IT;
01255 }
01256 else
01257 {
01258 FINFO(("not enough normal index (%d,%d)\n", nN, primitiveN));
01259 }
01260 }
01261 }
01262 }
01263 else
01264 {
01265
01266
01267
01268
01269
01270
01271
01272
01273 normalIT = EMPTY_IT;
01274 }
01275
01276
01277
01278 colorIT = UNKNOWN_IT;
01279 ciN = colorIndex.size();
01280 if(cN)
01281 {
01282 if(colorPerVertex)
01283 {
01284
01285 if(ciN >= piN)
01286 {
01287
01288 for(i = 0; i < piN; i++)
01289 {
01290 if(colorIndex[i] != coordIndex[i])
01291 {
01292 colorIT = VERTEX_IT;
01293 break;
01294 }
01295 }
01296
01297 if(colorIT == UNKNOWN_IT)
01298 {
01299
01300 colorIT = VERTEX_DUP_IT;
01301 }
01302 }
01303 else
01304 {
01305
01306 colorIT = VERTEX_COORD_IT;
01307 if(ciN)
01308 {
01309 FWARNING(("Not enough color index (%d,%d)\n", colorIndex.
01310 size(), piN));
01311 colorIndex.clear();
01312 }
01313 }
01314 }
01315 else
01316 {
01317
01318 if(ciN >= primitiveN)
01319 {
01320
01321 colorIT = PRIMITIVE_INDEX_IT;
01322 }
01323 else
01324 {
01325 if(cN >= primitiveN)
01326 {
01327
01328 colorIT = PRIMITIVE_IT;
01329 }
01330 else
01331 {
01332 FINFO(("not enough color index (%d,%d)\n", cN, primitiveN));
01333 }
01334 }
01335 }
01336 }
01337 else
01338 {
01339 colorIT = EMPTY_IT;
01340 }
01341
01342
01343
01344 textureIT = UNKNOWN_IT;
01345 tiN = texCoordIndex.size();
01346 if(tN)
01347 {
01348 if(tiN >= piN)
01349 {
01350
01351 for(i = 0; i < piN; i++)
01352 {
01353 if(texCoordIndex[i] != coordIndex[i])
01354 {
01355 textureIT = VERTEX_IT;
01356 break;
01357 }
01358 }
01359
01360 if(textureIT == UNKNOWN_IT)
01361 {
01362
01363 textureIT = VERTEX_DUP_IT;
01364 }
01365 }
01366 else
01367 {
01368
01369 textureIT = VERTEX_COORD_IT;
01370 if(ciN)
01371 {
01372 FWARNING(("Not enough texCoord index (%d,%d)\n", texCoordIndex.
01373 size(), piN));
01374 texCoordIndex.clear();
01375 }
01376 }
01377 }
01378 else
01379 {
01380 textureIT = EMPTY_IT;
01381 }
01382
01383 FNOTICE (( "primitiveN: %d, %d, 0/%d 1/%d 2/%d 3/%d 4/%d 5/%d\n",
01384 primitiveType,
01385 primitiveN, primitiveTypeCount[0],
01386 primitiveTypeCount[1], primitiveTypeCount[2],
01387 primitiveTypeCount[3], primitiveTypeCount[4],
01388 primitiveTypeCount[5]));
01389
01390 FNOTICE (( "IndexType: coord: %s, color: %s, normal: %s, texture: %s \n",
01391 indexTypeStr[coordIT], indexTypeStr[colorIT],
01392 indexTypeStr[normalIT], indexTypeStr[textureIT]));
01393
01394
01395
01396 indexPtr = geoPtr->getIndices();
01397 if(indexPtr == OSG::NullFC)
01398 {
01399 indexPtr = OSG::GeoIndicesUI32::create();
01400 }
01401 else
01402 {
01403 OSG::beginEditCP(indexPtr);
01404 indexPtr->clear();
01405 OSG::endEditCP(indexPtr);
01406 }
01407
01408 lensPtr = geoPtr->getLengths();
01409 if(lensPtr == OSG::NullFC)
01410 {
01411 lensPtr = OSG::GeoPLengthsUI32::create();
01412 }
01413 else
01414 {
01415 OSG::beginEditCP(lensPtr);
01416 lensPtr->clear();
01417 OSG::endEditCP(lensPtr);
01418 }
01419
01420 geoTypePtr = geoPtr->getTypes();
01421 if(geoTypePtr == OSG::NullFC)
01422 {
01423 geoTypePtr = OSG::GeoPTypesUI8::create();
01424 }
01425 else
01426 {
01427 OSG::beginEditCP(geoTypePtr);
01428 geoTypePtr->clear();
01429 OSG::endEditCP(geoTypePtr);
01430 }
01431
01432
01433
01434 indexMapID[0] = Geometry::MapPosition;
01435 indexMapID[1] = Geometry::MapNormal;
01436 indexMapID[2] = Geometry::MapColor;
01437 indexMapID[3] = Geometry::MapTexCoords;
01438
01439 for(mapi = i = 1; i <= 3; i++)
01440 {
01441 indexMap[i] = 0;
01442 switch(indexType[i])
01443 {
01444 case UNKNOWN_IT:
01445 case EMPTY_IT:
01446 break;
01447 case VERTEX_COORD_IT:
01448 case VERTEX_DUP_IT:
01449
01450 indexMap[0] |= indexMapID[i];
01451 break;
01452 case VERTEX_IT:
01453 case PRIMITIVE_IT:
01454 case PRIMITIVE_INDEX_IT:
01455
01456 indexMap[mapi++] = indexMapID[i];
01457 break;
01458 default:
01459 break;
01460 }
01461 }
01462
01463
01464
01465 OSG::beginEditCP(geoPtr);
01466 {
01467 geoPtr->setLengths(lensPtr);
01468 geoPtr->setTypes(geoTypePtr);
01469 geoPtr->setIndices(indexPtr);
01470 geoPtr->getIndexMapping().clear();
01471
01472
01473
01474 for(i = 0; ((i <= 3) && indexMap[i]); i++)
01475 {
01476 if(i == 0)
01477 {
01478 if(indexMap[i] & Geometry::MapTexCoords)
01479 {
01480 ++uiNumTextures;
01481
01482 if(tN1 != 0)
01483 {
01484 indexMap[i] |= Geometry::MapTexCoords1;
01485 }
01486
01487 if(tN2 != 0)
01488 {
01489 indexMap[i] |= Geometry::MapTexCoords2;
01490 }
01491
01492 if(tN3 != 0)
01493 {
01494 indexMap[i] |= Geometry::MapTexCoords3;
01495 }
01496
01497 if(tN4 != 0)
01498 {
01499 indexMap[i] |= Geometry::MapTexCoords4;
01500 }
01501
01502 if(tN5 != 0)
01503 {
01504 indexMap[i] |= Geometry::MapTexCoords5;
01505 }
01506
01507 if(tN6 != 0)
01508 {
01509 indexMap[i] |= Geometry::MapTexCoords6;
01510 }
01511
01512 if(tN7 != 0)
01513 {
01514 indexMap[i] |= Geometry::MapTexCoords7;
01515 }
01516 }
01517
01518 geoPtr->getIndexMapping().push_back(indexMap[i]);
01519 }
01520 else
01521 {
01522 geoPtr->getIndexMapping().push_back(indexMap[i]);
01523
01524 if(indexMap[i] & Geometry::MapTexCoords)
01525 {
01526 ++uiNumTextures;
01527
01528 if(tN1 != 0)
01529 {
01530 geoPtr->getIndexMapping().push_back(
01531 Geometry::MapTexCoords1);
01532
01533 ++uiNumTextures;
01534 }
01535
01536 if(tN2 != 0)
01537 {
01538 geoPtr->getIndexMapping().push_back(
01539 Geometry::MapTexCoords2);
01540
01541 ++uiNumTextures;
01542 }
01543
01544 if(tN3 != 0)
01545 {
01546 geoPtr->getIndexMapping().push_back(
01547 Geometry::MapTexCoords3);
01548
01549 ++uiNumTextures;
01550 }
01551
01552 if(tN4 != 0)
01553 {
01554 geoPtr->getIndexMapping().push_back(
01555 Geometry::MapTexCoords4);
01556
01557 ++uiNumTextures;
01558 }
01559
01560 if(tN5 != 0)
01561 {
01562 geoPtr->getIndexMapping().push_back(
01563 Geometry::MapTexCoords5);
01564
01565 ++uiNumTextures;
01566 }
01567
01568 if(tN6 != 0)
01569 {
01570 geoPtr->getIndexMapping().push_back(
01571 Geometry::MapTexCoords6);
01572
01573 ++uiNumTextures;
01574 }
01575
01576 if(tN7 != 0)
01577 {
01578 geoPtr->getIndexMapping().push_back(
01579 Geometry::MapTexCoords7);
01580
01581 ++uiNumTextures;
01582 }
01583 }
01584 }
01585 }
01586 }
01587 OSG::endEditCP(geoPtr);
01588
01589
01590
01591 OSG::beginEditCP(indexPtr);
01592 OSG::beginEditCP(lensPtr);
01593 OSG::beginEditCP(geoTypePtr);
01594
01595 for(pType = minPType; pType <= maxPType; pType++)
01596 {
01597
01598 if(primitiveTypeCount[pType])
01599 {
01600
01601
01602 if(pType < maxPType)
01603 {
01604 len = primitiveTypeCount[pType] * pType;
01605 switch (pType)
01606 {
01607 case 1:
01608 sysPType = GL_POINTS;
01609 break;
01610 case 2:
01611 sysPType = GL_LINES;
01612 break;
01613 case 3:
01614 sysPType = GL_TRIANGLES;
01615 break;
01616 case 4:
01617 sysPType = GL_QUADS;
01618 break;
01619 }
01620 }
01621 else
01622 {
01623 sysPType = 0;
01624 }
01625
01626
01627 if(sysPType)
01628 {
01629 lensPtr->push_back(len);
01630 geoTypePtr->push_back(sysPType);
01631 }
01632
01633 primitiveN = 0;
01634 beginIndex = endIndex = -1;
01635 for(i = 0; i <= piN; i++)
01636 {
01637 if(((i == piN) && (coordIndex[i - 1] >= 0)) ||
01638 ((i < piN) && (coordIndex[i] < 0)))
01639 {
01640 len = i - beginIndex;
01641 if(ccw)
01642 {
01643 endIndex = i;
01644 step = 1;
01645 }
01646 else
01647 {
01648 endIndex = beginIndex - 1;
01649 beginIndex = i - 1;
01650 step = -1;
01651 }
01652
01653 localPType = (len > maxPType) ? maxPType : len;
01654 if((beginIndex >= 0) && (localPType == pType))
01655 {
01656 if(len >= maxPType)
01657 {
01658 sysPType = primitiveType;
01659 lensPtr->push_back(len);
01660 geoTypePtr->push_back(sysPType);
01661 }
01662
01663
01664 for(pi = beginIndex; pi != endIndex; pi += step)
01665 {
01666 indexPtr->push_back(coordIndex[pi]);
01667 for(mapi = 1; (mapi <= 3) && (indexMap[mapi]);
01668 mapi++)
01669 {
01670 for(typei = 1; typei <= 3; typei++)
01671 {
01672 if(indexMap[mapi] & indexMapID[typei])
01673 {
01674 switch(indexType[typei])
01675 {
01676 case UNKNOWN_IT:
01677 case EMPTY_IT:
01678 case VERTEX_COORD_IT:
01679 case VERTEX_DUP_IT:
01680 FFATAL(("Fatal index mapping error \n"));
01681 break;
01682 case VERTEX_IT:
01683 index = (*indexBag[typei])[pi];
01684 break;
01685 case PRIMITIVE_IT:
01686 index = primitiveN;
01687 break;
01688 case PRIMITIVE_INDEX_IT:
01689 index = (*indexBag[typei])[primitiveN];
01690 break;
01691 default:
01692 break;
01693 }
01694
01695 indexPtr->push_back(index);
01696
01697 if(indexMap[mapi] & Geometry::MapTexCoords)
01698 {
01699 for(UInt32 ti = 0; ti < uiNumTextures - 1; ++ti)
01700 {
01701 indexPtr->push_back(index);
01702 }
01703 }
01704 }
01705
01706 }
01707 }
01708 }
01709
01710 triCount += len - 2;
01711 }
01712
01713 primitiveN++;
01714 beginIndex = endIndex = -1;
01715 }
01716 else if(beginIndex < 0)
01717 beginIndex = i;
01718 }
01719 }
01720 }
01721
01722 OSG::endEditCP(geoTypePtr);
01723 OSG::endEditCP(lensPtr);
01724 OSG::endEditCP(indexPtr);
01725
01726 return triCount;
01727 }
01728
01729
01732 struct IndexDic
01733 {
01734 typedef std::vector<Int32> Int32Vec;
01735 public:
01736
01737 Int32 entry(Int32Vec &indexVec);
01738
01739 const Int32Vec &entry(Int32 index);
01740
01741 UInt32 entryCount(void) const;
01742 private:
01743
01744 typedef std::map<Int32Vec, Int32> IndexMap;
01745 IndexMap _indexMap;
01746
01747 std::vector < const Int32Vec * > _indexVec;
01748 };
01749
01750 inline Int32 IndexDic::entry(Int32Vec &indexVec)
01751 {
01752 IndexMap::iterator iI = _indexMap.find(indexVec);
01753 if(iI == _indexMap.end())
01754 {
01755 std::pair < IndexMap::iterator, bool > mapRes =
01756 _indexMap.insert(IndexMap::value_type(indexVec, _indexVec.size()));
01757 if(mapRes.second)
01758 {
01759 iI = mapRes.first;
01760 _indexVec.push_back(&(iI->first));
01761 }
01762 else
01763 {
01764 FFATAL(("IndexDic::entry() map insert error\n"));
01765 }
01766 }
01767
01768 return iI->second;
01769 }
01770
01771 inline const IndexDic::Int32Vec & IndexDic::entry(Int32 index)
01772 {
01773 return *(_indexVec[index]);
01774 }
01775
01776 inline UInt32 IndexDic::entryCount(void) const
01777 {
01778 return _indexVec.size();
01779 }
01780
01781
01788 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcVertexTexCoords(GeometryPtr geo, Int32 texIndex)
01789 {
01790 struct Key {
01791 Real32 value;
01792 Int32 pos;
01793 } key[3], rem;
01794
01795 Int32 S = -1, T = -1, n = 3, i, j;
01796 Real32 sDenom, tDenom, sMin, tMin;
01797
01798 MFUInt16 &im = geo->getIndexMapping();
01799 UInt16 mapTex = 0;
01800
01801 GeoIndicesPtr ip = geo->getIndices();
01802 GeoPositionsPtr posP = geo->getPositions();
01803 GeoTexCoordsPtr texP;
01804
01805 if (posP == NullFC || !posP->size() || ip == NullFC || !ip->size())
01806 {
01807 FFATAL(("Geo without indices/ positions in calcVertexTexCoords()\n"));
01808 return;
01809 }
01810
01811 for (MFNodePtr::iterator pnI = geo->getMFParents()->begin();
01812 pnI != geo->getMFParents()->end(); ++pnI)
01813 {
01814 NodePtr node = *pnI;
01815
01816 if (node != NullFC)
01817 {
01818 DynamicVolume &dVol = node->getVolume(true);
01819 Pnt3f min, max;
01820 dVol.getBounds(min, max);
01821
01822 Vec3f dia(max - min);
01823 for (i=0; i<3; i++)
01824 {
01825 key[i].value = dia[i];
01826 key[i].pos = i;
01827 }
01828
01829 for (i=1; i<n; i++)
01830 {
01831 for (j=n-1; j>=i; j--)
01832 {
01833 if (key[j-1].value > key[j].value)
01834 {
01835 rem = key[j];
01836 key[j] = key[j-1];
01837 key[j-1] = rem;
01838 }
01839 }
01840 }
01841
01842 S = key[2].pos;
01843 T = key[1].pos;
01844 sDenom = dia[S];
01845 tDenom = dia[T];
01846 sMin = min[S];
01847 tMin = min[T];
01848
01849 break;
01850 }
01851 }
01852
01853 if (S < 0 || T < 0)
01854 {
01855 FFATAL(("Geo without parents in calcVertexTexCoords()\n"));
01856 return;
01857 }
01858
01859 switch (texIndex)
01860 {
01861 case 0:
01862 if (geo->getTexCoords() == osg::NullFC)
01863 {
01864 texP = GeoTexCoords2f::create();
01865 beginEditCP(geo);
01866 geo->setTexCoords(texP);
01867 endEditCP(geo);
01868 }
01869 else
01870 {
01871 texP = geo->getTexCoords();
01872 }
01873 mapTex = Geometry::MapTexCoords;
01874 break;
01875 case 1:
01876 if (geo->getTexCoords1() == osg::NullFC)
01877 {
01878 texP = GeoTexCoords2f::create();
01879 beginEditCP(geo);
01880 geo->setTexCoords1(texP);
01881 endEditCP(geo);
01882 }
01883 else
01884 {
01885 texP = geo->getTexCoords1();
01886 }
01887 mapTex = Geometry::MapTexCoords1;
01888 break;
01889 case 2:
01890 if (geo->getTexCoords2() == osg::NullFC)
01891 {
01892 texP = GeoTexCoords2f::create();
01893 beginEditCP(geo);
01894 geo->setTexCoords2(texP);
01895 endEditCP(geo);
01896 }
01897 else
01898 {
01899 texP = geo->getTexCoords2();
01900 }
01901 mapTex = Geometry::MapTexCoords2;
01902 break;
01903 case 3:
01904 if (geo->getTexCoords3() == osg::NullFC)
01905 {
01906 texP = GeoTexCoords2f::create();
01907 beginEditCP(geo);
01908 geo->setTexCoords3(texP);
01909 endEditCP(geo);
01910 }
01911 else
01912 {
01913 texP = geo->getTexCoords3();
01914 }
01915 mapTex = Geometry::MapTexCoords3;
01916 break;
01917 case 4:
01918 if (geo->getTexCoords4() == osg::NullFC)
01919 {
01920 texP = GeoTexCoords2f::create();
01921 beginEditCP(geo);
01922 geo->setTexCoords4(texP);
01923 endEditCP(geo);
01924 }
01925 else
01926 {
01927 texP = geo->getTexCoords4();
01928 }
01929 mapTex = Geometry::MapTexCoords4;
01930 break;
01931 case 5:
01932 if (geo->getTexCoords5() == osg::NullFC)
01933 {
01934 texP = GeoTexCoords2f::create();
01935 beginEditCP(geo);
01936 geo->setTexCoords5(texP);
01937 endEditCP(geo);
01938 }
01939 else
01940 {
01941 texP = geo->getTexCoords5();
01942 }
01943 mapTex = Geometry::MapTexCoords5;
01944 break;
01945 case 6:
01946 if (geo->getTexCoords6() == osg::NullFC)
01947 {
01948 texP = GeoTexCoords2f::create();
01949 beginEditCP(geo);
01950 geo->setTexCoords6(texP);
01951 endEditCP(geo);
01952 }
01953 else
01954 {
01955 texP = geo->getTexCoords6();
01956 }
01957 mapTex = Geometry::MapTexCoords6;
01958 break;
01959 case 7:
01960 if (geo->getTexCoords7() == osg::NullFC)
01961 {
01962 texP = GeoTexCoords2f::create();
01963 beginEditCP(geo);
01964 geo->setTexCoords7(texP);
01965 endEditCP(geo);
01966 }
01967 else
01968 {
01969 texP = geo->getTexCoords7();
01970 }
01971 mapTex = Geometry::MapTexCoords7;
01972 break;
01973 default:
01974 FWARNING(("Parameters are [0|1|2|3|4|5|6|7] in calcVertexTexCoords()\n"));
01975 return;
01976 }
01977
01978 Int16 niTex = geo->calcMappingIndex(mapTex),
01979 niPos = geo->calcMappingIndex(Geometry::MapPosition);
01980 Int32 len = posP->size(), indexMapSize = im.size(), imsize = 0, ibsize;
01981 UInt32 nind = ip->size() / (indexMapSize ? indexMapSize : 1);
01982
01983 Pnt3f point;
01984 Vec2f texCoord;
01985
01986 if (indexMapSize > 1)
01987 {
01988 MFUInt16::iterator imIt = im.begin();
01989 std::vector<UInt32> indexBuffer;
01990
01991 if (niTex >= 0)
01992 im[niTex] = im[niTex] &~ mapTex;
01993
01994 im.push_back(mapTex);
01995
01996 for (i=0; i<nind; i++)
01997 {
01998 for (j=0; j<indexMapSize; j++)
01999 {
02000 if (j != niTex || im[niTex] >= 1)
02001 indexBuffer.push_back(ip->getValue(i*indexMapSize + j));
02002 }
02003 indexBuffer.push_back(ip->getValue(i*indexMapSize + niPos));
02004 }
02005
02006 if (niTex >= 0 && im[niTex] < 1)
02007 im.erase(imIt + niTex);
02008
02009 imsize = im.size();
02010 ibsize = indexBuffer.size();
02011
02012 beginEditCP(ip);
02013 {
02014 ip->clear();
02015
02016 if (imsize != indexMapSize)
02017 ip->resize(ibsize);
02018
02019 for (i=0; i<ibsize; i++)
02020 ip->setValue(indexBuffer[i], i);
02021 }
02022 endEditCP(ip);
02023
02024 niTex = imsize ? imsize - 1 : 0;
02025 }
02026
02027 beginEditCP(texP);
02028 {
02029 niPos = geo->calcMappingIndex(Geometry::MapPosition);
02030 niPos = (niPos >= 0) ? niPos : 0;
02031
02032 if (texP->size() != len)
02033 texP->resize(len);
02034
02035 beginEditCP(ip);
02036 {
02037 for (i=0; i<len; i++)
02038 {
02039 posP->getValue(point, i);
02040
02041 texCoord[0] = (point[S] - sMin) / sDenom;
02042 texCoord[1] = (point[T] - tMin) / tDenom;
02043
02044 texP->setValue(texCoord, i);
02045 }
02046 }
02047 endEditCP(ip);
02048 }
02049 endEditCP(texP);
02050 }
02051
02052
02059 OSG_SYSTEMLIB_DLLMAPPING void OSG::calcVertexTangents (GeometryPtr geo,
02060 Int32 srcTexIndex,
02061 Int32 dstAttribTan,
02062 Int32 dstAttribBin)
02063 {
02064 GeoTexCoords4fPtr tangentP, binormalP;
02065 std::vector<Vec3f> tangent, binormal, normal;
02066 UInt16 mapTan = 0, mapBin = 0, mapTex = 0;
02067
02068
02069 if (dstAttribTan == dstAttribBin)
02070 dstAttribBin = -1;
02071
02072 switch (srcTexIndex)
02073 {
02074 case 0:
02075 mapTex = Geometry::MapTexCoords;
02076 break;
02077 case 1:
02078 mapTex = Geometry::MapTexCoords1;
02079 break;
02080 case 2:
02081 mapTex = Geometry::MapTexCoords2;
02082 break;
02083 case 3:
02084 mapTex = Geometry::MapTexCoords3;
02085 break;
02086 case 4:
02087 mapTex = Geometry::MapTexCoords4;
02088 break;
02089 case 5:
02090 mapTex = Geometry::MapTexCoords5;
02091 break;
02092 case 6:
02093 mapTex = Geometry::MapTexCoords6;
02094 break;
02095 case 7:
02096 mapTex = Geometry::MapTexCoords7;
02097 break;
02098 default:
02099 FWARNING(("Currently only 8 TexCoords allowed in GeoPtr\n"));
02100 srcTexIndex = 0;
02101 mapTex = Geometry::MapTexCoords;
02102 break;
02103 }
02104
02105 switch (dstAttribTan)
02106 {
02107 case Geometry::TexCoordsFieldId:
02108 beginEditCP(geo);
02109 {
02110
02111
02112 tangentP = GeoTexCoords4f::create();
02113 geo->setTexCoords(tangentP);
02114 }
02115 endEditCP(geo);
02116 mapTan = Geometry::MapTexCoords;
02117 break;
02118 case Geometry::TexCoords1FieldId:
02119 beginEditCP(geo);
02120 {
02121 tangentP = GeoTexCoords4f::create();
02122 geo->setTexCoords1(tangentP);
02123 }
02124 endEditCP(geo);
02125 mapTan = Geometry::MapTexCoords1;
02126 break;
02127 case Geometry::TexCoords2FieldId:
02128 beginEditCP(geo);
02129 {
02130 tangentP = GeoTexCoords4f::create();
02131 geo->setTexCoords2(tangentP);
02132 }
02133 endEditCP(geo);
02134 mapTan = Geometry::MapTexCoords2;
02135 break;
02136 case Geometry::TexCoords3FieldId:
02137 beginEditCP(geo);
02138 {
02139 tangentP = GeoTexCoords4f::create();
02140 geo->setTexCoords3(tangentP);
02141 }
02142 endEditCP(geo);
02143 mapTan = Geometry::MapTexCoords3;
02144 break;
02145 case Geometry::TexCoords4FieldId:
02146 beginEditCP(geo);
02147 {
02148 tangentP = GeoTexCoords4f::create();
02149 geo->setTexCoords4(tangentP);
02150 }
02151 endEditCP(geo);
02152 mapTan = Geometry::MapTexCoords4;
02153 break;
02154 case Geometry::TexCoords5FieldId:
02155 beginEditCP(geo);
02156 {
02157 tangentP = GeoTexCoords4f::create();
02158 geo->setTexCoords5(tangentP);
02159 }
02160 endEditCP(geo);
02161 mapTan = Geometry::MapTexCoords5;
02162 break;
02163 case Geometry::TexCoords6FieldId:
02164 beginEditCP(geo);
02165 {
02166 tangentP = GeoTexCoords4f::create();
02167 geo->setTexCoords6(tangentP);
02168 }
02169 endEditCP(geo);
02170 mapTan = Geometry::MapTexCoords6;
02171 break;
02172 case Geometry::TexCoords7FieldId:
02173 beginEditCP(geo);
02174 {
02175 tangentP = GeoTexCoords4f::create();
02176 geo->setTexCoords7(tangentP);
02177 }
02178 endEditCP(geo);
02179 mapTan = Geometry::MapTexCoords7;
02180 break;
02181
02182 case Geometry::PositionsFieldId:
02183 case Geometry::NormalsFieldId:
02184 case Geometry::ColorsFieldId:
02185 case Geometry::SecondaryColorsFieldId:
02186 FWARNING(("Case currently not treated, using NONE\n"));
02187 dstAttribTan = -1;
02188
02189 case -1:
02190 tangentP = GeoTexCoords4f::create();
02191 break;
02192 }
02193
02194 switch (dstAttribBin)
02195 {
02196 case Geometry::TexCoordsFieldId:
02197 beginEditCP(geo);
02198 {
02199 binormalP = GeoTexCoords4f::create();
02200 geo->setTexCoords(binormalP);
02201 }
02202 endEditCP(geo);
02203 mapBin = Geometry::MapTexCoords;
02204 break;
02205 case Geometry::TexCoords1FieldId:
02206 beginEditCP(geo);
02207 {
02208 binormalP = GeoTexCoords4f::create();
02209 geo->setTexCoords1(binormalP);
02210 }
02211 endEditCP(geo);
02212 mapBin = Geometry::MapTexCoords1;
02213 break;
02214 case Geometry::TexCoords2FieldId:
02215 beginEditCP(geo);
02216 {
02217 binormalP = GeoTexCoords4f::create();
02218 geo->setTexCoords2(binormalP);
02219 }
02220 endEditCP(geo);
02221 mapBin = Geometry::MapTexCoords2;
02222 break;
02223 case Geometry::TexCoords3FieldId:
02224 beginEditCP(geo);
02225 {
02226 binormalP = GeoTexCoords4f::create();
02227 geo->setTexCoords3(binormalP);
02228 }
02229 endEditCP(geo);
02230 mapBin = Geometry::MapTexCoords3;
02231 break;
02232 case Geometry::TexCoords4FieldId:
02233 beginEditCP(geo);
02234 {
02235 binormalP = GeoTexCoords4f::create();
02236 geo->setTexCoords4(binormalP);
02237 }
02238 endEditCP(geo);
02239 mapBin = Geometry::MapTexCoords4;
02240 break;
02241 case Geometry::TexCoords5FieldId:
02242 beginEditCP(geo);
02243 {
02244 binormalP = GeoTexCoords4f::create();
02245 geo->setTexCoords5(binormalP);
02246 }
02247 endEditCP(geo);
02248 mapBin = Geometry::MapTexCoords5;
02249 break;
02250 case Geometry::TexCoords6FieldId:
02251 beginEditCP(geo);
02252 {
02253 binormalP = GeoTexCoords4f::create();
02254 geo->setTexCoords6(binormalP);
02255 }
02256 endEditCP(geo);
02257 mapBin = Geometry::MapTexCoords6;
02258 break;
02259 case Geometry::TexCoords7FieldId:
02260 beginEditCP(geo);
02261 {
02262 binormalP = GeoTexCoords4f::create();
02263 geo->setTexCoords7(binormalP);
02264 }
02265 endEditCP(geo);
02266 mapBin = Geometry::MapTexCoords7;
02267 break;
02268
02269 case Geometry::PositionsFieldId:
02270 case Geometry::NormalsFieldId:
02271 case Geometry::ColorsFieldId:
02272 case Geometry::SecondaryColorsFieldId:
02273 FWARNING(("Case currently not treated, using NONE\n"));
02274 dstAttribBin = -1;
02275
02276 case -1:
02277 binormalP = GeoTexCoords4f::create();
02278 break;
02279 }
02280
02281
02282 if ( srcTexIndex < 0 || srcTexIndex > 3 ||
02283 (dstAttribTan == -1 && dstAttribBin == -1))
02284 {
02285 FFATAL(("Index set not supported in calcVertexTangents()\n"));
02286 return;
02287 }
02288
02289 GeoIndicesPtr ip = geo->getIndices();
02290
02291
02292 if (ip == NullFC || ip->size() == 0)
02293 {
02294 FFATAL(("Geo without indices in calcVertexTangents()\n"));
02295 return;
02296 }
02297
02298 GeoPositionsPtr positions = geo->getPositions();
02299
02300
02301 if (positions == NullFC)
02302 {
02303 FFATAL(("Geo without positions in calcVertexTangents()\n"));
02304 return;
02305 }
02306
02307 MFUInt16 &im = geo->getIndexMapping();
02308 Int16 niTan = (mapTan > 0) ? geo->calcMappingIndex(mapTan) : -1,
02309 niBin = (mapBin > 0) ? geo->calcMappingIndex(mapBin) : -1;
02310
02311 Int32 indexMapSize = im.size(), j, imsize = 0;
02312 UInt32 i, val, nind = ip->size() / (indexMapSize ? indexMapSize : 1);
02313 bool multiIndex = (indexMapSize > 1) ? true : false;
02314
02315 beginEditCP(geo, Geometry::IndexMappingFieldMask |
02316 Geometry::IndicesFieldMask );
02317
02318 if (multiIndex)
02319 {
02320
02321 if (niTan >= 0)
02322 im[niTan] = im[niTan] & ~mapTan;
02323 if (niBin >= 0)
02324 im[niBin] = im[niBin] & ~mapBin;
02325
02326
02327 MFUInt16::iterator imIt = im.begin();
02328 if (niTan == niBin)
02329 {
02330 if (niTan >= 0 && im[niTan] < 1)
02331 im.erase(imIt + niTan);
02332 else
02333 niTan = niBin = -1;
02334 }
02335 else if (niTan < niBin)
02336 {
02337 if (niBin >= 0 && im[niBin] < 1)
02338 im.erase(imIt + niBin);
02339 else
02340 niBin = -1;
02341 if (niTan >= 0 && im[niTan] < 1)
02342 im.erase(imIt + niTan);
02343 else
02344 niTan = -1;
02345 }
02346 else
02347 {
02348 if (niTan >= 0 && im[niTan] < 1)
02349 im.erase(imIt + niTan);
02350 else
02351 niTan = -1;
02352 if (niBin >= 0 && im[niBin] < 1)
02353 im.erase(imIt + niBin);
02354 else
02355 niBin = -1;
02356 }
02357
02358
02359 UInt16 map = 0;
02360 if (mapTan > 0)
02361 map |= mapTan;
02362 if (mapBin > 0)
02363 map |= mapBin;
02364 if (map > 0)
02365 im.push_back(map);
02366 imsize = im.size();
02367
02368
02369 std::vector<UInt32> indexBuffer;
02370 int status, l = 0, g = 0, ibSize;
02371
02372 if (niTan < 0 && niBin < 0)
02373 {
02374 status = 0;
02375 }
02376 else if (niBin < 0 && niTan >= 0 ||
02377 niBin >= 0 && niTan < 0 ||
02378 niBin >= 0 && niBin == niTan)
02379 {
02380 status = 1;
02381 l = (niBin < niTan) ? niTan : niBin;
02382 }
02383 else
02384 {
02385 status = 2;
02386 l = (niBin < niTan) ? niBin : niTan;
02387 g = (niBin < niTan) ? niTan : niBin;
02388 }
02389
02390
02391 for (i=0; i<nind; i++)
02392 {
02393 for (j=0; j<indexMapSize; j++)
02394 {
02395 switch (status)
02396 {
02397 case 0:
02398 indexBuffer.push_back(ip->getValue(i*indexMapSize+j));
02399 break;
02400 case 1:
02401 if (j != l)
02402 indexBuffer.push_back(ip->getValue(i*indexMapSize+j));
02403 break;
02404 case 2:
02405 if (j != l && j != g)
02406 indexBuffer.push_back(ip->getValue(i*indexMapSize+j));
02407 break;
02408 }
02409 }
02410 indexBuffer.push_back(0);
02411 }
02412 ibSize = indexBuffer.size();
02413
02414 beginEditCP(ip);
02415 {
02416 ip->clear();
02417 ip->resize(ibSize);
02418
02419 for (i=0; i<ibSize; i++)
02420 ip->setValue(indexBuffer[i], i);
02421 }
02422 endEditCP(ip);
02423
02424 }
02425 else
02426 {
02427
02428 if(im.size() > 0)
02429 im[0] |= (mapTan | mapBin);
02430 }
02431
02432 endEditCP(geo, Geometry::IndexMappingFieldMask |
02433 Geometry::IndicesFieldMask );
02434
02435 TriangleIterator tI;
02436 IndexDic indexDic;
02437 Int32 k, index, v[3];
02438 Vec4f vect(0, 0, 0, 0);
02439
02440 std::vector<Int32>indexVec;
02441 Int16 niPos = geo->calcMappingIndex(Geometry::MapPosition),
02442 niNorm = geo->calcMappingIndex(Geometry::MapNormal),
02443 niTex = geo->calcMappingIndex(mapTex);
02444
02445 indexVec.resize(3);
02446
02447 beginEditCP(ip);
02448
02449
02450 UInt32 maxindex = 0;
02451 for(i=0;i<ip->size();++i)
02452 maxindex = ip->getValue(i) > maxindex ? ip->getValue(i) : maxindex;
02453
02454
02455
02456 tangent.resize(maxindex + 1);
02457 binormal.resize(maxindex + 1);
02458 normal.resize(maxindex + 1);
02459
02460 for (tI=geo->beginTriangles(), i=0; tI!=geo->endTriangles(); ++tI, ++i)
02461 {
02462
02463 for (k=0; k<3; ++k)
02464 {
02465 index = tI.getIndexIndex(k);
02466
02467 if (multiIndex)
02468 {
02469
02470 for (j=0; j<imsize; j++)
02471 {
02472 if (j == niPos || j == niNorm || j == niTex)
02473 indexVec[j] = ip->getValue(index + j);
02474 }
02475 v[k] = indexDic.entry(indexVec);
02476 }
02477 else
02478 {
02479 v[k] = tI.getPositionIndex(k);
02480 }
02481 }
02482
02483
02484 Int32 v0 = tI.getPositionIndex(0),
02485 v1 = tI.getPositionIndex(1),
02486 v2 = tI.getPositionIndex(2);
02487 Vec2f t0, t1, t2, tex1, tex2;
02488 Vec3f edge1, edge2, sdir, tdir;
02489
02490 switch (srcTexIndex)
02491 {
02492 case 0:
02493 t0 = tI.getTexCoords(0);
02494 t1 = tI.getTexCoords(1);
02495 t2 = tI.getTexCoords(2);
02496 break;
02497 case 1:
02498 t0 = tI.getTexCoords1(0);
02499 t1 = tI.getTexCoords1(1);
02500 t2 = tI.getTexCoords1(2);
02501 break;
02502 case 2:
02503 t0 = tI.getTexCoords2(0);
02504 t1 = tI.getTexCoords2(1);
02505 t2 = tI.getTexCoords2(2);
02506 break;
02507 case 3:
02508 t0 = tI.getTexCoords3(0);
02509 t1 = tI.getTexCoords3(1);
02510 t2 = tI.getTexCoords3(2);
02511 break;
02512 case 4:
02513 t0 = tI.getTexCoords4(0);
02514 t1 = tI.getTexCoords4(1);
02515 t2 = tI.getTexCoords4(2);
02516 break;
02517 case 5:
02518 t0 = tI.getTexCoords5(0);
02519 t1 = tI.getTexCoords5(1);
02520 t2 = tI.getTexCoords5(2);
02521 break;
02522 case 6:
02523 t0 = tI.getTexCoords6(0);
02524 t1 = tI.getTexCoords6(1);
02525 t2 = tI.getTexCoords6(2);
02526 break;
02527 case 7:
02528 t0 = tI.getTexCoords7(0);
02529 t1 = tI.getTexCoords7(1);
02530 t2 = tI.getTexCoords7(2);
02531 break;
02532 }
02533
02534 edge1 = tI.getPosition(1) - tI.getPosition(0),
02535 edge2 = tI.getPosition(2) - tI.getPosition(0);
02536 tex1 = t1 - t0;
02537 tex2 = t2 - t0;
02538
02539
02540 Real32 invDet = (tex1[0]*tex2[1] - tex2[0]*tex1[1]);
02541 if(invDet != 0.0f)
02542 invDet = 1.0f / invDet;
02543 else
02544 invDet = 0.0f;
02545
02546 sdir = invDet * (tex2[1]*edge1 - tex1[1]*edge2);
02547 tdir = invDet * (tex1[0]*edge2 - tex2[0]*edge1);
02548
02549
02550 int tanOffset = (imsize == 0) ? 0 : imsize-1;
02551
02552 for (k=0; k<3; ++k)
02553 {
02554 tangent[v[k]] += sdir;
02555 binormal[v[k]] += tdir;
02556 normal[v[k]] = tI.getNormal(k);
02557 ip->setValue(v[k], tI.getIndexIndex(k) + tanOffset);
02558 }
02559 }
02560 endEditCP(ip);
02561
02562
02563 Vec3f T, B, N;
02564 Real32 sign = 0, l1, l2;
02565 tangentP->clear();
02566 binormalP->clear();
02567
02568 beginEditCP(tangentP);
02569 beginEditCP(binormalP);
02570
02571 for (i=0;i < tangent.size();++i)
02572 {
02573 T = tangent [i];
02574 B = binormal[i];
02575 N = normal [i];
02576
02577 sign = ((N.cross(T)).dot(B) < 0) ? -1 : 1;
02578
02579 T = T - N.dot(T) * N;
02580 T.normalize();
02581 B = B - N.dot(B) * N - T.dot(B) * T;
02582 B.normalize();
02583
02584 vect.setValues(T[0], T[1], T[2], sign);
02585 tangentP->getField().push_back(vect);
02586
02587 vect.setValues(B[0], B[1], B[2], sign);
02588 binormalP->getField().push_back(vect);
02589 }
02590
02591 endEditCP(tangentP);
02592 endEditCP(binormalP);
02593 }
02594
02595
02613 OSG_SYSTEMLIB_DLLMAPPING
02614 Int32 OSG::createOptimizedPrimitives(GeometryPtr geoPtr,
02615 UInt32 iteration,
02616 bool createStrips,
02617 bool createFans,
02618 UInt32 minFanEdgeCount,
02619 bool OSG_CHECK_ARG(colorCode),
02620 bool stitchStrips)
02621 {
02622 if (geoPtr == NullFC)
02623 {
02624 return 0;
02625 }
02626
02627 HalfEdgeGraph graph;
02628
02629 UInt32 cost = 0, startCost, bestCost = 0, worstCost = 0, best = 0;
02630
02631 GeoPLengthsPtr lensPtr;
02632 GeoPTypesPtr geoTypePtr;
02633 Time time, inputT, optimizeT, outputT;
02634
02635 IndexDic indexDic;
02636 int invalidTriCount = 0;
02637
02638 GeoPositionsPtr posPtr = geoPtr->getPositions();
02639 UInt32 pN = ((posPtr == OSG::NullFC) ? 0 : posPtr->getSize());
02640 UInt32 indexMapSize = (geoPtr->getIndexMapping().size());
02641 bool remapIndex = (indexMapSize > 1) ? true : false;
02642
02643 UInt32 triN, lineN, pointN;
02644 calcPrimitiveCount(geoPtr, triN, lineN, pointN);
02645
02646 GeoIndicesPtr indexPtr = geoPtr->getIndices();
02647
02648
02649 if(indexPtr == NullFC)
02650 startCost = pN;
02651 else
02652 {
02653 if(indexMapSize)
02654 {
02655 startCost = indexPtr->size() / indexMapSize;
02656 }
02657 else
02658 startCost = indexPtr->size();
02659 }
02660
02661
02662 if (pN == 0 || indexPtr == NullFC)
02663 {
02664 return 0;
02665 }
02666
02667 FDEBUG(("GeoOpt: start/tri cost: %d/%d imp: %d tri/line/point: %d/%d/%d\n",
02668 startCost, (triN * 3), indexMapSize, triN, lineN, pointN));
02669
02670 inputT = getSystemTime();
02671
02672 invalidTriCount = 0;
02673
02674 if (!remapIndex && (pN > (triN * 3)))
02675 {
02676 FINFO (( "Force index remap for unusual vertex/tri count: %d/%d\n",
02677 pN, triN ));
02678 indexMapSize = 1;
02679 remapIndex = true;
02680 }
02681
02682 if(remapIndex)
02683 {
02684 graph.reserve(triN * 3, triN, 8);
02685 std::vector < Int32 > indexVec(indexMapSize);
02686 UInt32 triCount = 0;
02687 for(TriangleIterator tI = geoPtr->beginTriangles(); (triCount < triN) && (tI != geoPtr->endTriangles());
02688 ++tI)
02689 {
02690 Int32 v[3];
02691 for(Int32 i = 0; i < 3; i++)
02692 {
02693 Int32 index = tI.getIndexIndex(i);
02694 for(Int32 j = 0; j < indexMapSize; j++)
02695 {
02696 indexVec[j] = indexPtr->getValue(index + j);
02697 }
02698
02699 v[i] = indexDic.entry(indexVec);
02700 }
02701
02702 invalidTriCount += graph.addTriangle(v[0], v[1], v[2]) ? 0 : 1;
02703 ++triCount;
02704 }
02705
02706 FDEBUG(("Multi-index dic entry: %d/%d\n", indexDic.entryCount(),
02707 (triN * 3)));
02708 }
02709 else
02710 {
02711 graph.reserve(osgMin(pN, triN * 3), triN, 8);
02712 UInt32 triCount = 0;
02713 for(TriangleIterator tI = geoPtr->beginTriangles(); (triCount < triN) && (tI != geoPtr->endTriangles());
02714 ++tI)
02715 {
02716 invalidTriCount += graph.addTriangle(tI.getPositionIndex(0),
02717 tI.getPositionIndex(1),
02718 tI.getPositionIndex(2)) ? 0 : 1;
02719 ++triCount;
02720 }
02721 }
02722
02723 if(invalidTriCount)
02724 {
02725 FNOTICE(("%d invalid tri during halfegde construction found\n",
02726 invalidTriCount));
02727 }
02728
02729 #ifdef OSG_DEBUG
02730 graph.verify();
02731 #endif
02732
02733 time = getSystemTime();
02734 inputT = time - inputT;
02735 optimizeT = time;
02736 bestCost = triN * 3 + 1;
02737 worstCost = 0;
02738 cost = graph.calcOptPrim(iteration, createStrips, createFans, minFanEdgeCount);
02739 if(cost)
02740 {
02741 if(cost < bestCost)
02742 bestCost = cost;
02743
02744 if(cost > worstCost)
02745 worstCost = cost;
02746 }
02747 else
02748 {
02749 bestCost = worstCost = 0;
02750 }
02751
02752
02753 if(bestCost && (bestCost < startCost))
02754 {
02755
02756 OSG::beginEditCP(geoPtr, OSG::Geometry::LengthsFieldMask |
02757 OSG::Geometry::TypesFieldMask);
02758
02759 lensPtr = geoPtr->getLengths();
02760 if(lensPtr == OSG::NullFC)
02761 {
02762 lensPtr = OSG::GeoPLengthsUI32::create();
02763 geoPtr->setLengths(lensPtr);
02764 }
02765
02766 geoTypePtr = geoPtr->getTypes();
02767 if(geoTypePtr == OSG::NullFC)
02768 {
02769 geoTypePtr = OSG::GeoPTypesUI8::create();
02770 geoPtr->setTypes(geoTypePtr);
02771 }
02772
02773 OSG::endEditCP(geoPtr, OSG::Geometry::LengthsFieldMask |
02774 OSG::Geometry::TypesFieldMask);
02775
02776 time = getSystemTime();
02777 optimizeT = time - optimizeT;
02778 outputT = time;
02779
02780 beginEditCP(lensPtr);
02781 beginEditCP(geoTypePtr);
02782 beginEditCP(indexPtr);
02783
02784 lensPtr->clear();
02785 geoTypePtr->clear();
02786 indexPtr->clear();
02787
02788 FDEBUG(("Start graph.getPrimitive() loop (triN: %d)\n", triN));
02789
02790 UInt32 numPrimitives = graph.primitiveCount();
02791 std::vector<std::vector<UInt32> > primIndex(numPrimitives);
02792
02793 const Int32 typeVec[] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN };
02794 const Int32 typeN = sizeof(typeVec) / sizeof(Int32);
02795
02796 cost = 0;
02797
02798 for(Int32 t = 0; t < typeN; ++t)
02799 {
02800 UInt32 triCount = 0;
02801
02802 bool stitch = false;
02803 UInt32 windingCorrection = 0;
02804 UInt32 lastTriStripIndex = 0;
02805 UInt32 totalTriStripLength = 0;
02806
02807 for(Int32 i = 0; i < Int32(numPrimitives); ++i)
02808 {
02809 graph.getPrimitive(primIndex[i], typeVec[t]);
02810 const Int32 n = primIndex[i].size();
02811 cost += n;
02812
02813 if(!n)
02814 {
02815 break;
02816 }
02817
02818 if(typeVec[t] == GL_TRIANGLES)
02819 {
02820 triCount += (n / 3);
02821 }
02822 else if (typeVec[t] == GL_TRIANGLE_STRIP)
02823 {
02824 if (stitchStrips)
02825 {
02826 if (stitch)
02827 {
02828
02829
02830 if (remapIndex)
02831 {
02832 for (int j = 0; j < 1 + windingCorrection; ++j)
02833 {
02834 for (int k = 0; k < indexMapSize; ++k)
02835 {
02836 indexPtr->push_back(indexDic.entry(lastTriStripIndex)[k]);
02837 }
02838 }
02839 for (int k = 0; k < indexMapSize; ++k)
02840 {
02841 indexPtr->push_back(indexDic.entry(primIndex[i][0])[k]);
02842 }
02843 }
02844 else
02845 {
02846 for (int j = 0; j < 1 + windingCorrection; ++j)
02847 {
02848 indexPtr->push_back(lastTriStripIndex);
02849 }
02850 indexPtr->push_back(primIndex[i][0]);
02851 }
02852 totalTriStripLength += 2 + windingCorrection;
02853 }
02854 stitch = true;
02855 windingCorrection = n % 2;
02856 lastTriStripIndex = primIndex[i][n - 1];
02857 }
02858 else
02859 {
02860 lensPtr->push_back(n);
02861 geoTypePtr->push_back(typeVec[t]);
02862 }
02863 }
02864 else
02865 {
02866 lensPtr->push_back(n);
02867 geoTypePtr->push_back(typeVec[t]);
02868 }
02869
02870 if(remapIndex)
02871 {
02872 for(Int32 j = 0; j < n; ++j)
02873 {
02874 for(Int32 k = 0; k < indexMapSize; ++k)
02875 {
02876 Int32 index = indexDic.entry(primIndex[i][j])[k];
02877 indexPtr->push_back(index);
02878 }
02879 }
02880 }
02881 else
02882 {
02883 for(Int32 j = 0; j < n; ++j)
02884 {
02885 indexPtr->push_back(primIndex[i][j]);
02886 }
02887 }
02888 totalTriStripLength += n;
02889 }
02890
02891 if(triCount && typeVec[t] == GL_TRIANGLES)
02892 {
02893 lensPtr->push_back(triCount * 3);
02894 geoTypePtr->push_back(GL_TRIANGLES);
02895 }
02896
02897 if(stitchStrips && totalTriStripLength &&
02898 typeVec[t] == GL_TRIANGLE_STRIP)
02899 {
02900 lensPtr->push_back(totalTriStripLength);
02901 geoTypePtr->push_back(GL_TRIANGLE_STRIP);
02902 }
02903 }
02904
02905 endEditCP(lensPtr);
02906 endEditCP(geoTypePtr);
02907 endEditCP(indexPtr);
02908
02909 time = getSystemTime();
02910 outputT = time - outputT;
02911
02912 FNOTICE(("Graph in/opt/out timing: %g/%g/%g \n", inputT, optimizeT,
02913 outputT));
02914
02915 if(cost != bestCost)
02916 {
02917 FWARNING(("cost != bestCost: %d/%d; we lost some nodes !\n",
02918 cost, bestCost));
02919 }
02920 else
02921 {
02922 FINFO(("OptResult: %2g%%, Sampling (%di): cost %d/%d \n",
02923 double(double(bestCost) / double(
02924 startCost) * 100.0
02925 ), iteration, bestCost, worstCost));
02926 }
02927 }
02928 else
02929 {
02930 FINFO(("startCost (%d) <= bestCost (%d), triCost(%d); keep geo data\n",
02931 startCost, bestCost, (triN * 3)));
02932 }
02933
02934 return bestCost;
02935 }
02936
02937
02938
02939
02940
02941 void OSG_APIENTRY gluTessEdgeFlagCB(GLboolean )
02942 {
02943
02944 FDEBUG(("gluEdgeVertexCB called\n"));
02945 }
02946
02947
02948
02949 void OSG_APIENTRY gluTessVertexDataCB(UInt32 *curIndexPtr,
02950 std::vector<UInt32> *indexV)
02951 {
02952 if(indexV != NULL)
02953 {
02954 FDEBUG(("gluVertexDataCB called: indexV@%p->push_back(%d)\n",
02955 indexV, *curIndexPtr));
02956 indexV->push_back(*curIndexPtr);
02957 }
02958 else
02959 {
02960 FDEBUG(("Null Pointer in gluTessVertexDataCB\n"));
02961 }
02962 }
02963
02964
02965 void OSG_APIENTRY gluTessBeginDataCB(GLenum type, std::vector<UInt32> *indexV)
02966 {
02967 if(indexV != NULL)
02968 {
02969 FDEBUG(("gluTessBeginDataCB: Beginning new Polygon\n"));
02970 FDEBUG(("gluTessBeginDataCB: Type is %d\n", type));
02971 FDEBUG(("gluTessBeginDataCB: indexV* is 0x%p\n", indexV));
02972 }
02973 else
02974 {
02975 FDEBUG(("Null Pointer in gluTessVertexDataCB\n"));
02976 }
02977 }
02978
02979
02980 void OSG_APIENTRY gluTessEndCB()
02981 {
02982 FDEBUG(("gluTessEndCB called\n"));
02983 }
02984
02985
02986 void OSG_APIENTRY gluTessErrorCB(GLenum errNo)
02987 {
02988 FWARNING(("gluTesselator Error: %s\n", gluErrorString(errNo)));
02989 }
02990
03004 OSG_SYSTEMLIB_DLLMAPPING
03005 void OSG::createConvexPrimitives(GeometryPtr geoPtr)
03006 {
03007 FINFO(("Entering createConvexPrimitives()\n"));
03008
03009 GLenum windingRule = GLU_TESS_WINDING_ODD;
03010
03011 OSG::GeoIndicesUI32Ptr indexPtr;
03012 OSG::GeoIndicesUI32Ptr newIndexPtr = GeoIndicesUI32::create();
03013 OSG::GeoPTypesPtr newTypesPtr = GeoPTypesUI8::create();
03014 OSG::GeoPLengthsPtr newLengthsPtr = GeoPLengthsUI32::create();
03015
03016 bool indexed = true;
03017
03018 std::vector< UInt32 > inIndexV;
03019 std::vector< UInt32 > outIndexV;
03020 std::vector< GLdouble > positionV;
03021
03022 inIndexV.reserve(4096);
03023 outIndexV.reserve(4096);
03024 positionV.reserve(4096);
03025
03026 if(geoPtr == NullFC)
03027 {
03028 FINFO(("Invalid geoPtr in createConvexPrimitives()\n"));
03029 return;
03030 }
03031
03032
03033 bool containsPolygon = false;
03034 PrimitiveIterator primI = geoPtr->beginPrimitives();
03035 for(;primI != geoPtr->endPrimitives(); ++primI)
03036 {
03037 if(primI.getType() == GL_POLYGON)
03038 {
03039 containsPolygon = true;
03040 break;
03041 }
03042 }
03043
03044
03045 if(!containsPolygon)
03046 {
03047 FINFO(("Geometry with no GL_POLYGONs in createConvexPrimitives:\n"));
03048 FINFO(("Nothing to do for createConvexPrimitives: Returning\n"));
03049 return;
03050 }
03051
03052
03053 indexPtr = GeoIndicesUI32Ptr::dcast(geoPtr->getIndices());
03054 indexed = (indexPtr == NullFC) ? false : true;
03055 FDEBUG(("Indexed: %d\n",indexed));
03056
03057
03058 if(!indexed)
03059 {
03060 FINFO(("Skipping nonindexed geometry in createConvexPrimitives()\n"));
03061 return;
03062 }
03063 else
03064 {
03065 if(geoPtr->getIndices()->size() == 0)
03066 {
03067 FINFO(("Skipping empty geometry in createConvexPrimitives()\n"));
03068 return;
03069 }
03070 }
03071
03072
03073 OSGGLUfuncptr gluTessBeginDataCBPtr =
03074 reinterpret_cast<OSGGLUfuncptr>(gluTessBeginDataCB);
03075
03076 OSGGLUfuncptr gluTessEdgeFlagCBPtr =
03077 reinterpret_cast<OSGGLUfuncptr>(gluTessEdgeFlagCB);
03078
03079 OSGGLUfuncptr gluTessVertexDataCBPtr =
03080 reinterpret_cast<OSGGLUfuncptr>(gluTessVertexDataCB);
03081
03082 OSGGLUfuncptr gluTessEndCBPtr =
03083 reinterpret_cast<OSGGLUfuncptr>(gluTessEndCB);
03084
03085 OSGGLUfuncptr gluTessErrorCBPtr =
03086 reinterpret_cast<OSGGLUfuncptr>(gluTessErrorCB);
03087
03088
03089 FDEBUG(("gluNewTess()\n"));
03090 GLUtesselator* tess = gluNewTess();
03091
03092 if(tess == NULL)
03093 {
03094 FFATAL(("Creation of GLUtesselator failed\n"));
03095 return;
03096 }
03097 else
03098 FINFO(("Created GLU Tesselator (%p)\n", tess));
03099
03100
03101 FDEBUG(("gluTessProperty(%p, GLU_TESS_WINDING_RULE, %d)\n",
03102 tess, windingRule));
03103 gluTessProperty(tess, GLU_TESS_WINDING_RULE, windingRule);
03104
03105
03106 FDEBUG(("gluTessCallback(%p, GLU_TESS_ERROR, %p)\n",
03107 tess, gluTessErrorCBPtr));
03108 gluTessCallback(tess, GLU_TESS_ERROR, gluTessErrorCBPtr);
03109
03110 FDEBUG(("gluTessCallback(%p, GLU_TESS_BEGIN_DATA, %p)\n",
03111 tess, gluTessBeginDataCBPtr));
03112 gluTessCallback(tess, GLU_TESS_BEGIN_DATA, gluTessBeginDataCBPtr);
03113
03114 FDEBUG(("gluTessCallback(%p, GLU_TESS_EDGE_FLAG, %p)\n",
03115 tess, gluTessEdgeFlagCBPtr));
03116 gluTessCallback(tess, GLU_TESS_EDGE_FLAG, gluTessEdgeFlagCBPtr);
03117
03118 FDEBUG(("gluTessCallback(%p, GLU_TESS_VERTEX_DATA, %p)\n",
03119 tess, gluTessVertexDataCBPtr));
03120 gluTessCallback(tess, GLU_TESS_VERTEX_DATA, gluTessVertexDataCBPtr);
03121
03122 FDEBUG(("gluTessCallback(%p, GLU_TESS_END, %p)\n",
03123 tess, gluTessEndCBPtr));
03124 gluTessCallback(tess, GLU_TESS_END, gluTessEndCBPtr);
03125
03126 beginEditCP(newTypesPtr);
03127 beginEditCP(newIndexPtr);
03128 beginEditCP(newLengthsPtr);
03129
03130 primI = geoPtr->beginPrimitives();
03131 for(;primI != geoPtr->endPrimitives(); ++primI)
03132 {
03133 FDEBUG(("Primitive index: %d\n", primI.getIndex()));
03134
03135
03136 if(primI.getType() != GL_POLYGON)
03137 {
03138 FDEBUG(("Not a GL_POLYGON. Copying properties\n"));
03139 if(!indexed)
03140 {
03141 FWARNING(("createConvexPrimitives(): Nonindexed geometries are not implemented!\n"));
03142 }
03143 else
03144 {
03145 newTypesPtr->push_back(primI.getType());
03146
03147
03148
03149 for(UInt32 i = 0; i < primI.getLength(); i++)
03150 {
03151 Int32 curIndex = primI.getIndexIndex(i);
03152 for(UInt32 j = 0; j < geoPtr->getIndexMapping().size(); j++)
03153 {
03154 UInt32 val = indexPtr->getValue(curIndex + j);
03155 newIndexPtr->push_back(val);
03156 }
03157 }
03158 newLengthsPtr->push_back(primI.getLength());
03159 }
03160 }
03161
03162 else
03163 {
03164 FDEBUG(("Tesselating GL_POLYGON (PrimitiveIndex: %d, Vertices %d)\n",
03165 primI.getIndex(), primI.getLength()));
03166
03167 inIndexV.clear();
03168 outIndexV.clear();
03169 positionV.clear();
03170
03171 for(UInt32 i = 0; i < primI.getLength(); i++)
03172 {
03173
03174
03175 positionV.push_back(static_cast< GLdouble >(primI.
03176 getPosition(i)[0]));
03177 positionV.push_back(static_cast< GLdouble >(primI.
03178 getPosition(i)[1]));
03179 positionV.push_back(static_cast< GLdouble >(primI.
03180 getPosition(i)[2]));
03181
03182
03183
03184 UInt32 curIndex = indexed ? primI.getIndexIndex(i) : i;
03185 inIndexV.push_back(curIndex);
03186 }
03187
03188 #ifdef OSG_DEBUG
03189
03190 for(UInt32 i = 0; i < primI.getLength(); i++)
03191 {
03192
03193 int index = inIndexV.at(i);
03194 double x = positionV.at(3*i);
03195 double y = positionV.at(3*i + 1);
03196 double z = positionV.at(3*i + 2);
03197
03198 FDEBUG(("Position index: %i Position: (%f,%f,%f)\n",
03199 index, x, y, z));
03200 }
03201 #endif
03202
03203
03204
03205 GLvoid* outIndexPtr = reinterpret_cast< GLvoid* >(&outIndexV);
03206
03207 FDEBUG(("gluTessBeginPolygon(%p, %p)\n", tess, outIndexPtr));
03208 gluTessBeginPolygon(tess, outIndexPtr);
03209
03210 FDEBUG(("gluTessBeginContour(%p)\n", tess));
03211 gluTessBeginContour(tess);
03212
03213
03214 for(UInt32 i = 0; i < primI.getLength(); i++)
03215 {
03216 GLvoid* curIndexPtr = reinterpret_cast< GLvoid* >(&inIndexV[i]);
03217 FDEBUG(("gluTessVertex(%p, %p, %p)\n",
03218 tess, &positionV[i * 3], curIndexPtr));
03219
03220
03221
03222 gluTessVertex(tess, &positionV[i * 3], curIndexPtr);
03223 }
03224
03225 FDEBUG(("gluTessEndContour(%p)\n", tess));
03226 gluTessEndContour(tess);
03227
03228 FDEBUG(("gluTessEndPolygon(%p)\n", tess));
03229
03230 gluTessEndPolygon(tess);
03231
03232 newTypesPtr->push_back(GL_TRIANGLES);
03233
03234 if(!indexed)
03235 {
03236 FWARNING(("createConvexPrimitives(): Nonindexed geometries are not implemented!\n"));
03237 }
03238 else
03239 {
03240 FDEBUG(("Rebuilding multi indices ...\n"));
03241
03242
03243 for(UInt32 i = 0; i < outIndexV.size(); i++)
03244 {
03245 UInt32 vII = outIndexV[i];
03246 for(UInt32 j = 0; j < geoPtr->getIndexMapping().size(); j++)
03247 {
03248 FDEBUG(("Index in tesselated data %d\n",vII + j));
03249 Int32 curIndex = indexPtr->getValue(vII + j);
03250
03251 FDEBUG(("newIndexPtr->push_back(%d)\n", curIndex));
03252 newIndexPtr->push_back(curIndex);
03253 }
03254 }
03255 }
03256 FINFO(("Vertex count: %d/%d (before/after tesselation)\n",
03257 primI.getLength(), outIndexV.size()));
03258 newLengthsPtr->push_back(outIndexV.size());
03259 }
03260 }
03261
03262 endEditCP(newTypesPtr);
03263 endEditCP(newIndexPtr);
03264 endEditCP(newLengthsPtr);
03265
03266 beginEditCP(geoPtr);
03267
03268
03269 geoPtr->setTypes(newTypesPtr);
03270 geoPtr->setIndices(newIndexPtr);
03271 geoPtr->setLengths(newLengthsPtr);
03272
03273 endEditCP(geoPtr);
03274
03275 FDEBUG(("gluDeleteTess(%p)\n", tess));
03276 gluDeleteTess(tess);
03277
03278 FDEBUG(("Exiting from createConvexPrimitives()\n"));
03279 }
03280
03288 OSG_SYSTEMLIB_DLLMAPPING Int32 OSG::createSharedIndex(GeometryPtr geoPtr)
03289 {
03290 #ifndef OSG_SUPPORT_NO_GEO_INTERFACE
03291 UInt32 indexSharedCount = 0, dataRemapCount = 0, indexRemapCount = 0;
03292 UInt32 i, iN, index, si, sN;
03293 UInt32 indexMapSize, indexBlock = 0, masterDSize;
03294 GeoPropertyArrayInterface *masterProp = 0, *slaveProp = 0;
03295 UInt8 *masterData;
03296 std::vector < UInt32 > slaveDSizeVec;
03297 std::vector < UInt8 * > slaveDataVec;
03298
03299 UInt16 mapMask, propMask, masterPropMask;
03300 typedef std::pair<UInt8 *, UInt32> Mem;
03301 Mem mem;
03302 std::map<Mem, UInt32, memless<Mem> > memMap;
03303 std::map<Mem, UInt32, memless<Mem> >::iterator mmI;
03304
03305 GeoIndicesPtr indexPtr;
03306 UChar8 *dataElem;
03307 std::vector < Int32 > indexRemap;
03308
03309 if(geoPtr != NullFC)
03310 {
03311 if(geoPtr->getPositions() != NullFC)
03312 {
03313
03314 iN = geoPtr->getPositions()->size();
03315 indexPtr = geoPtr->getIndices();
03316 if(indexPtr == NullFC)
03317 {
03318 indexPtr = GeoIndicesUI32::create();
03319 indexPtr->resize(iN);
03320 for(i = 0; i < iN; i++)
03321 indexPtr->setValue(i, i);
03322 beginEditCP(geoPtr);
03323 {
03324 geoPtr->setIndices(indexPtr);
03325 }
03326
03327 endEditCP(geoPtr);
03328 }
03329 }
03330 else
03331 {
03332 FNOTICE(("Invalid geoPtr->getPositions() in createSharedIndex()\n"));
03333 }
03334 }
03335 else
03336 {
03337 FNOTICE(("Invalid geoPtr in createSharedIndex()\n"));
03338 }
03339
03340 if(indexPtr != NullFC)
03341 {
03342
03343 indexMapSize = geoPtr->getIndexMapping().size();
03344
03345
03346 if(indexMapSize)
03347 {
03348 propMask = geoPtr->getIndexMapping()[0];
03349 }
03350 else
03351 {
03352
03353 for(mapMask = 1, propMask = 0; mapMask && mapMask != Geometry::MapEmpty;
03354 mapMask <<= 1)
03355 {
03356 if(geoPtr->getProperty(mapMask))
03357 propMask |= mapMask;
03358 }
03359
03360 indexMapSize = 1;
03361 }
03362
03363
03364 for(indexBlock = 0; propMask;)
03365 {
03366
03367 indexSharedCount = 0;
03368 dataRemapCount = 0;
03369 indexRemapCount = 0;
03370
03371
03372 for(masterPropMask = 1; (propMask & masterPropMask) == 0;)
03373 masterPropMask <<= 1;
03374
03375 if((masterProp = geoPtr->getProperty(masterPropMask)) &&
03376 (masterData = masterProp->getData()))
03377 {
03378
03379 masterDSize = masterProp->getFormatSize() *
03380 masterProp->getDimension() +
03381 masterProp->getStride();
03382
03383
03384 slaveDataVec.clear();
03385 slaveDSizeVec.clear();
03386 for(mapMask = 1; mapMask && mapMask != Geometry::MapEmpty;
03387 mapMask <<= 1)
03388 {
03389 if((mapMask != masterPropMask) && (mapMask & propMask))
03390 {
03391 if((slaveProp = geoPtr->getProperty(mapMask & propMask)))
03392 {
03393 slaveDataVec.push_back(slaveProp->getData());
03394 slaveDSizeVec.push_back(slaveProp->getFormatSize() *
03395 slaveProp->getDimension());
03396 }
03397 else
03398 {
03399 FWARNING(("Invalid slaveProp %d\n", (mapMask & propMask)
03400 ));
03401 }
03402 }
03403 }
03404
03405 sN = slaveDataVec.size();
03406 iN = indexPtr->size() / indexMapSize;
03407 memMap.clear();
03408 indexRemap.clear();
03409 indexRemap.resize(masterProp->size(), -1);
03410 mem.second = masterProp->getFormatSize() * masterProp->getDimension();
03411
03412 for(i = 0; i < iN; i++)
03413 {
03414 index = indexPtr->getValue(i * indexMapSize + indexBlock);
03415 if(indexRemap[index] >= 0)
03416 {
03417 if(indexRemap[index] == index)
03418 {
03419 indexSharedCount++;
03420 }
03421 else
03422 {
03423 indexPtr->setValue(indexRemap[index],
03424 i * indexMapSize + indexBlock);
03425 indexRemapCount++;
03426 }
03427 }
03428 else
03429 {
03430
03431 dataElem = masterData + (index * masterDSize);
03432 mem.first = dataElem;
03433 mmI = memMap.find(mem);
03434 if(mmI == memMap.end())
03435 {
03436
03437 memMap[mem] = index;
03438 indexRemap[index] = index;
03439 }
03440 else
03441 {
03442
03443 for(si = 0; si < sN; si++)
03444 {
03445 if(memcmp(slaveDataVec[si] +
03446 (index * slaveDSizeVec[si]),
03447 slaveDataVec[si] +
03448 (mmI->second * slaveDSizeVec[si]),
03449 slaveDSizeVec[si]))
03450 break;
03451 }
03452
03453 if(si == sN)
03454 {
03455
03456 indexPtr->setValue(mmI->second,
03457 i * indexMapSize + indexBlock);
03458 indexRemap[index] = mmI->second;
03459 dataRemapCount++;
03460 }
03461 else
03462 {
03463
03464 indexRemap[index] = index;
03465 }
03466 }
03467 }
03468 }
03469 }
03470 else
03471 {
03472 FWARNING(("Invalid masterProp %p, mask: %d, block: %d\n",
03473 masterProp, propMask, indexBlock));
03474 }
03475
03476 FINFO(("Create sharedIndex: %d/%d pass; "
03477 "data/index remap: %d/%d \n",
03478 indexBlock, int(propMask), dataRemapCount,
03479 indexRemapCount));
03480
03481
03482 if(++indexBlock < indexMapSize)
03483 {
03484 propMask = geoPtr->getIndexMapping()[indexBlock];
03485 }
03486 else
03487 propMask = 0;
03488 }
03489 }
03490
03491 return indexRemapCount + dataRemapCount;
03492
03493 #else
03494 FFATAL(("Cannot run createSharedIndex: NO_GEO_INFACE\n"));
03495 return -1;
03496 #endif
03497 }
03498
03508 OSG_SYSTEMLIB_DLLMAPPING Int32 OSG::createSingleIndex(GeometryPtr geoPtr)
03509 {
03510 #ifndef OSG_SUPPORT_NO_GEO_INTERFACE
03511 Int16 mask, maskID, finalMask = 0;
03512 Int32 indexMapSize, indexCount, i, j, vCount = 0;
03513 Int32 index;
03514 Int32 memSize, valueSize;
03515 UInt8 *pData, *data;
03516 GeoIndicesPtr indexPtr;
03517 IndexDic indexDic;
03518 std::vector < Int32 >
03519
03520 indexVec, sIndex;
03521 GeoPropertyArrayInterface *pP = 0;
03522
03523 if((geoPtr != NullFC) &&
03524 (indexMapSize = (geoPtr->getIndexMapping().size())))
03525 {
03526 beginEditCP(geoPtr, Geometry::IndexMappingFieldMask |
03527 Geometry::IndicesFieldMask);
03528
03529 indexPtr = geoPtr->getIndices();
03530 indexVec.resize(indexMapSize);
03531
03532
03533 if(indexPtr != NullFC)
03534 {
03535 indexCount = indexPtr->size() / indexMapSize;
03536 sIndex.resize(indexCount);
03537 for(i = 0; i < indexCount; i++)
03538 {
03539 for(j = 0; j < indexMapSize; j++)
03540 {
03541 indexVec[j] = indexPtr->getValue(i * indexMapSize + j);
03542 }
03543
03544 sIndex[i] = indexDic.entry(indexVec);
03545 }
03546
03547 vCount = indexDic.entryCount();
03548 }
03549 else
03550 vCount = 0;
03551
03552
03553 finalMask = 0;
03554 if(vCount)
03555 {
03556 for(i = 0; i < indexMapSize; i++)
03557 {
03558 mask = geoPtr->getIndexMapping()[i];
03559 for(maskID = 1; maskID; maskID <<= 1)
03560 {
03561 if((mask & maskID) && (pP = geoPtr->getProperty(maskID)))
03562 {
03563 valueSize = pP->getFormatSize() *
03564 pP->getDimension() +
03565 pP->getStride();
03566 finalMask |= maskID;
03567 memSize = pP->size() * valueSize;
03568 data = new UInt8[memSize];
03569 pData = pP->getData();
03570 memcpy(data, pData, memSize);
03571 pP->resize(vCount);
03572 pData = pP->getData();
03573 for(j = 0; j < vCount; j++)
03574 {
03575 index = indexDic.entry(j)[i];
03576 memcpy(pData + (valueSize * j),
03577 data + (valueSize * index),
03578 valueSize);
03579 }
03580
03581 delete[] data;
03582 }
03583 }
03584 }
03585 }
03586
03587
03588 if(finalMask)
03589 {
03590 indexPtr->clear();
03591 for(i = 0; i < indexCount; i++)
03592 {
03593 indexPtr->push_back(sIndex[i]);
03594 }
03595
03596 geoPtr->getIndexMapping().clear();
03597 geoPtr->getIndexMapping().push_back(finalMask);
03598 }
03599 else
03600 {
03601 FWARNING(("No valid finalMask in createSingleIndex()\n"));
03602 }
03603
03604 endEditCP(geoPtr, Geometry::IndexMappingFieldMask |
03605 Geometry::IndicesFieldMask);
03606 }
03607
03608 return vCount;
03609
03610 #else
03611 FFATAL(("Cannot run createSingleIndex: NO_GEO_INFACE\n"));
03612 return -1;
03613 #endif
03614 }
03615
03616
03626 OSG_SYSTEMLIB_DLLMAPPING UInt32 OSG::calcPrimitiveCount(GeometryPtr geoPtr,
03627 UInt32 &triangle,
03628 UInt32 &line,
03629 UInt32 &point)
03630 {
03631 GeoPTypesUI8Ptr geoTypePtr;
03632 GeoPLengthsUI32Ptr lens32Ptr;
03633 GeoPLengthsUI16Ptr lens16Ptr;
03634 GeoPTypesUI8Ptr::StoredObjectType::StoredFieldType::iterator typeI, endTypeI;
03635 GeoPLengthsUI32Ptr::StoredObjectType::StoredFieldType::iterator len32I;
03636 GeoPLengthsUI16Ptr::StoredObjectType::StoredFieldType::iterator len16I;
03637
03638 UInt32 lN, tN, len, type;
03639
03640
03641 triangle = line = point = 0;
03642
03643 if(geoPtr == OSG::NullFC)
03644 {
03645 FINFO(("No geo in calcPrimitiveCount\n"));
03646 }
03647 else
03648 {
03649 lens32Ptr = GeoPLengthsUI32Ptr::dcast(geoPtr->getLengths());
03650
03651 if(lens32Ptr == NullFC)
03652 {
03653 lens16Ptr = GeoPLengthsUI16Ptr::dcast(geoPtr->getLengths());
03654 lN = (lens16Ptr == OSG::NullFC) ? 0 : lens16Ptr->getSize();
03655 }
03656 else
03657 {
03658 lN = (lens32Ptr == OSG::NullFC) ? 0 : lens32Ptr->getSize();
03659 }
03660
03661 geoTypePtr = GeoPTypesUI8Ptr::dcast(geoPtr->getTypes());
03662 tN = (geoTypePtr == OSG::NullFC) ? 0 : geoTypePtr->getSize();
03663
03664 if((tN == 0) || (lN != 0 && tN != lN) || (lN == 0 && tN != 1))
03665 {
03666 return 0;
03667 }
03668
03669 typeI = geoTypePtr->getField().begin();
03670 if(lN != 0)
03671 {
03672 if(lens32Ptr != NullFC)
03673 len32I = lens32Ptr->getField().begin();
03674 else
03675 len16I = lens16Ptr->getField().begin();
03676 }
03677
03678 endTypeI = geoTypePtr->getField().end();
03679 while(typeI != endTypeI)
03680 {
03681 type = *typeI;
03682 if(lN != 0)
03683 {
03684 if(lens32Ptr != NullFC)
03685 len = *len32I;
03686 else
03687 len = *len16I;
03688 }
03689 else
03690 {
03691 GeoPositionsPtr pos = geoPtr->getPositions();
03692
03693 if(pos == OSG::NullFC)
03694 {
03695 FINFO(("calcPrimitiveCount: no Points!\n"));
03696 return 0;
03697 }
03698
03699 len = pos->size();
03700 }
03701
03702 switch(type)
03703 {
03704 case GL_POINTS:
03705 point += len;
03706 break;
03707 case GL_LINES:
03708 line += len / 2;
03709 break;
03710 case GL_LINE_LOOP:
03711 line += len;
03712 break;
03713 case GL_LINE_STRIP:
03714 line += len - 1;
03715 break;
03716 case GL_TRIANGLES:
03717 triangle += len / 3;
03718 break;
03719 case GL_TRIANGLE_STRIP:
03720 triangle += len - 2;
03721 break;
03722 case GL_TRIANGLE_FAN:
03723 triangle += len - 2;
03724 break;
03725 case GL_QUADS:
03726 triangle += len / 2;
03727 break;
03728 case GL_QUAD_STRIP:
03729 triangle += len - 2;
03730 break;
03731 case GL_POLYGON:
03732 triangle += len - 2;
03733 break;
03734 default:
03735 FWARNING(("calcPrimitiveCount(): Invalid geoType: %d\n", type));
03736 break;
03737 }
03738
03739 ++typeI;
03740 if (lN > 0)
03741 {
03742 if(lens32Ptr != NullFC)
03743 ++len32I;
03744 else if(lens16Ptr != NullFC)
03745 ++len16I;
03746 }
03747 }
03748 }
03749
03750 return triangle + line + point;
03751 }
03752
03753
03754
03765 OSG_SYSTEMLIB_DLLMAPPING
03766 NodePtr OSG::calcVertexNormalsGeo(GeometryPtr geo, Real32 length)
03767 {
03768 GeoPositions3f::PtrType pnts = GeoPositions3f::create();
03769
03770 beginEditCP(pnts);
03771
03772 PrimitiveIterator pi(geo);
03773
03774 if(1 )
03775 {
03776 for(pi = geo->beginPrimitives(); pi != geo->endPrimitives(); ++pi)
03777 {
03778 for(UInt32 k = 0; k < pi.getLength(); k++)
03779 {
03780 pnts->push_back(pi.getPosition(k));
03781 pnts->push_back(pi.getPosition(k) + length * pi.getNormal(k));
03782 }
03783 }
03784 }
03785 else
03786 {
03787 Pnt3f center(0, 0, 0);
03788
03789 for(pi = geo->beginPrimitives(); pi != geo->endPrimitives(); ++pi)
03790 {
03791 for(UInt32 k = 0; k < pi.getLength(); k++)
03792 {
03793 center[0] += pi.getPosition(k)[0];
03794 center[1] += pi.getPosition(k)[1];
03795 center[2] += pi.getPosition(k)[2];
03796 }
03797
03798 pnts->push_back(center);
03799 pnts->push_back(center + length * pi.getNormal(0));
03800 }
03801 }
03802
03803 endEditCP(pnts);
03804
03805 GeoPTypesPtr type = GeoPTypesUI8::create();
03806 beginEditCP(type);
03807 type->push_back(GL_LINES);
03808 endEditCP(type);
03809
03810 GeoPLengthsPtr lens = GeoPLengthsUI32::create();
03811 beginEditCP(lens);
03812 lens->push_back(pnts->getSize());
03813 endEditCP(lens);
03814
03815 GeometryPtr g = Geometry::create();
03816 beginEditCP(g);
03817 g->setTypes(type);
03818 g->setLengths(lens);
03819 g->setPositions(pnts);
03820 endEditCP(g);
03821
03822 return makeNodeFor(g);
03823 }
03824
03825 #ifdef __sgi
03826 #pragma reset woff 1209
03827 #endif
03828
03839 OSG_SYSTEMLIB_DLLMAPPING
03840 NodePtr OSG::calcFaceNormalsGeo(GeometryPtr geo, Real32 length)
03841 {
03842 NodePtr p = Node::create();
03843 GeometryPtr g = Geometry::create();
03844 GeoPositions3f::PtrType pnts = GeoPositions3f::create();
03845 GeoIndicesUI32Ptr index = GeoIndicesUI32::create();
03846 GeoPTypesPtr type = GeoPTypesUI8::create();
03847 GeoPLengthsPtr lens = GeoPLengthsUI32::create();
03848
03849
03850 FaceIterator faceIter = geo->beginFaces();
03851 Pnt3f center;
03852
03853 beginEditCP(pnts);
03854 for(; faceIter != geo->endFaces(); ++faceIter)
03855 {
03856 center[0] = 0;
03857 center[1] = 0;
03858 center[2] = 0;
03859 for(UInt16 i = 0; i < faceIter.getLength(); ++i)
03860 {
03861 center[0] += faceIter.getPosition(i)[0] / faceIter.getLength();
03862 center[1] += faceIter.getPosition(i)[1] / faceIter.getLength();
03863 center[2] += faceIter.getPosition(i)[2] / faceIter.getLength();
03864 }
03865
03866 pnts->push_back(center);
03867 switch(faceIter.getType())
03868 {
03869 case GL_TRIANGLE_STRIP:
03870 pnts->push_back(center + length * faceIter.getNormal(2));
03871 break;
03872 case GL_TRIANGLE_FAN:
03873 pnts->push_back(center + length * faceIter.getNormal(2));
03874 break;
03875 case GL_QUAD_STRIP:
03876 pnts->push_back(center + length * faceIter.getNormal(3));
03877 break;
03878 default:
03879
03880 pnts->push_back(center + length * faceIter.getNormal(0));
03881 break;
03882 }
03883 }
03884
03885 endEditCP(pnts);
03886
03887 beginEditCP(index);
03888 for(UInt32 i = 0; i < pnts->getSize(); i++)
03889 index->push_back(i);
03890 endEditCP(index);
03891
03892 beginEditCP(type);
03893 type->push_back(GL_LINES);
03894 endEditCP(type);
03895
03896 beginEditCP(lens);
03897 lens->push_back(index->getSize());
03898 endEditCP(lens);
03899
03900 beginEditCP(g);
03901 g->setTypes(type);
03902 g->setLengths(lens);
03903 g->setIndices(index);
03904 g->setPositions(pnts);
03905 endEditCP(g);
03906
03907 beginEditCP(p);
03908 p->setCore(g);
03909 endEditCP(p);
03910
03911 return p;
03912 }
03913
03914
03915
03916 #if !defined(OSG_DO_DOC)
03917 OSG_SYSTEMLIB_DLLMAPPING void OSG::mergeGeometries(std::vector<NodePtr> &nodes,
03918 std::vector<NodePtr> &results)
03919 {
03920 FFATAL(("Merge Geometries: Not implemented yet!\n"));
03921 results.clear();
03922
03923 for(std::vector < NodePtr >::iterator n = nodes.begin(); n != nodes.end();
03924 ++n)
03925 {
03926 GeometryPtr actnode = GeometryPtr::dcast((*n)->getCore());
03927
03928 if(actnode == NullFC)
03929 {
03930 FWARNING(("mergeGeometries: core of 0x%p is not a geometry!\n", n->
03931 getCPtr()));
03932 continue;
03933 }
03934
03935 std::vector < NodePtr >::iterator r;
03936 for(r = nodes.begin(); r != nodes.end(); ++r)
03937 {
03938 GeometryPtr res = GeometryPtr::dcast((*r)->getCore());
03939
03940 if(res->isMergeable(actnode))
03941 {
03942 res->merge(actnode);
03943 }
03944 }
03945
03946 if(r == nodes.end())
03947 {
03948
03949 NodePtr node = Node::create();
03950
03951 beginEditCP(node);
03952 node->setCore(actnode->clone());
03953 endEditCP(node);
03954
03955 results.push_back(node);
03956 }
03957 }
03958 }
03959 #endif
03960
03961 #define separateProperty(TypeT, Type) \
03962 Geo ## TypeT ## Ptr Type = geo->get ## Type (); \
03963 if(Type != NullFC && Type->getParents().size() > 1) \
03964 { \
03965 beginEditCP(geo, Geometry :: Type ## FieldMask); \
03966 geo->set ## Type (Geo ## TypeT ## Ptr::dcast(OSG::deepClone(Type))); \
03967 endEditCP(geo, Geometry :: Type ## FieldMask); \
03968 }
03969
03975 OSG_SYSTEMLIB_DLLMAPPING void OSG::separateProperties(GeometryPtr geo)
03976 {
03977 separateProperty(PTypes, Types)
03978 separateProperty(PLengths, Lengths)
03979 separateProperty(Positions, Positions)
03980 separateProperty(Normals, Normals)
03981 separateProperty(Colors, Colors)
03982 separateProperty(Colors, SecondaryColors)
03983 separateProperty(TexCoords, TexCoords)
03984 separateProperty(TexCoords, TexCoords1)
03985 separateProperty(TexCoords, TexCoords2)
03986 separateProperty(TexCoords, TexCoords3)
03987 separateProperty(TexCoords, TexCoords4)
03988 separateProperty(TexCoords, TexCoords5)
03989 separateProperty(TexCoords, TexCoords6)
03990 separateProperty(TexCoords, TexCoords7)
03991 separateProperty(Indices, Indices)
03992 }