Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include "OSGConfig.h"
00047 
00048 #include <OSGLog.h>
00049 #include <OSGFieldContainer.h>
00050 #include <OSGFieldContainerPtr.h>
00051 #include <OSGNode.h>
00052 #include <OSGNodeCore.h>
00053 #include <OSGGroup.h>
00054 #include <OSGGeometry.h>
00055 #include <OSGTriangleIterator.h>
00056 #include <OSGComponentTransform.h>
00057 #include <OSGGeoPropPtrs.h>
00058 #include <OSGSimpleMaterial.h>
00059 #include <OSGMaterialGroup.h>
00060 #include "OSGAction.h"
00061 #include "OSGVRMLWriteAction.h"
00062 #include <OSGSimpleAttachments.h>
00063 #include <OSGTextureChunk.h>
00064 #include <OSGImage.h>
00065 #include <OSGImageFileHandler.h>
00066 #include <OSGSimpleGeometry.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     addInitFunction      (&VRMLWriteAction::initializeAction);
00093     addSystemExitFunction(&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         stringDup(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(Int16 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? add an _
00153     if(szName[0] >= 0x30 && szName[0] <= 0x39)
00154     {
00155         Char8 *newstring = new char [strlen(szName) + 2];
00156         
00157         newstring[0] = '_';
00158         strcpy(newstring + 1, szName);
00159         delete[] szName;
00160         szName = newstring;
00161     }
00162 }
00163 
00164 void VRMLWriteAction::FCInfo::setName(const Char8 *szName)
00165 {
00166     stringDup(szName, _szName);
00167     convertName(_szName);
00168     _bOwnName = true;
00169 }
00170 
00171 void VRMLWriteAction::FCInfo::buildName(const Char8  *szTypename,
00172                                               UInt32  uiContainerId)
00173 {
00174     if(_szName != NULL)
00175         return;
00176 
00177     if(szTypename != NULL)
00178     {
00179         _szName = new Char8[strlen(szTypename) + 32];
00180 
00181         sprintf(_szName, "%s_%d", szTypename, uiContainerId);
00182     }
00183     else
00184     {
00185         _szName = new Char8[64];
00186         
00187         sprintf(_szName, "UType_%d", uiContainerId);
00188     }
00189 
00190     _bOwnName = true;
00191 }
00192 
00193 void VRMLWriteAction::FCInfo::incUse(void)
00194 {
00195     _iTimesUsed++;
00196 }
00197 
00198 UInt32 VRMLWriteAction::FCInfo::getUse(void) const
00199 {
00200     return _iTimesUsed;
00201 }
00202 
00203 const Char8 *VRMLWriteAction::FCInfo::getName(void) const
00204 {
00205     return _szName;
00206 }
00207 
00208 bool VRMLWriteAction::FCInfo::getWritten(void) const
00209 {
00210     return _bWritten;
00211 }
00212 
00213 void VRMLWriteAction::FCInfo::setWritten(void)
00214 {
00215     _bWritten = true;
00216 }
00217 
00218 Int32 VRMLWriteAction::FCInfo::clear(void)
00219 {
00220     _iTimesUsed = 0;
00221 
00222     if(_bOwnName == true)
00223     {
00224         delete [] _szName;
00225     }
00226 
00227     _bOwnName = false;
00228     _szName   = NULL;
00229     _bWritten  = false;
00230 
00231     return 0;
00232 }
00233 
00234 /***************************************************************************\
00235  *                           Class variables                               *
00236 \***************************************************************************/
00237 
00238 char VRMLWriteAction::cvsid[] = "@(#)$Id: $";
00239 
00240 VRMLWriteAction * VRMLWriteAction::_prototype = NULL;
00241 
00242 std::vector<Action::Functor> *VRMLWriteAction::_defaultEnterFunctors;
00243 std::vector<Action::Functor> *VRMLWriteAction::_defaultLeaveFunctors;
00244 
00245 VRMLWriteAction::ActionInitializer VRMLWriteAction::_actionInitializer;
00246 
00247 
00248 /***************************************************************************\
00249  *                           Class methods                                 *
00250 \***************************************************************************/
00251 
00252 
00253 
00254 /*-------------------------------------------------------------------------*\
00255  -  public                                                                 -
00256 \*-------------------------------------------------------------------------*/
00257 
00258 void VRMLWriteAction::registerEnterDefault(const FieldContainerType &type, 
00259                                            const Action::Functor    &func)
00260 {
00261     if(!_defaultEnterFunctors)
00262         _defaultEnterFunctors = new std::vector<Action::Functor>;
00263 
00264     while(type.getId() >= _defaultEnterFunctors->size())
00265     {
00266         _defaultEnterFunctors->push_back( 
00267             osgTypedFunctionFunctor2CPtrRef<
00268                 ResultE, 
00269                 CNodePtr,
00270                 Action *                   >(&Action::_defaultEnterFunction));
00271     }
00272     
00273     (*_defaultEnterFunctors)[ type.getId() ] = func;
00274 }
00275 
00276 void VRMLWriteAction::registerLeaveDefault(const FieldContainerType &type, 
00277                                            const Action::Functor    &func)
00278 {
00279     if(! _defaultLeaveFunctors)
00280         _defaultLeaveFunctors = new std::vector<Action::Functor>;
00281 
00282     while(type.getId() >= _defaultLeaveFunctors->size())
00283     {
00284         _defaultLeaveFunctors->push_back( 
00285             osgTypedFunctionFunctor2CPtrRef<
00286                 ResultE, 
00287                 CNodePtr,
00288                 Action *                   >(&Action::_defaultLeaveFunction));
00289     }
00290     
00291     (*_defaultLeaveFunctors)[ type.getId() ] = func;
00292 }
00293 
00294 
00295 void VRMLWriteAction::setPrototype(VRMLWriteAction *proto)
00296 {
00297     _prototype = proto;
00298 }
00299 
00300 VRMLWriteAction *VRMLWriteAction::getPrototype( void )
00301 {
00302     return _prototype;
00303 }
00304 
00305 /*-------------------------------------------------------------------------*\
00306  -  protected                                                              -
00307 \*-------------------------------------------------------------------------*/
00308 
00309 
00310 /*-------------------------------------------------------------------------*\
00311  -  private                                                                -
00312 \*-------------------------------------------------------------------------*/
00313 
00314 Action::ResultE VRMLWriteAction::writeGroupEnter(CNodePtr &pGroup,
00315                                                  Action   *pAction)
00316 {
00317     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00318 
00319     NodePtr pNode(pGroup);
00320 
00321     if(pWriter == NULL)
00322     {
00323         return Action::Quit;
00324     }
00325 
00326     FDEBUG(("Write Group Enter 0x%04x\n", pWriter->getMode()));
00327 
00328     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00329     {
00330         pWriter->addNodeUse(pGroup);
00331     }
00332     else
00333     {
00334         FILE *pFile = pWriter->getFilePtr();
00335         
00336         if(pFile == NULL)    
00337         {
00338             return Action::Quit;
00339         }
00340 
00341         NodeCorePtr pCore = pNode->getCore();
00342 
00343         FCInfo *pInfo     = pWriter->getInfo(pGroup);
00344         FCInfo *pCoreInfo = pWriter->getInfo(pCore );
00345 
00346         if(pInfo == NULL || pCoreInfo == NULL)
00347         {
00348             FWARNING(("Info missing %p %p\n", pInfo, pCoreInfo));
00349             return Action::Quit;
00350         }
00351 
00352         if(pCoreInfo->getUse()    >  0 && 
00353            pCoreInfo->getWritten() == true)
00354         {
00355             pWriter->printIndent();
00356             fprintf(pFile, "Group # osg shared %s\n", pCoreInfo->getName());
00357 
00358 //            pWriter->setCurrentUse(true);
00359         }
00360         else if((pCoreInfo->getName()    != NULL) &&
00361                (pCoreInfo->getName()[0] != '\0'))
00362         {
00363             pWriter->printIndent();
00364             fprintf(pFile, "DEF %s Group\n", pCoreInfo->getName());
00365             
00366             pCoreInfo->setWritten();
00367         }
00368         else if((pInfo->getName()    != NULL) &&
00369                 (pInfo->getName()[0] != '\0'))
00370         {
00371             pWriter->printIndent();
00372             fprintf(pFile, "DEF %s Group\n", pInfo->getName());
00373             
00374             pInfo->setWritten();
00375         }
00376         else
00377         {
00378             pWriter->printIndent();
00379             fprintf(pFile, "Group\n");
00380         }
00381                     
00382         pWriter->printIndent();
00383         fprintf(pFile, "{\n");
00384         
00385         if(pNode->getNChildren() != 0)
00386         {
00387             pWriter->incIndent(4);
00388             
00389             pWriter->printIndent();
00390             fprintf(pFile, "children [\n");
00391             
00392             pWriter->incIndent(4);        
00393         }
00394     }
00395 
00396     return Action::Continue;
00397 }
00398 
00399 Action::ResultE VRMLWriteAction::writeGroupLeave(CNodePtr &pGroup,
00400                                                  Action   *pAction)
00401 {
00402     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00403 
00404     NodePtr pNode(pGroup);
00405 
00406     if(pWriter == NULL)
00407     {
00408         return Action::Quit;
00409     }
00410 
00411     FDEBUG(("Write Group Leave 0x%04x\n", pWriter->getMode()));
00412 
00413     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00414     {
00415         FILE *pFile = pWriter->getFilePtr();
00416         
00417         if(pFile == NULL)    
00418         {
00419             return Action::Quit;
00420         }
00421 
00422         if(pWriter->isCurrentUse() == false)
00423         {
00424             if(pNode->getNChildren() != 0)
00425             {
00426                 pWriter->decIndent(4);
00427                 
00428                 pWriter->printIndent();
00429                 fprintf(pFile, "]\n");
00430                 
00431                 pWriter->decIndent(4);
00432             }
00433 
00434             pWriter->printIndent();
00435             fprintf(pFile, "}\n");
00436         }
00437         
00438         pWriter->setCurrentUse(false);
00439     }
00440 
00441     return Action::Continue;
00442 }
00443 
00444 Action::ResultE VRMLWriteAction::writeComponentTransformEnter(CNodePtr &pGroup,
00445                                                       Action   *pAction)
00446 {
00447     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00448 
00449     ComponentTransformPtr pTrans = 
00450         ComponentTransformPtr::dcast(pGroup.getNode()->getCore());
00451 
00452     Real32 rQX;
00453     Real32 rQY;
00454     Real32 rQZ;
00455     Real32 rQW;
00456 
00457     if(pWriter == NULL)
00458     {
00459         return Action::Quit;
00460     }
00461 
00462     FDEBUG(("Write ComponentTransform Enter 0x%04x\n", pWriter->getMode()));
00463 
00464     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00465     {
00466         pWriter->addNodeUse(pGroup);
00467     }
00468     else
00469     {
00470         FILE *pFile = pWriter->getFilePtr();
00471         
00472         if(pFile == NULL)    
00473         {
00474             return Action::Quit;
00475         }
00476 
00477         FCInfo *pInfo = pWriter->getInfo(pGroup);
00478 
00479         if(pInfo == NULL)
00480         {
00481             return Action::Quit;
00482         }
00483 
00484         if((pInfo->getName() != NULL   ) &&
00485            (pInfo->getWritten() == false) && 
00486            (pInfo->getName()[0] != '\0'))
00487         {
00488             pWriter->printIndent();
00489             fprintf(pFile, "DEF %s Transform\n", pInfo->getName());
00490 
00491             pInfo->setWritten();
00492         }
00493         else
00494         {
00495             pWriter->printIndent();
00496             fprintf(pFile, "Transform\n");
00497         }
00498 
00499         pWriter->printIndent();
00500         fprintf(pFile, "{\n");
00501 
00502         pWriter->incIndent(4);
00503 
00504         pWriter->printIndent();
00505         fprintf(pFile, "center %f %f %f\n",
00506                 pTrans->getCenter()[0],
00507                 pTrans->getCenter()[1],
00508                 pTrans->getCenter()[2]);
00509 
00510         pTrans->getRotation().getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00511 
00512         pWriter->printIndent();
00513         fprintf(pFile, "rotation %f %f %f %f\n",
00514                 rQX, rQY, rQZ, rQW);
00515 
00516         pWriter->printIndent();
00517         fprintf(pFile, "scale %f %f %f\n",
00518                 pTrans->getScale()[0],
00519                 pTrans->getScale()[1],
00520                 pTrans->getScale()[2]);
00521 
00522         pTrans->getScaleOrientation().getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00523 
00524         pWriter->printIndent();
00525         fprintf(pFile, "scaleOrientation %f %f %f %f\n",
00526                 rQX, rQY, rQZ, rQW);
00527 
00528         pWriter->printIndent();
00529         fprintf(pFile, "translation %f %f %f\n", 
00530                 pTrans->getTranslation()[0],
00531                 pTrans->getTranslation()[1],
00532                 pTrans->getTranslation()[2]);
00533 
00534         pWriter->printIndent();
00535         fprintf(pFile, "children [\n");
00536 
00537         pWriter->incIndent(4);
00538     }
00539 
00540     return Action::Continue;
00541 }
00542 
00543 Action::ResultE VRMLWriteAction::writeComponentTransformLeave(CNodePtr &,
00544                                                       Action   *pAction)
00545 {
00546     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00547 
00548     if(pWriter == NULL)
00549     {
00550         return Action::Quit;
00551     }
00552 
00553     FDEBUG(("Write ComponentTransform Leave 0x%04x\n", pWriter->getMode()));
00554 
00555     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00556     {
00557         FILE *pFile = pWriter->getFilePtr();
00558         
00559         if(pFile == NULL)    
00560         {
00561             return Action::Quit;
00562         }
00563 
00564         pWriter->decIndent(4);
00565 
00566         pWriter->printIndent();
00567         fprintf(pFile, "]\n");
00568 
00569         pWriter->decIndent(4);
00570 
00571         pWriter->printIndent();
00572         fprintf(pFile, "}\n");
00573     }
00574 
00575     return Action::Continue;
00576 }
00577 
00578 Action::ResultE VRMLWriteAction::writeTransformEnter(CNodePtr &pGroup,
00579                                                      Action   *pAction)
00580 {
00581     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00582 
00583     TransformPtr pTrans = TransformPtr::dcast(pGroup.getNode()->getCore());
00584 
00585     Real32 rQX;
00586     Real32 rQY;
00587     Real32 rQZ;
00588     Real32 rQW;
00589 
00590     if(pWriter == NULL)
00591     {
00592         return Action::Quit;
00593     }
00594 
00595     FDEBUG(("Write Transform Enter 0x%04x\n", pWriter->getMode()));
00596 
00597     if(pWriter->getMode() == VRMLWriteAction::OSGCollectFC)
00598     {
00599         pWriter->addNodeUse(pGroup);
00600     }
00601     else
00602     {
00603         FILE *pFile = pWriter->getFilePtr();
00604         
00605         if(pFile == NULL)    
00606         {
00607             return Action::Quit;
00608         }
00609 
00610         FCInfo *pInfo = pWriter->getInfo(pGroup);
00611 
00612         if(pInfo == NULL)
00613         {
00614             return Action::Quit;
00615         }
00616 
00617         if((pInfo->getName() != NULL   ) &&
00618            (pInfo->getWritten() == false) && 
00619            (pInfo->getName()[0] != '\0'))
00620         {
00621             pWriter->printIndent();
00622             fprintf(pFile, "DEF %s Transform\n", pInfo->getName());
00623 
00624             pInfo->setWritten();
00625         }
00626         else
00627         {
00628             pWriter->printIndent();
00629             fprintf(pFile, "Transform\n");
00630         }
00631 
00632         pWriter->printIndent();
00633         fprintf(pFile, "{\n");
00634 
00635         pWriter->incIndent(4);
00636 
00637         // decompose matrix.
00638         Matrix m = pTrans->getSFMatrix()->getValue();
00639         Vec3f translation, scale, center;
00640         Quaternion rotation, scaleOrientation;
00641         m.getTransform(translation, rotation, scale, scaleOrientation);
00642         
00643         pWriter->printIndent();
00644         fprintf(pFile, "center %f %f %f\n",
00645                 center[0],
00646                 center[1],
00647                 center[2]);
00648 
00649         rotation.getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00650 
00651         pWriter->printIndent();
00652         fprintf(pFile, "rotation %f %f %f %f\n",
00653                 rQX, rQY, rQZ, rQW);
00654 
00655         pWriter->printIndent();
00656         fprintf(pFile, "scale %f %f %f\n",
00657                 scale[0],
00658                 scale[1],
00659                 scale[2]);
00660 
00661         scaleOrientation.getValueAsAxisRad(rQX, rQY, rQZ, rQW);
00662 
00663         pWriter->printIndent();
00664         fprintf(pFile, "scaleOrientation %f %f %f %f\n",
00665                 rQX, rQY, rQZ, rQW);
00666 
00667         pWriter->printIndent();
00668         fprintf(pFile, "translation %f %f %f\n", 
00669                 translation[0],
00670                 translation[1],
00671                 translation[2]);
00672 
00673         pWriter->printIndent();
00674         fprintf(pFile, "children [\n");
00675 
00676         pWriter->incIndent(4);
00677     }
00678 
00679     return Action::Continue;
00680 }
00681 
00682 Action::ResultE VRMLWriteAction::writeTransformLeave(CNodePtr &,
00683                                                       Action   *pAction)
00684 {
00685     VRMLWriteAction *pWriter = dynamic_cast<VRMLWriteAction *>(pAction);
00686 
00687     if(pWriter == NULL)
00688     {
00689         return Action::Quit;
00690     }
00691 
00692     FDEBUG(("Write Transform Leave 0x%04x\n", pWriter->getMode()));
00693 
00694     if(pWriter->getMode() != VRMLWriteAction::OSGCollectFC)
00695     {
00696         FILE *pFile = pWriter->getFilePtr();
00697         
00698         if(pFile == NULL)    
00699         {
00700             return Action::Quit;
00701         }
00702 
00703         pWriter->decIndent(4);
00704 
00705         pWriter->printIndent();
00706         fprintf(pFile, "]\n");
00707 
00708         pWriter->decIndent(4);
00709 
00710         pWriter->printIndent();
00711         fprintf(pFile, "}\n");
00712     }
00713 
00714     return Action::Continue;
00715 }
00716 
00717 void VRMLWriteAction::writePoints(GeometryPtr      pGeo, 
00718                                   FILE            *pFile,
00719                                   VRMLWriteAction *pWriter)
00720 {
00721     if(pGeo == NullFC)
00722         return;
00723 
00724     GeoPositionsPtr pPos = pGeo->getPositions();
00725 
00726     if(pPos == NullFC)
00727         return;
00728 
00729     pWriter->printIndent();
00730     fprintf(pFile, "coord Coordinate\n");
00731 
00732     pWriter->printIndent();
00733     fprintf(pFile, "{\n");
00734     pWriter->incIndent(4);
00735 
00736     pWriter->printIndent();
00737     fprintf(pFile, "point [\n");
00738     pWriter->incIndent(4);
00739 
00740     for(UInt32 i = 0; i < pPos->getSize(); i++)
00741     {
00742         pWriter->printIndent();
00743 
00744         Pnt3f p;
00745         pPos->getValue(p,i);
00746         
00747         fprintf(pFile, "%f %f %f", p[0], p[1], p[2]);
00748 
00749         if(i == pPos->getSize() - 1)
00750         {
00751             fprintf(pFile, "\n");
00752         }
00753         else
00754         {
00755             fprintf(pFile, ", \n");
00756         }
00757     }
00758 
00759     pWriter->decIndent(4);
00760     pWriter->printIndent();
00761     fprintf(pFile, "]\n");
00762 
00763     pWriter->decIndent(4);
00764     pWriter->printIndent();
00765     fprintf(pFile, "}\n");
00766 
00767 }
00768 
00769 void VRMLWriteAction::writeNormals(GeometryPtr      pGeo, 
00770                                    FILE            *pFile,
00771                                    VRMLWriteAction *pWriter)
00772 {
00773     if(0 != (pWriter->getOptions() & VRMLWriteAction::OSGNoNormals))
00774         return;
00775 
00776     if(pGeo == NullFC)
00777         return;
00778 
00779     GeoNormalsPtr pNorm = pGeo->getNormals();
00780 
00781     if(pNorm == NullFC)
00782         return;
00783 
00784     pWriter->printIndent();
00785     fprintf(pFile, "normal Normal\n");
00786 
00787     pWriter->printIndent();
00788     fprintf(pFile, "{\n");
00789     pWriter->incIndent(4);
00790 
00791     pWriter->printIndent();
00792     fprintf(pFile, "vector [\n");
00793     pWriter->incIndent(4);
00794 
00795     for(UInt32 i = 0; i < pNorm->getSize(); i++)
00796     {
00797         pWriter->printIndent();
00798 
00799         Vec3f n;
00800         pNorm->getValue(n,i);
00801         
00802         fprintf(pFile, "%f %f %f", n[0], n[1], n[2]);
00803 
00804         if(i == pNorm->getSize() - 1)
00805         {
00806             fprintf(pFile, "\n");
00807         }
00808         else
00809         {
00810             fprintf(pFile, ", \n");
00811         }
00812     }
00813 
00814     pWriter->decIndent(4);
00815     pWriter->printIndent();
00816     fprintf(pFile, "]\n");
00817 
00818     pWriter->decIndent(4);
00819     pWriter->printIndent();
00820     fprintf(pFile, "}\n");
00821 }
00822 
00823 void VRMLWriteAction::writeColors(GeometryPtr      pGeo, 
00824                                   FILE            *pFile,
00825                                   VRMLWriteAction *pWriter)
00826 {
00827     if(pGeo == NullFC)
00828         return;
00829 
00830     GeoColorsPtr pCol = pGeo->getColors();
00831 
00832     if(pCol == NullFC)
00833         return;
00834 
00835     pWriter->printIndent();
00836     fprintf(pFile, "color Color\n");
00837 
00838     pWriter->printIndent();
00839     fprintf(pFile, "{\n");
00840     pWriter->incIndent(4);
00841 
00842     pWriter->printIndent();
00843     fprintf(pFile, "color [\n");
00844     pWriter->incIndent(4);
00845 
00846     for(UInt32 i = 0; i < pCol->getSize(); i++)
00847     {
00848         pWriter->printIndent();
00849 
00850         Color3f c;
00851         pCol->getValue(c,i);
00852         
00853         fprintf(pFile, "%f %f %f", c[0], c[1], c[2]);
00854 
00855         if(i == pCol->getSize() - 1)
00856         {
00857             fprintf(pFile, "\n");
00858         }
00859         else
00860         {
00861             fprintf(pFile, ", \n");
00862         }
00863     }
00864 
00865     pWriter->decIndent(4);
00866     pWriter->printIndent();
00867     fprintf(pFile, "]\n");
00868 
00869     pWriter->decIndent(4);
00870     pWriter->printIndent();
00871     fprintf(pFile, "}\n");
00872 }
00873 
00874 void VRMLWriteAction::writeTexCoords(GeometryPtr      pGeo, 
00875                                      FILE            *pFile,
00876                                      VRMLWriteAction *pWriter)
00877 {
00878     if(pGeo == NullFC)
00879         return;
00880 
00881     GeoTexCoordsPtr pTex = pGeo->getTexCoords();
00882 
00883     if(pTex == NullFC)
00884         return;
00885 
00886     pWriter->printIndent();
00887     fprintf(pFile, "texCoord TextureCoordinate\n");
00888 
00889     pWriter->printIndent();
00890     fprintf(pFile, "{\n");
00891     pWriter->incIndent(4);
00892 
00893     pWriter->printIndent();
00894     fprintf(pFile, "point [\n");
00895     pWriter->incIndent(4);
00896 
00897     for(UInt32 i = 0; i < pTex->getSize(); i++)
00898     {
00899         pWriter->printIndent();
00900 
00901         Vec2f t;
00902         pTex->getValue(t,i);
00903         
00904         fprintf(pFile, "%f %f", t[0], t[1]);
00905  
00906         if(i == pTex->getSize() - 1)
00907         {
00908             fprintf(pFile, "\n");
00909         }
00910         else
00911         {
00912             fprintf(pFile, ", \n");
00913         }
00914     }
00915 
00916     pWriter->decIndent(4);
00917     pWriter->printIndent();
00918     fprintf(pFile, "]\n");
00919 
00920     pWriter->decIndent(4);
00921     pWriter->printIndent();
00922     fprintf(pFile, "}\n");
00923 }
00924 
00925 void VRMLWriteAction::writeIndex(GeometryPtr      pGeo, 
00926                                  FILE            *pFile,
00927                                  VRMLWriteAction *pWriter)
00928 {
00929     if(pGeo == NullFC)
00930         return;
00931 
00932     GeoIndicesUI32Ptr  pIndex  = GeoIndicesUI32Ptr ::dcast(pGeo->getIndices());
00933     GeoPTypesUI8Ptr    pTypes  = GeoPTypesUI8Ptr   ::dcast(pGeo->getTypes());
00934     GeoPLengthsUI32Ptr pLength = GeoPLengthsUI32Ptr::dcast(pGeo->getLengths());
00935 
00936     if((pIndex  == NullFC) ||
00937        (pTypes  == NullFC) ||
00938        (pLength == NullFC))
00939     {
00940         return;
00941     }
00942 
00943     GeoIndicesUI32::StoredFieldType  *pIndexField  = pIndex ->getFieldPtr();
00944     GeoPTypesUI8::StoredFieldType    *pTypeField   = pTypes ->getFieldPtr();
00945     GeoPLengthsUI32::StoredFieldType *pLengthField = pLength->getFieldPtr();
00946 
00947     if(pIndexField          == NULL ||
00948        pIndexField->size()  == 0    ||
00949        pTypeField           == NULL ||
00950        pTypeField->size()   == 0    ||
00951        pLengthField         == NULL ||
00952        pLengthField->size() == 0)
00953     {
00954         return;
00955     }
00956 
00957     pWriter->printIndent();
00958     fprintf(pFile, "coordIndex [\n");
00959     pWriter->incIndent(4);
00960 
00961     TriangleIterator it;
00962 
00963     for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
00964     {
00965         pWriter->printIndent();
00966 
00967         for(UInt32 i = 0; i < 3; ++i)
00968         {
00969             fprintf(pFile, "%d, ", it.getPositionIndex(i));
00970         }
00971 /*
00972         fprintf(pFile, "%d,%d,%d,", it.getPositionIndex(0), 
00973                                     it.getPositionIndex(1), 
00974                                     it.getPositionIndex(2));
00975         if(it.getPositionIndex(3) != -1)
00976             fprintf(pFile, "%d,", it.getPositionIndex(3));
00977             */
00978         
00979         fprintf(pFile, "-1,\n");
00980     }
00981 
00982     pWriter->decIndent(4);
00983     pWriter->printIndent();
00984     fprintf(pFile, "]\n");
00985     
00986     if(pGeo->getNormals()           != NullFC && 
00987        pGeo->getNormals()->getSize() > 0      &&
00988        0 == (pWriter->getOptions() & VRMLWriteAction::OSGNoNormals))
00989     {
00990         pWriter->printIndent();
00991         fprintf(pFile, "normalIndex [\n");
00992         pWriter->incIndent(4);
00993 
00994         TriangleIterator it;
00995 
00996         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
00997         {
00998             pWriter->printIndent();
00999 
01000             for(UInt32 i = 0; i < 3; ++i)
01001             {
01002                 fprintf(pFile, "%d, ", it.getNormalIndex(i));
01003             }
01004 
01005 /*
01006             fprintf(pFile, "%d,%d,%d,", it.getNormalIndex(0), 
01007                                         it.getNormalIndex(1), 
01008                                         it.getNormalIndex(2));
01009             if(it.getNormalIndex(3) != -1)
01010                 fprintf(pFile, "%d,", it.getNormalIndex(3));
01011                 */
01012 
01013             fprintf(pFile, "-1,\n");
01014         }
01015 
01016         pWriter->decIndent(4);
01017         pWriter->printIndent();
01018         fprintf(pFile, "]\n");
01019     }
01020     
01021     if(pGeo->getColors() != NullFC && pGeo->getColors()->getSize() > 0)
01022     {
01023         pWriter->printIndent();
01024         fprintf(pFile, "colorIndex [\n");
01025         pWriter->incIndent(4);
01026 
01027         TriangleIterator it;
01028 
01029         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
01030         {
01031             pWriter->printIndent();
01032 
01033             for(UInt32 i = 0; i < 3; ++i)
01034             {
01035                 fprintf(pFile, " %d,", it.getColorIndex(i));
01036             }
01037 /*
01038             fprintf(pFile, "%d,%d,%d,", it.getColorIndex(0), 
01039                                         it.getColorIndex(1), 
01040                                         it.getColorIndex(2));
01041             if(it.getColorIndex(3) != -1)
01042                 fprintf(pFile, "%d,", it.getColorIndex(3));
01043                 */
01044 
01045             fprintf(pFile, "-1,\n");
01046         }
01047 
01048         pWriter->decIndent(4);
01049         pWriter->printIndent();
01050         fprintf(pFile, "]\n");
01051     }
01052     
01053     if(pGeo->getTexCoords() != NullFC && pGeo->getTexCoords()->getSize() > 0)
01054     {
01055         pWriter->printIndent();
01056         fprintf(pFile, "texCoordIndex [\n");
01057         pWriter->incIndent(4);
01058 
01059         TriangleIterator it;
01060 
01061         for(it = pGeo->beginTriangles(); it != pGeo->endTriangles(); ++it)
01062         {
01063             pWriter->printIndent();
01064 
01065             for(UInt32 i = 0; i < 3; ++i)
01066             {
01067                 fprintf(pFile, "%d,", it.getTexCoordsIndex(i));
01068             }
01069 /*
01070             fprintf(pFile, "%d,%d,%d,", it.getTexCoordsIndex(0), 
01071                                         it.getTexCoordsIndex(1), 
01072                                         it.getTexCoordsIndex(2));
01073             if(it.getTexCoordsIndex(3) != -1)
01074                 fprintf(pFile, "%d,", it.getTexCoordsIndex(3));
01075                 */
01076 
01077             fprintf(pFile, "-1,\n");
01078         }
01079 
01080         pWriter->decIndent(4);
01081         pWriter->printIndent();
01082         fprintf(pFile, "]\n");
01083     }
01084 }
01085 
01086 void VRMLWriteAction::writeLineIndex(GeometryPtr      pGeo, 
01087                                      FILE            *pFile,
01088                                      VRMLWriteAction *pWriter)
01089 {
01090     if(pGeo == NullFC)
01091         return;
01092 
01093     GeoPTypesUI8Ptr    pTypes  = GeoPTypesUI8Ptr   ::dcast(pGeo->getTypes());
01094     GeoPLengthsUI32Ptr pLength = GeoPLengthsUI32Ptr::dcast(pGeo->getLengths());
01095 
01096     if((pTypes  == NullFC) ||
01097        (pLength == NullFC))
01098     {
01099         return;
01100     }
01101 
01102     GeoPTypesUI8::StoredFieldType    *pTypeField   = pTypes->getFieldPtr();
01103     GeoPLengthsUI32::StoredFieldType *pLengthField = pLength->getFieldPtr();
01104 
01105     if(pTypeField           == NULL ||
01106        pTypeField->size()   == 0    ||
01107        pLengthField         == NULL ||
01108        pLengthField->size() == 0)
01109     {
01110         return;
01111     }
01112 
01113     pWriter->printIndent();
01114     fprintf(pFile, "coordIndex [\n");
01115     pWriter->incIndent(4);
01116 
01117     PrimitiveIterator it;
01118     UInt32            i;
01119 
01120     for(it = pGeo->beginPrimitives(); it != pGeo->endPrimitives(); ++it)
01121     {
01122         if(it.getType() == GL_LINES)
01123         {
01124             for(i = 0; i < it.getLength(); i += 2)
01125             {
01126                 pWriter->printIndent();
01127 
01128                 fprintf(pFile, "%d, %d, -1,\n", 
01129                         it.getPositionIndex(i),
01130                         it.getPositionIndex(i + 1));
01131             }
01132         }
01133         else if(it.getType() == GL_LINE_STRIP)
01134         {
01135             pWriter->printIndent();
01136 
01137             for(i = 0; i < it.getLength(); ++i)
01138             {
01139                 fprintf(pFile, "%d, ", it.getPositionIndex(i));
01140             }
01141 
01142             fprintf(pFile, "-1,\n");
01143         }
01144         else if(it.getType() == GL_LINE_LOOP)
01145         {
01146             pWriter->printIndent();
01147 
01148             for(i = 0; i < it.getLength(); ++i)
01149             {
01150                 fprintf(pFile, "%d, ", it.getPositionIndex(i));
01151             }
01152 
01153             fprintf(pFile, "%d, -1, \n", it.getPositionIndex(i - 1));
01154         }
01155     }
01156 
01157     pWriter->decIndent(4);
01158     pWriter->printIndent();
01159     fprintf(pFile, "]\n");
01160 
01161 
01162     if(pGeo->getColors() != NullFC && pGeo->getColors()->getSize() > 0)
01163     {
01164         pWriter->printIndent();
01165         fprintf(pFile, "colorIndex [\n");
01166         pWriter->incIndent(4);
01167 
01168         PrimitiveIterator it;
01169         UInt32            i;
01170         
01171         for(it = pGeo->beginPrimitives(); it != pGeo->endPrimitives(); ++it)
01172         {
01173             if(it.getType() == GL_LINES)
01174             {
01175                 for(i = 0; i < it.getLength(); i += 2)
01176                 {
01177                     pWriter->printIndent();
01178 
01179                     fprintf(pFile, "%d, %d, -1,\n", 
01180                             it.getColorIndex(i),
01181                             it.getColorIndex(i + 1));
01182                 }
01183             }
01184             else if(it.getType() == GL_LINE_STRIP)
01185             {
01186                 pWriter->printIndent();
01187                 
01188                 for(i = 0; i < it.getLength(); ++i)
01189                 {
01190                     fprintf(pFile, "%d, ", it.getColorIndex(i));
01191                 }
01192                 
01193                 fprintf(pFile, "-1,\n");
01194             }
01195             else if(it.getType() == GL_LINE_LOOP)
01196             {
01197                 pWriter->printIndent();
01198                 
01199                 for(i = 0; i < it.getLength(); ++i)
01200                 {
01201                     fprintf(pFile, "%d, ", it.getColorIndex(i));
01202                 }
01203                 
01204                 fprintf(pFile, "%d, -1, \n", it.getColorIndex(i - 1));
01205             }
01206         }
01207 
01208         pWriter->decIndent(4);
01209         pWriter->printIndent();
01210         fprintf(pFile, "]\n");
01211     }
01212 }
01213 
01214 void VRMLWriteAction::writeMaterial(GeometryPtr      pGeo, 
01215                                     FILE            *pFile,
01216                                     VRMLWriteAction *pWriter)
01217 {
01218     if(pGeo == NullFC)
01219         return;
01220 
01221     MaterialPtr pMat;
01222     
01223     pMat = pWriter->getMaterial();
01224     
01225     if(pMat == NullFC)
01226         pMat = pGeo->getMaterial();
01227 
01228     if(pMat == NullFC)
01229         pMat = OSG::getDefaultMaterial();
01230 
01231     if(pWriter->isWritten(pMat))
01232     {
01233         pWriter->printIndent();
01234         fprintf(pFile, "appearance USE App_%d\n", pWriter->getIndex(pMat));
01235         return;
01236     }
01237     
01238     StatePtr st = pMat->makeState();
01239     
01240     StateChunkPtr sChunk =
01241         st->getChunk(MaterialChunk::getStaticClassId());
01242     
01243     if(sChunk == NullFC)
01244         return;
01245     
01246     MaterialChunkPtr mChunk = MaterialChunkPtr::dcast(sChunk);
01247     
01248     if(mChunk == NullFC)
01249         return;
01250 
01251     pWriter->printIndent();
01252     fprintf(pFile, "appearance DEF App_%d Appearance\n", pWriter->setWritten(pMat));
01253     
01254     pWriter->printIndent();
01255     fprintf(pFile, "{\n");
01256     
01257     pWriter->incIndent(4);
01258     
01259     pWriter->printIndent();
01260     fprintf(pFile, "material Material\n");
01261     
01262     pWriter->printIndent();
01263     fprintf(pFile, "{\n");
01264     
01265     pWriter->incIndent(4);
01266 
01267     Real32 rAmbient = 0.f;
01268 
01269     if(osgabs(mChunk->getDiffuse()[0]) > Eps)
01270     {
01271         rAmbient = mChunk->getAmbient()[0] / mChunk->getDiffuse()[0];
01272     }
01273     else if(osgabs(mChunk->getDiffuse()[1]) > Eps)
01274     {
01275         rAmbient = mChunk->getAmbient()[1] / mChunk->getDiffuse()[1];
01276     }
01277     else if(osgabs(mChunk->getDiffuse()[2]) >