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