OSGVRMLWriteAction.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGLog.h"
00049 #include "OSGFieldContainer.h"
00050 #include "OSGNode.h"
00051 #include "OSGNodeCore.h"
00052 #include "OSGGroup.h"
00053 #include "OSGGeometry.h"
00054 #include "OSGTriangleIterator.h"
00055 #include "OSGComponentTransform.h"
00056 //#include "OSGGeoPropPtrs.h"
00057 #include "OSGSimpleMaterial.h"
00058 #include "OSGMaterialGroup.h"
00059 #include "OSGAction.h"
00060 #include "OSGVRMLWriteAction.h"
00061 #include "OSGNameAttachment.h"
00062 #include "OSGTextureObjChunk.h"
00063 #include "OSGImage.h"
00064 #include "OSGImageFileHandler.h"
00065 #include "OSGSimpleGeometry.h"
00066 #include "OSGSceneFileHandler.h"
00067
00068 #include "OSGGL.h"
00069
00070 #include "functional"
00071
00072 OSG_USING_NAMESPACE
00073
00074
00075 /***************************************************************************\
00076  *                            Description                                  *
00077 \***************************************************************************/
00078
00086 /***************************************************************************\
00087  *                               Types                                     *
00088 \***************************************************************************/
00089
00090 VRMLWriteAction::ActionInitializer::ActionInitializer(void)
00091 {
00092     addPostFactoryInitFunction(&VRMLWriteAction::initializeAction);
00093     addPreFactoryExitFunction (&VRMLWriteAction::terminateAction );
00094 }
00095
00096 VRMLWriteAction::ActionInitializer::~ActionInitializer(void)
00097 {
00098 }
00099
00100 VRMLWriteAction::FCInfo::FCInfo(void) :
00101     _iTimesUsed(0     ),
00102     _bOwnName   (false),
00103     _szName     (NULL ),
00104     _bWritten    (false)
00105 {
00106 }
00107
00108 VRMLWriteAction::FCInfo::FCInfo(const FCInfo &source) :
00109     _iTimesUsed(source._iTimesUsed),
00110     _bOwnName  (source._bOwnName  ),
00111     _szName    (NULL              ),
00112     _bWritten   (source._bWritten   )
00113 {
00114     if(_bOwnName == true)
00115     {
00116         osgStringDup(source._szName, _szName);
00117     }
00118 }
00119
00120 VRMLWriteAction::FCInfo::~FCInfo(void)
00121 {
00122     if(_bOwnName == true)
00123         delete [] _szName;
00124 }
00125
00126 Char8 VRMLWriteAction::FCInfo::mapChar(Char8 c)
00127 {
00128     // These are taken from the VRML97 reference document
00129     static char badchars[] = {
00130         0x22, 0x23, 0x27, 0x2c, 0x2e, 0x5b, 0x5c, 0x5d, 0x7b, 0x7d, 0x7f
00131     };
00132
00133     if (c <= 0x20) return '_';
00134
00135     for(UInt16 i = 0; i < sizeof(badchars); ++i)
00136         if(c == badchars[i])
00137             return '_';
00138
00139     return c;
00140 }
00141
00142 void VRMLWriteAction::FCInfo::convertName(Char8 *&szName)
00143 {
00144     if(szName == NULL)
00145         return;
00146
00147     for(UInt32 i = 0; i < strlen(szName); i++)
00148     {
00149         szName[i] = mapChar(szName[i]);
00150     }
00151
00152     // first char a number a plus or a minus? add an _
00153     if((szName[0] >= 0x30 && szName[0] <= 0x39) ||
00154         szName[0] == 0x2b || szName[0] == 0x2d)
00155     {
00156         Char8 *newstring = new char [strlen(szName) + 2];
00157
00158         newstring[0] = '_';
00159         strcpy(newstring + 1, szName);
00160         delete[] szName;
00161         szName = newstring;
00162     }
00163 }
00164
00165 void VRMLWriteAction::FCInfo::setName(const Char8 *szName)
00166 {
00167     osgStringDup(szName, _szName);
00168     convertName(_szName);
00169     _bOwnName = true;
00170 }
00171
00172 void VRMLWriteAction::FCInfo::buildName(const Char8  *szTypename,
00173                                               UInt32  uiContainerId)
00174 {
00175     if(_szName != NULL)
00176         return;
00177
00178     if(szTypename != NULL)
00179     {
00180         _szName = new Char8[strlen(szTypename) + 32];
00181
00182         sprintf(_szName, "%s_%u", szTypename, uiContainerId);
00183     }
00184     else
00185     {
00186         _szName = new Char8[64];
00187
00188         sprintf(_szName, "UType_%u", uiContainerId);
00189     }
00190
00191     _bOwnName = true;
00192 }
00193
00194 void VRMLWriteAction::FCInfo::incUse(void)
00195 {
00196     _iTimesUsed++;
00197 }
00198
00199 UInt32 VRMLWriteAction::FCInfo::getUse(void) const
00200 {
00201     return _iTimesUsed;
00202 }
00203
00204 const Char8 *VRMLWriteAction::FCInfo::getName(void) const
00205 {
00206     return _szName;
00207 }
00208
00209 bool VRMLWriteAction::FCInfo::getWritten(void) const
00210 {
00211     return _bWritten;
00212 }
00213
00214 void VRMLWriteAction::FCInfo::setWritten(void)
00215 {
00216     _bWritten = true;
00217 }
00218
00219 Int32 VRMLWriteAction::FCInfo::clear(void)
00220 {
00221     _iTimesUsed = 0;
00222
00223     if(_bOwnName == true)
00224     {
00225         delete [] _szName;
00226     }
00227
00228     _bOwnName = false;
00229     _szName   = NULL;
00230     _bWritten  = false;
00231
00232     return 0;
00233 }
00234
00235 /***************************************************************************\
00236  *                           Class variables                               *
00237 \***************************************************************************/
00238
00239 VRMLWriteAction * VRMLWriteAction::_prototype = NULL;
00240
00241 std::vector<Action::Functor> *VRMLWriteAction::_defaultEnterFunctors;
00242 std::vector<Action::Functor> *VRMLWriteAction::_defaultLeaveFunctors;
00243
00244 VRMLWriteAction::ActionInitializer VRMLWriteAction::_actionInitializer;
00245
00246
00247 /***************************************************************************\
00248  *                           Class methods                                 *
00249 \***************************************************************************/
00250
00251
00252
00253 /*-------------------------------------------------------------------------*\
00254  -  public                                                                 -
00255 \*-------------------------------------------------------------------------*/
00256
00257 void VRMLWriteAction::registerEnterDefault(const FieldContainerType &type,
00258                                            const Action::Functor    &func)
00259 {
00260     if(_defaultEnterFunctors == NULL)
00261         _defaultEnterFunctors = new std::vector<Action::Functor>;
00262
00263     while(type.getId() >= _defaultEnterFunctors->size())
00264     {
00265         _defaultEnterFunctors->push_back(&Action::_defaultEnterFunction);
00266     }
00267
00268     (*_defaultEnterFunctors)[type.getId()] = func;
00269 }
00270
00271 void VRMLWriteAction::registerLeaveDefault(const FieldContainerType &type,
00272                                            const Action::Functor    &func)
00273 {
00274     if(_defaultLeaveFunctors == NULL)
00275         _defaultLeaveFunctors = new std::vector<Action::Functor>;
00276
00277     while(type.getId() >= _defaultLeaveFunctors->size())
00278     {
00279         _defaultLeaveFunctors->push_back(&Action::_defaultLeaveFunction);
00280     }
00281
00282     (*_defaultLeaveFunctors)[type.getId()] = func;
00283 }
00284
00285 void VRMLWriteAction::setPrototype(VRMLWriteAction *proto)
00286 {
00287     _prototype = proto;
00288 }
00289
00290 VRMLWriteAction *VRMLWriteAction::getPrototype( void )
00291 {
00292     return _prototype;
00293 }
00294
00295 /*-------------------------------------------------------------------------*\
00296  -  protected                                                              -
00297 \*-------------------------------------------------------------------------*/
00298
00299
00300 /*-------------------------------------------------------------------------*\
00301  -  private                                                                -
00302 \*-------------------------------------------------------------------------*/
00303
00304 ActionBase::ResultE VRMLWriteAction::writeGroupEnter(NodeCore * const ,
00305                                                      Action   *pAction)
00306 {
00307     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00308
00309     Node *pNode = pAction->getActNode();
00310
00311     if(pWriter == NULL)
00312     {
00313         return Action::Quit;
00314     }
00315
00316     FDEBUG(("Write Group Enter 0x%04x\n", pWriter->getMode()));
00317
00318     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00319     {
00320         pWriter->addNodeUse(pNode);
00321     }
00322     else
00323     {
00324         FILE *pFile = pWriter->getFilePtr();
00325
00326         if(pFile == NULL)
00327         {
00328             return Action::Quit;
00329         }
00330
00331         pWriter->updateProgress();
00332
00333         NodeCore *pCore = pNode->getCore();
00334
00335         FCInfo *pInfo     = pWriter->getInfo(pNode);
00336         FCInfo *pCoreInfo = pWriter->getInfo(pCore);
00337
00338         if(pInfo == NULL || pCoreInfo == NULL)
00339         {
00340             FWARNING(("Info missing %p %p\n", pInfo, pCoreInfo));
00341             return Action::Quit;
00342         }
00343
00344         if(pCoreInfo->getUse()    >  0 &&
00345            pCoreInfo->getWritten() == true)
00346         {
00347             pWriter->printIndent();
00348             fprintf(pFile, "Group # osg shared %s\n", pCoreInfo->getName());
00349
00350 //            pWriter->setCurrentUse(true);
00351         }
00352         else if((pCoreInfo->getName()    != NULL) &&
00353                (pCoreInfo->getName()[0] != '\0'))
00354         {
00355             pWriter->printIndent();
00356             fprintf(pFile, "DEF %s Group\n", pCoreInfo->getName());
00357
00358             pCoreInfo->setWritten();
00359         }
00360         else if((pInfo->getName()    != NULL) &&
00361                 (pInfo->getName()[0] != '\0'))
00362         {
00363             pWriter->printIndent();
00364             fprintf(pFile, "DEF %s Group\n", pInfo->getName());
00365
00366             pInfo->setWritten();
00367         }
00368         else
00369         {
00370             pWriter->printIndent();
00371             fprintf(pFile, "Group\n");
00372         }
00373
00374         pWriter->printIndent();
00375         fprintf(pFile, "{\n");
00376
00377         if(pNode->getNChildren() != 0)
00378         {
00379             pWriter->incIndent(4);
00380
00381             pWriter->printIndent();
00382             fprintf(pFile, "children [\n");
00383
00384             pWriter->incIndent(4);
00385         }
00386     }
00387
00388     return Action::Continue;
00389 }
00390
00391 Action::ResultE VRMLWriteAction::writeGroupLeave(NodeCore * const ,
00392                                                  Action   *pAction)
00393 {
00394     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00395
00396     Node *pNode = pAction->getActNode();
00397
00398     if(pWriter == NULL)
00399     {
00400         return Action::Quit;
00401     }
00402
00403     FDEBUG(("Write Group Leave 0x%04x\n", pWriter->getMode()));
00404
00405     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00406     {
00407         FILE *pFile = pWriter->getFilePtr();
00408
00409         if(pFile == NULL)
00410         {
00411             return Action::Quit;
00412         }
00413
00414         if(pWriter->isCurrentUse() == false)
00415         {
00416             if(pNode->getNChildren() != 0)
00417             {
00418                 pWriter->decIndent(4);
00419
00420                 pWriter->printIndent();
00421                 fprintf(pFile, "]\n");
00422
00423                 pWriter->decIndent(4);
00424             }
00425
00426             pWriter->printIndent();
00427             fprintf(pFile, "}\n");
00428         }
00429
00430         pWriter->setCurrentUse(false);
00431     }
00432
00433     return Action::Continue;
00434 }
00435
00436 Action::ResultE VRMLWriteAction::writeComponentTransformEnter(NodeCore * const,
00437                                                               Action   *pAction)
00438 {
00439     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00440     Node *pNode = pAction->getActNode();
00441     ComponentTransform *pTrans =
00442         dynamic_cast<ComponentTransform *>(pNode->getCore());
00443
00444     Real32 rQX;
00445     Real32 rQY;
00446     Real32 rQZ;
00447     Real32 rQW;
00448
00449     if(pWriter == NULL)
00450     {
00451         return Action::Quit;
00452     }
00453
00454     FDEBUG(("Write ComponentTransform Enter 0x%04x\n", pWriter->getMode()));
00455
00456     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00457     {
00458         pWriter->addNodeUse(pNode);
00459     }
00460     else
00461     {
00462         FILE *pFile = pWriter->getFilePtr();
00463
00464         if(pFile == NULL)
00465         {
00466             return Action::Quit;
00467         }
00468
00469         pWriter->updateProgress();
00470
00471         FCInfo *pInfo = pWriter->getInfo(pNode);
00472
00473         if(pInfo == NULL)
00474         {
00475             return Action::Quit;
00476         }
00477
00478         if((pInfo->getName() != NULL   ) &&
00479            (pInfo->getWritten() == false) &&
00480            (pInfo->getName()[0] != '\0'))
00481         {
00482             pWriter->printIndent();
00483             fprintf(pFile, "DEF %s Transform\n", pInfo->getName());
00484
00485             pInfo->setWritten();
00486         }
00487         else
00488         {
00489             pWriter->printIndent();
00490             fprintf(pFile, "Transform\n");
00491         }
00492
00493         pWriter->printIndent();
00494         fprintf(pFile, "{\n");
00495
00496         pWriter->incIndent(4);
00497
00498         pWriter->printIndent();
00499         fprintf(pFile, "center %f %f %f\n",
00500                 pTrans->getCenter()[0],
00501                 pTrans->getCenter()[1],
00502                 pTrans->getCenter()[2]);
00503
00504         pTrans->getRotation().getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00505
00506         pWriter->printIndent();
00507         fprintf(pFile, "rotation %f %f %f %f\n",
00508                 rQX, rQY, rQZ, rQW);
00509
00510         pWriter->printIndent();
00511         fprintf(pFile, "scale %f %f %f\n",
00512                 pTrans->getScale()[0],
00513                 pTrans->getScale()[1],
00514                 pTrans->getScale()[2]);
00515
00516         pTrans->getScaleOrientation().getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00517
00518         pWriter->printIndent();
00519         fprintf(pFile, "scaleOrientation %f %f %f %f\n",
00520                 rQX, rQY, rQZ, rQW);
00521
00522         pWriter->printIndent();
00523         fprintf(pFile, "translation %f %f %f\n",
00524                 pTrans->getTranslation()[0],
00525                 pTrans->getTranslation()[1],
00526                 pTrans->getTranslation()[2]);
00527
00528         pWriter->printIndent();
00529         fprintf(pFile, "children [\n");
00530
00531         pWriter->incIndent(4);
00532     }
00533
00534     return Action::Continue;
00535 }
00536
00537 Action::ResultE VRMLWriteAction::writeComponentTransformLeave(NodeCore * const,
00538                                                               Action *pAction)
00539 {
00540     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00541
00542     if(pWriter == NULL)
00543     {
00544         return Action::Quit;
00545     }
00546
00547     FDEBUG(("Write ComponentTransform Leave 0x%04x\n", pWriter->getMode()));
00548
00549     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00550     {
00551         FILE *pFile = pWriter->getFilePtr();
00552
00553         if(pFile == NULL)
00554         {
00555             return Action::Quit;
00556         }
00557
00558         pWriter->decIndent(4);
00559
00560         pWriter->printIndent();
00561         fprintf(pFile, "]\n");
00562
00563         pWriter->decIndent(4);
00564
00565         pWriter->printIndent();
00566         fprintf(pFile, "}\n");
00567     }
00568
00569     return Action::Continue;
00570 }
00571
00572 Action::ResultE VRMLWriteAction::writeTransformEnter(NodeCore * const ,
00573                                                      Action *pAction)
00574 {
00575     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00576     Node *pNode = pAction->getActNode();
00577     Transform *pTrans = dynamic_cast<Transform *>(pNode->getCore());
00578
00579     Real32 rQX;
00580     Real32 rQY;
00581     Real32 rQZ;
00582     Real32 rQW;
00583
00584     if(pWriter == NULL)
00585     {
00586         return Action::Quit;
00587     }
00588
00589     FDEBUG(("Write Transform Enter 0x%04x\n", pWriter->getMode()));
00590
00591     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00592     {
00593         pWriter->addNodeUse(pNode);
00594     }
00595     else
00596     {
00597         FILE *pFile = pWriter->getFilePtr();
00598
00599         if(pFile == NULL)
00600         {
00601             return Action::Quit;
00602         }
00603
00604         pWriter->updateProgress();
00605
00606         FCInfo *pInfo = pWriter->getInfo(pNode);
00607
00608         if(pInfo == NULL)
00609         {
00610             return Action::Quit;
00611         }
00612
00613         if((pInfo->getName() != NULL   ) &&
00614            (pInfo->getWritten() == false) &&
00615            (pInfo->getName()[0] != '\0'))
00616         {
00617             pWriter->printIndent();
00618             fprintf(pFile, "DEF %s Transform\n", pInfo->getName());
00619
00620             pInfo->setWritten();
00621         }
00622         else
00623         {
00624             pWriter->printIndent();
00625             fprintf(pFile, "Transform\n");
00626         }
00627
00628         pWriter->printIndent();
00629         fprintf(pFile, "{\n");
00630
00631         pWriter->incIndent(4);
00632
00633         // decompose matrix.
00634         Matrix m = pTrans->getSFMatrix()->getValue();
00635         Vec3f translation, scale, center;
00636         Quaternion rotation, scaleOrientation;
00637         m.getTransform(translation, rotation, scale, scaleOrientation);
00638
00639         pWriter->printIndent();
00640         fprintf(pFile, "center %f %f %f\n",
00641                 center[0],
00642                 center[1],
00643                 center[2]);
00644
00645         rotation.getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00646
00647         pWriter->printIndent();
00648         fprintf(pFile, "rotation %f %f %f %f\n",
00649                 rQX, rQY, rQZ, rQW);
00650
00651         pWriter->printIndent();
00652         fprintf(pFile, "scale %f %f %f\n",
00653                 scale[0],
00654                 scale[1],
00655                 scale[2]);
00656
00657         scaleOrientation.getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00658
00659         pWriter->printIndent();
00660         fprintf(pFile, "scaleOrientation %f %f %f %f\n",
00661                 rQX, rQY, rQZ, rQW);
00662
00663         pWriter->printIndent();
00664         fprintf(pFile, "translation %f %f %f\n",
00665                 translation[0],
00666                 translation[1],
00667                 translation[2]);
00668
00669         pWriter->printIndent();
00670         fprintf(pFile, "children [\n");
00671
00672         pWriter->incIndent(4);
00673     }
00674
00675     return Action::Continue;
00676 }
00677
00678 Action::ResultE VRMLWriteAction::writeTransformLeave(NodeCore * const ,
00679                                                      Action *pAction)
00680 {
00681     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00682
00683     if(pWriter == NULL)
00684     {
00685         return Action::Quit;
00686     }
00687
00688     FDEBUG(("Write Transform Leave 0x%04x\n", pWriter->getMode()));
00689
00690     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00691     {
00692         FILE *pFile = pWriter->getFilePtr();
00693
00694         if(pFile == NULL)
00695         {
00696             return Action::Quit;
00697         }
00698
00699         pWriter->decIndent(4);
00700
00701         pWriter->printIndent();
00702         fprintf(pFile, "]\n");
00703
00704         pWriter->decIndent(4);
00705
00706         pWriter->printIndent();
00707         fprintf(pFile, "}\n");
00708     }
00709
00710     return Action::Continue;
00711 }
00712
00713 void VRMLWriteAction::writePoints(Geometry        *pGeo,
00714                                   FILE            *pFile,
00715                                   VRMLWriteAction *pWriter)
00716 {
00717     if(pGeo == NULL)
00718         return;
00719
00720     GeoVectorProperty *pPos = pGeo->getPositions();
00721
00722     if(pPos == NULL)
00723         return;
00724
00725     pWriter->printIndent();
00726     fprintf(pFile, "coord Coordinate\n");
00727
00728     pWriter->printIndent();
00729     fprintf(pFile, "{\n");
00730     pWriter->incIndent(4);
00731
00732     pWriter->printIndent();
00733     fprintf(pFile, "point [\n");
00734     pWriter->incIndent(4);
00735
00736     for(UInt32 i = 0; i < pPos->getSize(); i++)
00737     {
00738         pWriter->printIndent();
00739
00740         Pnt3f p;
00741         pPos->getValue(p,i);
00742
00743         fprintf(pFile, "%f %f %f", p[0], p[1], p[2]);
00744
00745         if(i == pPos->getSize() - 1)
00746         {
00747             fprintf(pFile, "\n");
00748         }
00749         else
00750         {
00751             fprintf(pFile, ", \n");
00752         }
00753     }
00754
00755     pWriter->decIndent(4);
00756     pWriter->printIndent();
00757     fprintf(pFile, "]\n");
00758
00759     pWriter->decIndent(4);
00760     pWriter->printIndent();
00761     fprintf(pFile, "}\n");
00762
00763 }
00764
00765 void VRMLWriteAction::writeNormals(Geometry        *pGeo,
00766                                    FILE            *pFile,
00767                                    VRMLWriteAction *pWriter)
00768 {
00769     if(0 != (pWriter->getOptions() & VRMLWriteAction::OSGNoNormals))
00770         return;
00771
00772     if(pGeo == NULL)
00773         return;
00774
00775     GeoVectorProperty *pNorm = pGeo->getNormals();
00776
00777     if(pNorm == NULL)
00778         return;
00779
00780     pWriter->printIndent();
00781     fprintf(pFile, "normal Normal\n");
00782
00783     pWriter->printIndent();
00784     fprintf(pFile, "{\n");
00785     pWriter->incIndent(4);
00786
00787     pWriter->printIndent();
00788     fprintf(pFile, "vector [\n");
00789     pWriter->incIndent(4);
00790
00791     for(UInt32 i = 0; i < pNorm->getSize(); i++)
00792     {
00793         pWriter->printIndent();
00794
00795         Vec3f n;
00796         pNorm->getValue(n,i);
00797
00798         fprintf(pFile, "%f %f %f", n[0], n[1], n[2]);
00799
00800         if(i == pNorm->getSize() - 1)
00801         {
00802             fprintf(pFile, "\n");
00803         }
00804         else
00805         {
00806             fprintf(pFile, ", \n");
00807         }
00808     }
00809
00810     pWriter->decIndent(4);
00811     pWriter->printIndent();
00812     fprintf(pFile, "]\n");
00813
00814     pWriter->decIndent(4);
00815     pWriter->printIndent();
00816     fprintf(pFile, "}\n");
00817 }
00818
00819 void VRMLWriteAction::writeColors(Geometry        *pGeo,
00820                                   FILE            *pFile,
00821                                   VRMLWriteAction *pWriter)
00822 {
00823     if(pGeo == NULL)
00824         return;
00825
00826     GeoVectorProperty *pCol = pGeo->getColors();
00827
00828     if(pCol == NULL)
00829         return;
00830
00831     pWriter->printIndent();
00832     fprintf(pFile, "color Color\n");
00833
00834     pWriter->printIndent();
00835     fprintf(pFile, "{\n");
00836     pWriter->incIndent(4);
00837
00838     pWriter->printIndent();
00839     fprintf(pFile, "color [\n");
00840     pWriter->incIndent(4);
00841
00842     for(UInt32 i = 0; i < pCol->getSize(); i++)
00843     {
00844         pWriter->printIndent();
00845
00846         Color3f c;
00847         pCol->getValue(c,i);
00848
00849         fprintf(pFile, "%f %f %f", c[0], c[1], c[2]);
00850
00851         if(i == pCol->getSize() - 1)
00852         {
00853             fprintf(pFile, "\n");
00854         }
00855         else
00856         {
00857             fprintf(pFile, ", \n");
00858         }
00859     }
00860
00861     pWriter->decIndent(4);
00862     pWriter->printIndent();
00863     fprintf(pFile, "]\n");
00864
00865     pWriter->decIndent(4);
00866     pWriter->printIndent();
00867     fprintf(pFile, "}\n");
00868 }
00869
00870 void VRMLWriteAction::writeTexCoords(Geometry        *pGeo,
00871                                      FILE            *pFile,
00872                                      VRMLWriteAction *pWriter)
00873 {
00874     if(pGeo == NULL)
00875         return;
00876
00877     GeoVectorProperty *pTex = pGeo->getTexCoords();
00878
00879     if(pTex == NULL)
00880         return;
00881
00882     pWriter->printIndent();
00883     fprintf(pFile, "texCoord TextureCoordinate\n");
00884
00885     pWriter->printIndent();
00886     fprintf(pFile, "{\n");
00887     pWriter->incIndent(4);
00888
00889     pWriter->printIndent();
00890     fprintf(pFile, "point [\n");
00891     pWriter->incIndent(4);
00892
00893     for(UInt32 i = 0; i < pTex->getSize(); i++)
00894     {
00895         pWriter->printIndent();
00896
00897         Vec2f t;
00898         pTex->getValue(t,i);
00899
00900         fprintf(pFile, "%f %f", t[0], t[1]);
00901
00902         if(i == pTex->getSize() - 1)
00903         {
00904             fprintf(pFile, "\n");
00905         }
00906         else
00907         {
00908             fprintf(pFile, ", \n");
00909         }
00910     }
00911
00912     pWriter->decIndent(4);
00913     pWriter->printIndent();
00914     fprintf(pFile, "]\n");
00915
00916     pWriter->decIndent(4);
00917     pWriter->printIndent();
00918     fprintf(pFile, "}\n");
00919 }
00920
00921 void VRMLWriteAction::writeIndex(Geometry        *pGeo,
00922                                  FILE            *pFile,
00923                                  VRMLWriteAction *pWriter)
00924 {
00925     if(pGeo == NULL)
00926         return;
00927
00928     GeoIntegralProperty *pIndex  = pGeo->getIndices();
00929     GeoIntegralProperty *pTypes  = pGeo->getTypes  ();
00930     GeoIntegralProperty *pLength = pGeo->getLengths();
00931
00932     if((pIndex  == NULL) ||
00933        (pTypes  == NULL) ||
00934        (pLength == NULL))
00935     {
00936         return;
00937     }
00938
00939     if(pIndex->size() == 0 ||
00940        pTypes->size() == 0 ||
00941        pLength->size() == 0)
00942     {
00943         return;
00944     }
00945
00946     pWriter->printIndent();
00947     fprintf(pFile, "coordIndex [\n");
00948     pWriter->incIndent(4);
00949
00950     TriangleIterator it;
00951
00952     for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
00953     {
00954         pWriter->printIndent();
00955
00956         for(UInt32 i = 0; i < 3; ++i)
00957         {
00958             fprintf(pFile, "%d, ", it.getPositionIndex(i));
00959         }
00960 /*
00961         fprintf(pFile, "%d,%d,%d,", it.getPositionIndex(0), 
00962                                     it.getPositionIndex(1), 
00963                                     it.getPositionIndex(2));
00964         if(it.getPositionIndex(3) != -1)
00965             fprintf(pFile, "%d,", it.getPositionIndex(3));
00966             */
00967
00968         fprintf(pFile, "-1,\n");
00969     }
00970
00971     pWriter->decIndent(4);
00972     pWriter->printIndent();
00973     fprintf(pFile, "]\n");
00974
00975     if(pGeo->getNormals()           != NULL   &&
00976        pGeo->getNormals()->getSize() > 0      &&
00977        0 == (pWriter->getOptions() & VRMLWriteAction::OSGNoNormals))
00978     {
00979         pWriter->printIndent();
00980         fprintf(pFile, "normalIndex [\n");
00981         pWriter->incIndent(4);
00982
00983         TriangleIterator it;
00984
00985         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
00986         {
00987             pWriter->printIndent();
00988
00989             for(UInt32 i = 0; i < 3; ++i)
00990             {
00991                 fprintf(pFile, "%d, ", it.getNormalIndex(i));
00992             }
00993
00994 /*
00995             fprintf(pFile, "%d,%d,%d,", it.getNormalIndex(0), 
00996                                         it.getNormalIndex(1), 
00997                                         it.getNormalIndex(2));
00998             if(it.getNormalIndex(3) != -1)
00999                 fprintf(pFile, "%d,", it.getNormalIndex(3));
01000                 */
01001
01002             fprintf(pFile, "-1,\n");
01003         }
01004
01005         pWriter->decIndent(4);
01006         pWriter->printIndent();
01007         fprintf(pFile, "]\n");
01008     }
01009
01010     if(pGeo->getColors() != NULL && pGeo->getColors()->getSize() > 0)
01011     {
01012         pWriter->printIndent();
01013         fprintf(pFile, "colorIndex [\n");
01014         pWriter->incIndent(4);
01015
01016         TriangleIterator it;
01017
01018         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
01019         {
01020             pWriter->printIndent();
01021
01022             for(UInt32 i = 0; i < 3; ++i)
01023             {
01024                 fprintf(pFile, " %d,", it.getColorIndex(i));
01025             }
01026 /*
01027             fprintf(pFile, "%d,%d,%d,", it.getColorIndex(0), 
01028                                         it.getColorIndex(1), 
01029                                         it.getColorIndex(2));
01030             if(it.getColorIndex(3) != -1)
01031                 fprintf(pFile, "%d,", it.getColorIndex(3));
01032                 */
01033
01034             fprintf(pFile, "-1,\n");
01035         }
01036
01037         pWriter->decIndent(4);
01038         pWriter->printIndent();
01039         fprintf(pFile, "]\n");
01040     }
01041
01042     if(pGeo->getTexCoords() != NULL && pGeo->getTexCoords()->getSize() > 0)
01043     {
01044         pWriter->printIndent();
01045         fprintf(pFile, "texCoordIndex [\n");
01046         pWriter->incIndent(4);
01047
01048         TriangleIterator it;
01049
01050         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
01051         {
01052             pWriter->printIndent();
01053
01054             for(UInt32 i = 0; i < 3; ++i)
01055             {
01056                 fprintf(pFile, "%d,", it.getTexCoordsIndex(i));
01057             }
01058 /*
01059             fprintf(pFile, "%d,%d,%d,", it.getTexCoordsIndex(0), 
01060                                         it.getTexCoordsIndex(1), 
01061                                         it.getTexCoordsIndex(2));
01062             if(it.getTexCoordsIndex(3) != -1)
01063                 fprintf(pFile, "%d,", it.getTexCoordsIndex(3));
01064                 */
01065
01066             fprintf(pFile, "-1,\n");
01067         }
01068
01069         pWriter->decIndent(4);
01070         pWriter->printIndent();
01071         fprintf(pFile, "]\n");
01072     }
01073 }
01074
01075 void VRMLWriteAction::writeLineIndex(Geometry        *pGeo,
01076                                      FILE            *pFile,
01077                                      VRMLWriteAction *pWriter)
01078 {
01079     if(pGeo == NULL)
01080         return;
01081
01082     GeoIntegralProperty *pTypes  = pGeo->getTypes();
01083     GeoIntegralProperty *pLength = pGeo->getLengths();
01084
01085     if((pTypes  == NULL) ||
01086        (pLength == NULL))
01087     {
01088         return;
01089     }
01090
01091     if(pTypes->size() == 0 ||
01092        pLength->size() == 0)
01093     {
01094         return;
01095     }
01096
01097     pWriter->printIndent();
01098     fprintf(pFile, "coordIndex [\n");
01099     pWriter->incIndent(4);
01100
01101     PrimitiveIterator it;
01102     UInt32            i;
01103
01104     for(it = pGeo->beginPrimitives(); it != pGeo->endPrimitives(); ++it)
01105     {
01106         if(it.getType() == GL_LINES)
01107         {
01108             for(i = 0; i < it.getLength(); i += 2)
01109             {
01110                 pWriter->printIndent();
01111
01112                 fprintf(pFile, "%d, %d, -1,\n",
01113                         it.getPositionIndex(i),
01114                         it.getPositionIndex(i + 1));
01115             }
01116         }
01117         else if(it.getType() == GL_LINE_STRIP)
01118         {
01119             pWriter->printIndent();
01120
01121             for(i = 0; i < it.getLength(); ++i)
01122             {
01123                 fprintf(pFile, "%d, ", it.getPositionIndex(i));
01124             }
01125
01126             fprintf(pFile, "-1,\n");
01127         }
01128         else if(it.getType() == GL_LINE_LOOP)
01129         {
01130             pWriter->printIndent();
01131
01132             for(i = 0; i < it.getLength(); ++i)
01133             {
01134                 fprintf(pFile, "%d, ", it.getPositionIndex(i));
01135             }
01136
01137             fprintf(pFile, "%d, -1, \n", it.getPositionIndex(i - 1));
01138         }
01139     }
01140
01141     pWriter->decIndent(4);
01142     pWriter->printIndent();
01143     fprintf(pFile, "]\n");
01144
01145
01146     if(pGeo->getColors() != NULL && pGeo->getColors()->getSize() > 0)
01147     {
01148         pWriter->printIndent();
01149         fprintf(pFile, "colorIndex [\n");
01150         pWriter->incIndent(4);
01151
01152         PrimitiveIterator it;
01153         UInt32            i;
01154
01155         for(it = pGeo->beginPrimitives(); it != pGeo->endPrimitives(); ++it)
01156         {
01157             if(it.getType() == GL_LINES)
01158             {
01159                 for(i = 0; i < it.getLength(); i += 2)
01160                 {
01161                     pWriter->printIndent();
01162
01163                     fprintf(pFile, "%d, %d, -1,\n",
01164                             it.getColorIndex(i),
01165                             it.getColorIndex(i + 1));
01166                 }
01167             }
01168             else if(it.getType() == GL_LINE_STRIP)
01169             {
01170                 pWriter->printIndent();
01171
01172                 for(i = 0; i < it.getLength(); ++i)
01173                 {
01174                     fprintf(pFile, "%d, ", it.getColorIndex(i));
01175                 }
01176
01177                 fprintf(pFile, "-1,\n");
01178             }
01179             else if(it.getType() == GL_LINE_LOOP)
01180             {
01181                 pWriter->printIndent();
01182
01183                 for(i = 0; i < it.getLength(); ++i)
01184                 {
01185                     fprintf(pFile, "%d, ", it.getColorIndex(i));
01186                 }
01187
01188                 fprintf(pFile, "%d, -1, \n", it.getColorIndex(i - 1));
01189             }
01190         }
01191
01192         pWriter->decIndent(4);
01193         pWriter->printIndent();
01194         fprintf(pFile, "]\n");
01195     }
01196 }
01197
01198 void VRMLWriteAction::writeMaterial(Geometry        *pGeo,
01199                                     FILE            *pFile,
01200                                     VRMLWriteAction *pWriter)
01201 {
01202     if(pGeo == NULL)
01203         return;
01204
01205     Material *pMat;
01206
01207     pMat = pWriter->getMaterial();
01208
01209     if(pMat == NULL)
01210         pMat = pGeo->getMaterial();
01211
01212     if(pMat == NULL)
01213         pMat = OSG::getDefaultMaterial();
01214
01215     if(pWriter->isWritten(pMat))
01216     {
01217         pWriter->printIndent();
01218         fprintf(pFile, "appearance USE App_%u\n", pWriter->getIndex(pMat));
01219         return;
01220     }
01221
01222     PrimeMaterial *pPrimeMat = pMat->finalize(0x0000);
01223
01224     pPrimeMat->rebuildState();
01225     State *st = pPrimeMat->getState();
01226
01227     StateChunk *sChunk =
01228         st->getChunk(MaterialChunk::getStaticClassId());
01229
01230     if(sChunk == NULL)
01231         return;
01232
01233     MaterialChunk *mChunk = dynamic_cast<MaterialChunk *>(sChunk);
01234
01235     if(mChunk == NULL)
01236         return;
01237
01238     pWriter->printIndent();
01239     fprintf(pFile, "appearance DEF App_%u Appearance\n",
01240             pWriter->setWritten(pMat));
01241
01242     pWriter->printIndent();
01243     fprintf(pFile, "{\n");
01244
01245     pWriter->incIndent(4);
01246
01247     pWriter->printIndent();
01248     fprintf(pFile, "material Material\n");
01249
01250     pWriter->printIndent();
01251     fprintf(pFile, "{\n");
01252
01253     pWriter->incIndent(4);
01254
01255     Real32 rAmbient = 0.f;
01256
01257     if(osgAbs(mChunk->getDiffuse()[0]) > Eps)
01258     {
01259         rAmbient = mChunk->getAmbient()[0] / mChunk->getDiffuse()[0];
01260     }
01261     else if(osgAbs(mChunk->getDiffuse()[1]) > Eps)
01262     {
01263         rAmbient = mChunk->getAmbient()[1] / mChunk->getDiffuse()[1];
01264     }
01265     else if(osgAbs(mChunk->getDiffuse()[2]) > Eps)
01266     {
01267         rAmbient = mChunk->getAmbient()[2] / mChunk->getDiffuse()[2];
01268     }
01269
01270
01271     pWriter->printIndent();
01272     fprintf(pFile, "ambientIntensity %f\n", rAmbient);
01273
01274     pWriter->printIndent();
01275     fprintf(pFile, "diffuseColor %f %f %f\n",
01276             mChunk->getDiffuse()[0],
01277             mChunk->getDiffuse()[1],
01278             mChunk->getDiffuse()[2]);
01279
01280     pWriter->printIndent();
01281     if(!mChunk->getLit())
01282     {
01283         fprintf(pFile, "emissiveColor 1.0 1.0 1.0\n");
01284     }
01285     else
01286     {
01287         fprintf(pFile, "emissiveColor %f %f %f\n",
01288                 mChunk->getEmission()[0],
01289                 mChunk->getEmission()[1],
01290                 mChunk->getEmission()[2]);
01291     }
01292
01293     pWriter->printIndent();
01294     fprintf(pFile, "shininess %f\n",
01295             mChunk->getShininess() / 128.);
01296
01297     pWriter->printIndent();
01298     fprintf(pFile, "specularColor %f %f %f\n",
01299             mChunk->getSpecular()[0],
01300             mChunk->getSpecular()[1],
01301             mChunk->getSpecular()[2]);
01302
01303     pWriter->printIndent();
01304     fprintf(pFile, "transparency %f\n",
01305             1.f-mChunk->getDiffuse()[3]);
01306
01307     pWriter->decIndent(4);
01308
01309     pWriter->printIndent();
01310     fprintf(pFile, "}\n");
01311
01312     sChunk = st->getChunk(TextureObjChunk::getStaticClassId());
01313
01314     TextureObjChunk *pTChunk = dynamic_cast<TextureObjChunk *>(sChunk);
01315
01316     if(pTChunk != NULL)
01317     {
01318         if(pWriter->isWritten(pTChunk))
01319         {
01320             pWriter->printIndent();
01321             fprintf(pFile, "texture USE Tex_%u\n", pWriter->getIndex(pTChunk));
01322         }
01323         else
01324         {
01325             Image *pImage = pTChunk->getImage();
01326
01327             if(pImage != NULL)
01328             {
01329                 if(pWriter->getOptions() &
01330                                    VRMLWriteAction::OSGPixelTextures)
01331                 {
01332                     pWriter->printIndent();
01333                     fprintf(pFile, "texture DEF Tex_%u PixelTexture\n",
01334                         pWriter->setWritten(pTChunk) );
01335
01336                     pWriter->printIndent();
01337                     fprintf(pFile, "{\n");
01338
01339                     pWriter->incIndent(4);
01340
01341                     UInt32 pixelformat = pImage->getPixelFormat();
01342                     UInt32 pixelsize = 1;
01343                     if ( pixelformat == Image::OSG_RGB_PF)
01344                         pixelsize = 3;
01345                     else if ( pixelformat == Image::OSG_RGBA_PF)
01346                         pixelsize = 4;
01347                     else if ( pixelformat == Image::OSG_LA_PF )
01348                         pixelsize = 2;
01349
01350                     pWriter->printIndent();
01351                     fprintf(pFile, "image %d %d %u    ",
01352                         pImage->getWidth(), pImage->getHeight(), pixelsize);
01353
01354                     const UInt8 *data = pImage->getData();
01355                     for (Int32 x=0; x<pImage->getHeight(); ++x)
01356                     {
01357                         for (Int32 y=0; y<pImage->getWidth(); ++y)
01358                         {
01359                             UInt32 pos = (x * pImage->getWidth() + y) * pixelsize;
01360                             fprintf(pFile, "0x");
01361                             for (UInt32 i=0;i<pixelsize;i++)
01362                             {
01363                                 fprintf(pFile, "%02X", data[pos+i] );
01364                             }
01365                             fprintf(pFile, " ");
01366                         }
01367                         fprintf(pFile, "\n");
01368                     }
01369
01370                     if(pTChunk->getWrapS() != GL_REPEAT)
01371                     {
01372                         pWriter->printIndent();
01373                         fprintf(pFile, "repeatS FALSE\n");
01374                     }
01375
01376                     if(pTChunk->getWrapT() != GL_REPEAT)
01377                     {
01378                         pWriter->printIndent();
01379                         fprintf(pFile, "repeatT FALSE\n");
01380                     }
01381
01382                     pWriter->decIndent(4);
01383
01384                     pWriter->printIndent();
01385                     fprintf(pFile, "}\n");
01386                 }
01387                 else
01388                 {
01389                     const std::string *pFilename =
01390                         pImage->findAttachmentField("fileName");
01391                     std::string filename;
01392                     if(pFilename == NULL)
01393                         filename = pImage->getName();
01394                     else
01395                         filename = *pFilename;
01396
01397                     if(!filename.empty())
01398                     {
01399
01400                         pWriter->printIndent();
01401                         fprintf(pFile, "texture DEF Tex_%u ImageTexture\n",
01402                                     pWriter->setWritten(pTChunk) );
01403
01404                         pWriter->printIndent();
01405                         fprintf(pFile, "{\n");
01406
01407                         pWriter->incIndent(4);
01408
01409                         pWriter->printIndent();
01410                         fprintf(pFile, "url \"%s\"\n",
01411                                 filename.c_str());
01412
01413                         if(pTChunk->getWrapS() != GL_REPEAT)
01414                         {
01415                             pWriter->printIndent();
01416                             fprintf(pFile, "repeatS FALSE\n");
01417                         }
01418
01419                         if(pTChunk->getWrapT() != GL_REPEAT)
01420                         {
01421                             pWriter->printIndent();
01422                             fprintf(pFile, "repeatT FALSE\n");
01423                         }
01424
01425                         pWriter->decIndent(4);
01426
01427                         pWriter->printIndent();
01428                         fprintf(pFile, "}\n");
01429                     }
01430                 }
01431             }
01432         }
01433     }
01434 /*
01435     sChunk = st->getChunk(TextureTransformChunk::getStaticClassId());    
01436 
01437     TextureTransformChunkPtr pTTChunk = dynamic_cast<TextureTransformChunkPtr>(sChunk);
01438 
01439     if(pTTChunk != NULL)
01440     {
01441     }
01442  */
01443
01444     pWriter->decIndent(4);
01445
01446     pWriter->printIndent();
01447     fprintf(pFile, "}\n");
01448 }
01449
01450 bool VRMLWriteAction::writeGeoCommon(Node            *pNode,
01451                                      Geometry        *pGeo,
01452                                      FILE            *pFile,
01453                                      VRMLWriteAction *pWriter,
01454                                      const Char8     *setTypename)
01455 {
01456     FCInfo *pInfo     = pWriter->getInfo(pNode);
01457     FCInfo *pCoreInfo = pWriter->getInfo(pGeo);
01458
01459     if(pInfo == NULL || pCoreInfo == NULL || setTypename == NULL)
01460     {
01461         FWARNING(("Info missing %p %p\n", pInfo, pCoreInfo));
01462         return false;
01463     }
01464
01465     if(pCoreInfo->getUse()    >  0 &&
01466        pCoreInfo->getWritten() == true)
01467     {
01468         pWriter->printIndent();
01469         fprintf(pFile, "geometry USE %s\n", pCoreInfo->getName());
01470         pWriter->setCurrentUse(true);
01471     }
01472     else
01473     {
01474         if((pCoreInfo->getName()    != NULL) &&
01475            (pCoreInfo->getName()[0] != '\0'))
01476         {
01477             pWriter->printIndent();
01478             fprintf(pFile, "geometry DEF %s %s\n",
01479                     pCoreInfo->getName(),
01480                     setTypename);
01481
01482             pCoreInfo->setWritten();
01483         }
01484         else if((pInfo->getName()    != NULL) &&
01485                 (pInfo->getName()[0] != '\0'))
01486         {
01487             pWriter->printIndent();
01488             fprintf(pFile,
01489                     "geometry DEF %s %s\n",
01490                     pInfo->getName(),
01491                     setTypename);
01492
01493             pInfo->setWritten();
01494         }
01495         else
01496         {
01497             pWriter->printIndent();
01498             fprintf(pFile, "geometry %s\n", setTypename);
01499
01500         }
01501
01502         pWriter->printIndent();
01503         fprintf(pFile, "{\n");
01504
01505         pWriter->incIndent(4);
01506     }
01507
01508     return true;
01509 #if 0
01510 
01511 //        pWriter->printIndent();
01512 // !!!        fprintf(pFile, "colorPerVertex  %s\n", 
01513 // !!!                pGeo->getColorPerVertex() ? "TRUE" : "FALSE");
01514
01515 //        pWriter->printIndent();
01516 // !!!        fprintf(pFile, "normalPerVertex %s\n",
01517 // !!!                pGeo->getNormalPerVertex() ? "TRUE" : "FALSE");
01518 #endif
01519 }
01520
01521 void VRMLWriteAction::writePointSet(Node            *pNode,
01522                                     Geometry        *pGeo,
01523                                     FILE            *pFile,
01524                                     VRMLWriteAction *pWriter)
01525 {
01526     FWARNING(("point set not supported\n"));
01527
01528     if(writeGeoCommon(pNode, pGeo, pFile, pWriter, "PointSet") == true)
01529     {
01530
01531         if(pWriter->isCurrentUse() == false)
01532         {
01533             pWriter->decIndent(4);
01534
01535             pWriter->printIndent();
01536             fprintf(pFile, "}\n");
01537         }
01538
01539         pWriter->setCurrentUse(false);
01540     }
01541 }
01542
01543 void VRMLWriteAction::writeLineSet(Node            *pNode,
01544                                    Geometry        *pGeo,
01545                                    FILE            *pFile,
01546                                    VRMLWriteAction *pWriter,
01547                                    bool             )
01548 {
01549     if(writeGeoCommon(pNode, pGeo, pFile, pWriter, "IndexedLineSet") == true)
01550     {
01551
01552         if(pWriter->isCurrentUse() == false)
01553         {
01554             writePoints   (pGeo, pFile, pWriter);
01555             writeColors   (pGeo, pFile, pWriter);
01556
01557             writeLineIndex(pGeo, pFile, pWriter);
01558
01559             pWriter->decIndent(4);
01560
01561             pWriter->printIndent();
01562             fprintf(pFile, "}\n");
01563
01564             writeMaterial(pGeo, pFile, pWriter);
01565         }
01566
01567         pWriter->setCurrentUse(false);
01568     }
01569 }
01570
01571 void VRMLWriteAction::writeFaceSet(Node            *pNode,
01572                                    Geometry        *pGeo,
01573                                    FILE            *pFile,
01574                                    VRMLWriteAction *pWriter,
01575                                    bool             )
01576 {
01577     if(writeGeoCommon(pNode, pGeo, pFile, pWriter, "IndexedFaceSet") == true)
01578     {
01579         if(pWriter->isCurrentUse() == false)
01580         {
01581             pWriter->printIndent();
01582             fprintf(pFile, "solid FALSE\n");
01583
01584             writePoints   (pGeo, pFile, pWriter);
01585             writeNormals  (pGeo, pFile, pWriter);
01586             writeColors   (pGeo, pFile, pWriter);
01587             writeTexCoords(pGeo, pFile, pWriter);
01588
01589             writeIndex    (pGeo, pFile, pWriter);
01590
01591             pWriter->decIndent(4);
01592
01593             pWriter->printIndent();
01594             fprintf(pFile, "}\n");
01595
01596             writeMaterial(pGeo, pFile, pWriter);
01597         }
01598
01599         pWriter->setCurrentUse(false);
01600     }
01601 }
01602
01603
01604 Action::ResultE VRMLWriteAction::writeGeoEnter(NodeCore * const ,
01605                                                Action *pAction)
01606 {
01607     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
01608
01609     Node *pNode = pAction->getActNode();
01610     Geometry *pGeo = dynamic_cast<Geometry *>(pNode->getCore());
01611
01612     if(pWriter == NULL || pGeo == NULL)
01613     {
01614         return Action::Quit;
01615     }
01616
01617     FDEBUG(("Write Geo Enter 0x%04x\n", pWriter->getMode()));
01618
01619     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
01620     {
01621         pWriter->addNodeUse(pNode);
01622
01623         pWriter->addContainerUse(pGeo->getPositions());
01624         pWriter->addContainerUse(pGeo->getNormals  ());
01625         pWriter->addContainerUse(pGeo->getColors   ());
01626         pWriter->addContainerUse(pGeo->getTexCoords());
01627     }
01628     else
01629     {
01630         FILE *pFile = pWriter->getFilePtr();
01631
01632         if(pFile == NULL)
01633         {
01634             return Action::Quit;
01635         }
01636
01637         pWriter->updateProgress();
01638
01639         pWriter->printIndent();
01640         fprintf(pFile, "Shape\n");
01641         pWriter->printIndent();
01642         fprintf(pFile, "{\n");
01643
01644         pWriter->incIndent(4);
01645
01646         PrimitiveIterator pIt  = pGeo->beginPrimitives();
01647         PrimitiveIterator pEnd = pGeo->endPrimitives();
01648
01649         UInt32 uiPointCount = 0;
01650         UInt32 uiLineCount  = 0;
01651         UInt32 uiFaceCount  = 0;
01652
01653         while(pIt != pEnd)
01654         {
01655             if(pIt.getType() == GL_LINES      ||
01656                pIt.getType() == GL_LINE_STRIP ||
01657                pIt.getType() == GL_LINE_LOOP   )
01658             {
01659                 ++uiLineCount;
01660             }
01661             else if(pIt.getType() == GL_POINTS)
01662             {
01663                 ++uiPointCount;
01664             }
01665             else
01666             {
01667                 ++uiFaceCount;
01668             }
01669
01670             ++pIt;
01671         }
01672
01673         FINFO(( "Geo Stat : %d %d %d\n",
01674                 uiPointCount,
01675                 uiLineCount,
01676                 uiFaceCount));
01677
01678         if(uiPointCount != 0)
01679         {
01680             if((uiLineCount != 0) || (uiFaceCount != 0))
01681             {
01682                 FWARNING(("ERROR writer does not support mixed primitives"
01683                           "including points\n"));
01684             }
01685             else
01686             {
01687                 writePointSet(pNode, pGeo, pFile, pWriter);
01688             }
01689         }
01690
01691         if(uiLineCount != 0)
01692         {
01693             writeLineSet(pNode,
01694                          pGeo,
01695                          pFile,
01696                          pWriter,
01697                          ((uiPointCount == 0) && (uiFaceCount == 0)));
01698         }
01699
01700         if(uiFaceCount != 0)
01701         {
01702             writeFaceSet(pNode,
01703                          pGeo,
01704                          pFile,
01705                          pWriter,
01706                          ((uiPointCount == 0) && (uiLineCount == 0)));
01707         }
01708     }
01709
01710     return Action::Continue;
01711 }
01712
01713 Action::ResultE VRMLWriteAction::writeGeoLeave(NodeCore * const ,
01714                                                Action *pAction)
01715 {
01716     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
01717
01718     if(pWriter == NULL)
01719     {
01720         return Action::Quit;
01721     }
01722
01723     FDEBUG(("Write Geo Leave 0x%04x\n", pWriter->getMode()));
01724
01725     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
01726     {
01727         FILE *pFile = pWriter->getFilePtr();
01728
01729         if(pFile == NULL)
01730         {
01731             return Action::Quit;
01732         }
01733
01734         pWriter->decIndent(4);
01735
01736         pWriter->printIndent();
01737         fprintf(pFile, "}\n");
01738     }
01739
01740     return Action::Continue;
01741 }
01742
01743 Action::ResultE VRMLWriteAction::writeMatGroupEnter(NodeCore * const ,
01744                                                     Action *pAction)
01745 {
01746     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
01747
01748     Node *pNode = pAction->getActNode();
01749
01750     MaterialGroup *pMatGroup =
01751         dynamic_cast<MaterialGroup *>(pNode->getCore());
01752
01753     if(pWriter == NULL || pMatGroup == NULL)
01754     {
01755         return Action::Quit;
01756     }
01757
01758     FDEBUG(("Write MatGroup Enter 0x%04x\n", pWriter->getMode()));
01759
01760     pWriter->setMaterial(pMatGroup->getMaterial());
01761
01762     return Action::Continue;
01763 }
01764
01765 Action::ResultE VRMLWriteAction::writeMatGroupLeave(NodeCore * const ,
01766                                                     Action *pAction)
01767 {
01768     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
01769
01770
01771     if(pWriter == NULL)
01772     {
01773         return Action::Quit;
01774     }
01775
01776     FDEBUG(("Write MatGroup Leave 0x%04x\n", pWriter->getMode()));
01777
01778     pWriter->setMaterial(NULL);
01779
01780     return Action::Continue;
01781 }
01782
01783
01784 bool VRMLWriteAction::initializeAction(void)
01785 {
01786     FINFO(( "Init VRMLWriter\n" ));
01787
01788     VRMLWriteAction::registerEnterDefault(
01789             Group::getClassType(), &VRMLWriteAction::writeGroupEnter);
01790
01791     VRMLWriteAction::registerEnterDefault(
01792             ComponentTransform::getClassType(),
01793             &VRMLWriteAction::writeComponentTransformEnter);
01794
01795     VRMLWriteAction::registerEnterDefault(
01796             Transform::getClassType(), &VRMLWriteAction::writeTransformEnter);
01797
01798     VRMLWriteAction::registerEnterDefault(
01799             Geometry::getClassType(), &VRMLWriteAction::writeGeoEnter);
01800
01801     VRMLWriteAction::registerEnterDefault(
01802             MaterialGroup::getClassType(), &VRMLWriteAction::writeMatGroupEnter);
01803
01804
01805     VRMLWriteAction::registerLeaveDefault(
01806             Group::getClassType(), &VRMLWriteAction::writeGroupLeave);
01807
01808     VRMLWriteAction::registerLeaveDefault(
01809             ComponentTransform::getClassType(),
01810             &VRMLWriteAction::writeComponentTransformLeave);
01811
01812     VRMLWriteAction::registerLeaveDefault(
01813             Transform::getClassType(), &VRMLWriteAction::writeTransformLeave);
01814
01815     VRMLWriteAction::registerLeaveDefault(
01816             Geometry::getClassType(), &VRMLWriteAction::writeGeoLeave);
01817
01818     VRMLWriteAction::registerLeaveDefault(
01819             MaterialGroup::getClassType(), &VRMLWriteAction::writeMatGroupLeave);
01820
01821     return true;
01822 }
01823
01824 bool VRMLWriteAction::terminateAction(void)
01825 {
01826     FINFO(( "Terminate VRMLWriter\n" ));
01827
01828     delete _defaultEnterFunctors;
01829     delete _defaultLeaveFunctors;
01830
01831     return true;
01832 }
01833
01834
01835 void VRMLWriteAction::incIndent(UInt32 uiDelta)
01836 {
01837     if(0 == (_uiOptions & OSGNoIndent))
01838     {
01839         _uiIndent += uiDelta;
01840     }
01841 }
01842
01843 void VRMLWriteAction::decIndent(UInt32 uiDelta)
01844 {
01845     if(0 == (_uiOptions & OSGNoIndent))
01846     {
01847         _uiIndent -= uiDelta;
01848     }
01849 }
01850
01851 void VRMLWriteAction::printIndent(void)
01852 {
01853     if(_pFile != NULL)
01854     {
01855         for(UInt32 i = 0; i < _uiIndent/8; i++)
01856         {
01857             fprintf(_pFile, "\t");
01858         }
01859         for(UInt32 i = 0; i < _uiIndent%8; i++)
01860         {
01861             fprintf(_pFile, " ");
01862         }
01863     }
01864 }
01865
01866 void VRMLWriteAction::setCurrentUse(bool bVal)
01867 {
01868     _currentUse = bVal;
01869 }
01870
01871 bool VRMLWriteAction::isCurrentUse(void)
01872 {
01873     return _currentUse;
01874 }
01875
01876 void VRMLWriteAction::addNodeUse(Node * pNode)
01877 {
01878     if(pNode == NULL)
01879         return;
01880
01881     NodeCore *pCore = pNode->getCore();
01882
01883     if(_vFCInfos.find(pNode->getId()) == _vFCInfos.end())
01884         _vFCInfos.insert(std::make_pair(pNode->getId(), new FCInfo));
01885
01886     if(_vFCInfos.find(pCore->getId()) == _vFCInfos.end())
01887         _vFCInfos.insert(std::make_pair(pCore->getId(), new FCInfo));
01888
01889     FCInfo *pInfoNode = _vFCInfos[pNode->getId()];
01890     FCInfo *pInfoCore = _vFCInfos[pCore->getId()];
01891
01892     Name *pNodename =
01893         dynamic_cast<Name *>(pNode->findAttachment(
01894             Name::getClassType().getGroupId()));
01895
01896     Name *pCorename =
01897         dynamic_cast<Name *>(pCore->findAttachment(
01898             Name::getClassType().getGroupId()));
01899
01900     pInfoNode->incUse();
01901     pInfoCore->incUse();
01902
01903     if(pNodename != NULL)
01904     {
01905         pInfoNode->setName(pNodename->getFieldPtr()->getValue().c_str());
01906     }
01907
01908     if(pCorename != NULL)
01909     {
01910         pInfoCore->setName(pCorename->getFieldPtr()->getValue().c_str());
01911     }
01912
01913     if(pInfoCore->getUse() > 1)
01914     {
01915         if(pCorename != NULL)
01916         {
01917             pInfoCore->buildName(pCore->getTypeName(),
01918                                  pCore->getId());
01919         }
01920     }
01921
01922     ++_nodeCount;
01923 }
01924
01925 void VRMLWriteAction::addContainerUse(FieldContainer *pContainer)
01926 {
01927     if(pContainer == NULL)
01928         return;
01929
01930     if(_vFCInfos.find(pContainer->getId()) == _vFCInfos.end())
01931         _vFCInfos.insert(std::make_pair(pContainer->getId(), new FCInfo));
01932
01933     FCInfo *pInfo = _vFCInfos[pContainer->getId()];
01934
01935     pInfo->incUse();
01936
01937     if(pInfo->getUse() > 1)
01938     {
01939         pInfo->buildName(pContainer->getTypeName(),
01940                          pContainer->getId());
01941     }
01942 }
01943
01944 void VRMLWriteAction::clearInfos(void)
01945 {
01946     for(FCInfosMap::iterator it = _vFCInfos.begin();it != _vFCInfos.end();++it)
01947         delete (*it).second;
01948     _vFCInfos.clear();
01949 }
01950
01951 VRMLWriteAction::FCInfo *VRMLWriteAction::getInfo(
01952     FieldContainer *pContainer)
01953 {
01954     if(pContainer == NULL)
01955         return NULL;
01956
01957     if(_vFCInfos.find(pContainer->getId()) == _vFCInfos.end())
01958         return NULL;
01959
01960     return _vFCInfos[pContainer->getId()];
01961 }
01962
01963 void VRMLWriteAction::updateProgress(void)
01964 {
01965     if(_nodeCount > 0)
01966         SceneFileHandler::the()->updateWriteProgress((_currentNodeCount++ * 100) / _nodeCount);
01967 }
01968
01969 /***************************************************************************\
01970  *                           Instance methods                              *
01971 \***************************************************************************/
01972
01973 /*-------------------------------------------------------------------------*\
01974  -  public                                                                 -
01975 \*-------------------------------------------------------------------------*/
01976
01977 /*------------- constructors & destructors --------------------------------*/
01978
01982 VRMLWriteAction::VRMLWriteAction(void) :
01983      Inherited       (            ),
01984     _material        (NULL        ),
01985     _uiIndent        (0           ),
01986     _pFile           (NULL        ),
01987     _eTraversalMode  (OSGCollectFC),
01988     _currentUse      (false       ),
01989     _uiOptions       (OSGNoOptions),
01990     _vFCInfos        (            ),
01991     _writtenFCs      (            ),
01992     _nodeCount       (0           ),
01993     _currentNodeCount(0           )
01994 {
01995     if(_defaultEnterFunctors)
01996         _enterFunctors = *_defaultEnterFunctors;
01997
01998     if(_defaultLeaveFunctors)
01999         _leaveFunctors = *_defaultLeaveFunctors;
02000 }
02001
02002
02006 VRMLWriteAction::VRMLWriteAction(const VRMLWriteAction &source) :
02007      Inherited       (source                  ),
02008     _material        (source._material        ),
02009     _uiIndent        (source._uiIndent        ),
02010     _pFile           (NULL                    ),
02011     _eTraversalMode  (source._eTraversalMode  ),
02012     _currentUse      (source._currentUse      ),
02013     _uiOptions       (source._uiOptions       ),
02014     _vFCInfos        (source._vFCInfos        ),
02015     _writtenFCs      (source._writtenFCs      ),
02016     _nodeCount       (source._nodeCount       ),
02017     _currentNodeCount(source._currentNodeCount)
02018 {
02019     if(_defaultEnterFunctors)
02020         _enterFunctors = *_defaultEnterFunctors;
02021
02022     if(_defaultLeaveFunctors)
02023         _leaveFunctors = *_defaultLeaveFunctors;
02024 }
02025
02029 VRMLWriteAction *VRMLWriteAction::create( void )
02030 {
02031     VRMLWriteAction * act;
02032
02033     if(_prototype)
02034         act = new VRMLWriteAction(*_prototype);
02035     else
02036         act = new VRMLWriteAction();
02037
02038     return act;
02039 }
02040
02041
02045 VRMLWriteAction::~VRMLWriteAction(void)
02046 {
02047 }
02048
02049 /*------------------------------ access -----------------------------------*/
02050
02051 /*---------------------------- properties ---------------------------------*/
02052
02053 void VRMLWriteAction::setMaterial(Material *material)
02054 {
02055     _material = material;
02056 }
02057
02058 bool VRMLWriteAction::open(const Char8 *szFilename)
02059 {
02060     if(szFilename != NULL)
02061     {
02062         _pFile = fopen(szFilename, "w");
02063
02064         if(_pFile != NULL)
02065         {
02066             fprintf(_pFile, "#VRML V2.0 utf8 \n");
02067         }
02068     }
02069
02070     return _pFile != NULL;
02071 }
02072
02073 void VRMLWriteAction::close(void)
02074 {
02075     if(_pFile != NULL)
02076     {
02077         fclose(_pFile);
02078     }
02079 }
02080
02081 void VRMLWriteAction::addOptions(UInt32 uiOptions)
02082 {
02083     _uiOptions |= uiOptions;
02084 }
02085
02086 void VRMLWriteAction::subOptions(UInt32 uiOptions)
02087 {
02088     _uiOptions &= ~uiOptions;
02089 }
02090
02091 UInt32 VRMLWriteAction::getOptions(void)
02092 {
02093     return _uiOptions;
02094 }
02095
02096 Action::ResultE VRMLWriteAction::write(Node *node)
02097 {
02098     Action::ResultE returnValue = Action::Continue;
02099
02100     _eTraversalMode = OSGCollectFC;
02101
02102     clearInfos();
02103
02104     _writtenFCs.clear();
02105
02106     setMaterial(NULL);
02107
02108     SceneFileHandler::the()->updateWriteProgress(0);
02109     _nodeCount = 0;
02110     _currentNodeCount = 0;
02111
02112     returnValue = Inherited::apply(node);
02113
02114     if(returnValue == Action::Continue)
02115     {
02116         _eTraversalMode = OSGWrite;
02117         returnValue = Inherited::apply(node);
02118     }
02119
02120     SceneFileHandler::the()->updateReadProgress(100);
02121
02122     clearInfos();
02123
02124     return returnValue;
02125 }
02126
02127 /*-------------------------- your_category---------------------------------*/
02128
02129 /*-------------------------- assignment -----------------------------------*/
02130
02134 /*
02135 
02136 DrawAction& DrawAction::operator = (const DrawAction &source)
02137 {
02138     if (this == &source)
02139         return *this;
02140 
02141     // copy parts inherited from parent
02142     *(static_cast<Inherited *>(this)) = source;
02143 
02144     // free mem alloced by members of 'this'
02145 
02146     // alloc new mem for members
02147 
02148     // copy 
02149 }
02150 
02151 */
02152
02153 /*-------------------------- comparison -----------------------------------*/
02154
02158 bool VRMLWriteAction::operator < (const VRMLWriteAction &other) const
02159 {
02160     return this < &other;
02161 }
02162
02166 bool VRMLWriteAction::operator == (
02167     const VRMLWriteAction &OSG_CHECK_ARG(other)) const
02168 {
02169     return false;
02170 }
02171
02175 bool VRMLWriteAction::operator != (const VRMLWriteAction &other) const
02176 {
02177     return ! (*this == other);
02178 }
02179
02180
02181 /*-------------------------------------------------------------------------*\
02182  -  protected                                                              -
02183 \*-------------------------------------------------------------------------*/
02184
02185
02186 std::vector<VRMLWriteAction::Functor> *
02187     VRMLWriteAction::getDefaultEnterFunctors(void)
02188 {
02189     return _defaultEnterFunctors;
02190 }
02191
02192 std::vector<VRMLWriteAction::Functor> *
02193     VRMLWriteAction::getDefaultLeaveFunctors(void)
02194 {
02195     return _defaultLeaveFunctors;
02196 }
02197
02198 Action::ResultE VRMLWriteAction::apply(std::vector<Node *>::iterator begin,
02199                                        std::vector<Node *>::iterator end)
02200 {
02201     return Inherited::apply(begin, end);
02202 }
02203
02204 Action::ResultE VRMLWriteAction::apply(Node * const node)
02205 {
02206     return Inherited::apply(node);
02207 }
02208
02209 /*-------------------------------------------------------------------------*\
02210  -  private                                                                -
02211 \*-------------------------------------------------------------------------*/
02212
02213
02214
02218 //:  Example for the head comment of a function
02221 //p: Paramaters: 
02222 //p: 
02224 //g: GlobalVars:
02225 //g: 
02227 //r: Return:
02228 //r: 
02230 //c: Caution:
02231 //c: 
02233 //a: Assumptions:
02234 //a: 
02236 //d: Description:
02237 //d: 
02239 //s: SeeAlso:
02240 //s: 
02242