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