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

OSGVRMLNodeDescs.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #define OSG_COMPILEVRMLNODEDESCINST
00040 
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 
00044 #include "OSGConfig.h"
00045 
00046 #include <iostream>
00047 #include <fstream>
00048 
00049 #include "OSGVRMLNodeDescs.h"
00050 #include <OSGLog.h>
00051 
00052 #include <OSGNode.h>
00053 #include <OSGNodeCore.h>
00054 #include <OSGGroup.h>
00055 #include <OSGComponentTransform.h>
00056 #include <OSGGeometry.h>
00057 #include <OSGMaterialGroup.h>
00058 #include <OSGSimpleGeometry.h>
00059 #include <OSGExtrusionGeometry.h>
00060 #include <OSGTextureChunk.h>
00061 #include <OSGTextureTransformChunk.h>
00062 #include <OSGGeoFunctions.h>
00063 #include <OSGDistanceLOD.h>
00064 #include <OSGSwitch.h>
00065 #include <OSGInline.h>
00066 #include <OSGImage.h>
00067 #include <OSGSceneFileHandler.h>
00068 #include <OSGImageFileHandler.h>
00069 #include <OSGZStream.h>
00070 
00071 #include <OSGVRMLFile.h>
00072 
00073 #ifndef OSG_LOG_MODULE
00074 #define OSG_LOG_MODULE "VRMLLoader"
00075 #endif
00076 
00077 //#define OSG_DEBUG_VRML
00078 
00079 #ifndef OSG_DO_DOC
00080 #    ifdef OSG_DEBUG_VRML
00081 #        define OSG_VRML_ARG(ARG) ARG
00082 #    else
00083 #        define OSG_VRML_ARG(ARG)
00084 #    endif
00085 #else
00086 #    define OSG_VRML_ARG(ARG) ARG
00087 #endif
00088 
00089 OSG_USING_NAMESPACE
00090 
00091 
00092 
00101 #ifdef WIN32
00102 OSG_FC_ST_TYPE_FUNCTIONS_INL_TMPL_DEF(GenericAttDesc,
00103                                       DynFieldAttachment)
00104 #endif
00105 
00106 OSG_DYNFIELD_FC_DLLEXPORT_DEF(DynFieldAttachment,
00107                               GenericAttDesc,
00108                               OSG_SYSTEMLIB_DLLTMPLMAPPING);
00109 
00110 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
00111 #pragma warning (disable : 383)
00112 #endif
00113 
00114 //---------------------------------------------------------------------------
00115 //  Class
00116 //---------------------------------------------------------------------------
00117 
00123 UInt32 VRMLNodeDesc::_uiIndent = 0;
00124 
00125 /*-------------------------------------------------------------------------*/
00126 /*                            Static Get                                   */
00127 
00128 UInt32 VRMLNodeDesc::getIndent(void)
00129 {
00130     return _uiIndent;
00131 }
00132 
00133 void VRMLNodeDesc::incIndent(void)
00134 {
00135     _uiIndent += 4;
00136 }
00137 
00138 void VRMLNodeDesc::decIndent(void)
00139 {
00140     if(_uiIndent < 4)
00141     {
00142         PWARNING << "Indent smaller 4 decremented" << std::endl;
00143 
00144         _uiIndent = 4;
00145     }
00146 
00147     _uiIndent -= 4;
00148 }
00149 
00150 void VRMLNodeDesc::resetIndent(void)
00151 {
00152     _uiIndent = 0;
00153 }
00154 
00155 /*-------------------------------------------------------------------------*/
00156 /*                            Constructors                                 */
00157 
00158 VRMLNodeDesc::VRMLNodeDesc(void) :
00159     _mFieldTypes   (),
00160 
00161     _pGenAtt       (NullFC),
00162 
00163     _pNodeProto    (NullFC),
00164     _pNodeCoreProto(NullFC),
00165 
00166     _pCurrField    (NULL),
00167 
00168     _szCurrentName (),
00169     _bSaveOnEnd    (false)
00170 {
00171 }
00172 
00173 /*-------------------------------------------------------------------------*/
00174 /*                             Destructor                                  */
00175 
00176 VRMLNodeDesc::~VRMLNodeDesc(void)
00177 {
00178 }
00179 
00180 /*-------------------------------------------------------------------------*/
00181 /*                              Helper                                     */
00182 
00183 void VRMLNodeDesc::init(const Char8 *szName)
00184 {
00185     if(szName == NULL)
00186     {
00187         _pNodeCoreProto = Group::create();
00188     }
00189     else if(stringcasecmp(szName, "Transform") == 0)
00190     {
00191         _pNodeCoreProto = ComponentTransform::create();
00192     }
00193     else
00194     {
00195         _pNodeCoreProto = Group::create();
00196     }
00197 
00198     _pNodeProto = Node::create();
00199 
00200     _pGenAtt    = GenericAtt::create();
00201     _pGenAtt->setInternal(true);
00202 }
00203 
00204 
00205 void VRMLNodeDesc::reset(void)
00206 {
00207 }
00208 
00209 void VRMLNodeDesc::setOnEndSave(const Char8 *szName)
00210 {
00211     _szCurrentName = szName; // does that make a copy? I expect it to...
00212     _bSaveOnEnd = true;
00213 }
00214 
00215 void VRMLNodeDesc::clearOnEndSave(void)
00216 {
00217     _bSaveOnEnd = false;
00218 }
00219 
00220 bool VRMLNodeDesc::getOnEndSave(void)
00221 {
00222     return _bSaveOnEnd;
00223 }
00224 
00225 const Char8 *VRMLNodeDesc::getSavename(void)
00226 {
00227     return _szCurrentName.c_str();
00228 }
00229 
00230 FieldContainerPtr VRMLNodeDesc::getSaveFieldContainer(void)
00231 {
00232     return NullFC;
00233 }
00234 
00235 /*-------------------------------------------------------------------------*/
00236 /*                                Field                                    */
00237 
00238 Field *VRMLNodeDesc::getField(const Char8 *szFieldname)
00239 {
00240     return getField(_pNodeProto, _pNodeCoreProto, _pGenAtt, szFieldname);
00241 }
00242 
00243 void VRMLNodeDesc::getFieldAndDesc(
00244     FieldContainerPtr        pFC,
00245     const Char8            * szFieldname,
00246     Field                  *&pField,
00247     const FieldDescription *&pDesc)
00248 {
00249     FieldContainerPtr pTmpFC    = NullFC;
00250     NodePtr           pNode     = NullFC;
00251     NodeCorePtr       pNodeCore = NullFC;
00252 
00253     pField = NULL;
00254     pDesc  = NULL;
00255 
00256     if(pFC == NullFC)
00257         return;
00258 
00259 #ifdef OSG_DEBUG_VRML
00260     indentLog(getIndent(), PINFO);
00261     PINFO << "VRMLNodeDesc::getFieldAndDesc : looking for "
00262           << szFieldname
00263           << std::endl;
00264 
00265     incIndent();
00266 #endif
00267 
00268     pField = pFC->getField(szFieldname);
00269 
00270 #ifdef OSG_DEBUG_VRML
00271     indentLog(getIndent(), PINFO);
00272     PINFO << "Got this from fieldcontainer : " << pField << std::endl;
00273 #endif
00274 
00275     if(pField != NULL)
00276     {
00277         pDesc = pFC->getType().findFieldDescription(szFieldname);
00278 
00279 #ifdef OSG_DEBUG_VRML
00280         decIndent();
00281 #endif
00282 
00283         return;
00284     }
00285 
00286     if(pFC->getType().isNode() == true)
00287     {
00288         pNode     = NodePtr::dcast(pFC);
00289 
00290         pNodeCore = pNode->getCore();
00291 
00292         if(pNodeCore != NullFC)
00293         {
00294             pField    = pNodeCore->getField(szFieldname);
00295 
00296 #ifdef OSG_DEBUG_VRML
00297             indentLog(getIndent(), PINFO);
00298             PINFO << "Got this from nodecore : " << pField << std::endl;
00299 #endif
00300         }
00301 
00302         if(pField != NULL)
00303         {
00304             pDesc = pNodeCore->getType().findFieldDescription(szFieldname);
00305         }
00306         else
00307         {
00308             pTmpFC = pNode->findAttachment(
00309                 GenericAtt::getClassType().getGroupId());
00310 
00311             if(pTmpFC != NullFC)
00312             {
00313                 pField = pTmpFC->getField(szFieldname);
00314             }
00315 
00316 #ifdef OSG_DEBUG_VRML
00317             indentLog(getIndent(), PINFO);
00318             PINFO << "Got this from node attachment : " << pField << std::endl;
00319 #endif
00320             if(pField == NULL)
00321             {
00322                 pTmpFC =
00323                     pNodeCore->findAttachment(
00324                         GenericAtt::getClassType().getGroupId());
00325 
00326                 if(pTmpFC != NullFC)
00327                 {
00328                     pField = pTmpFC->getField(szFieldname);
00329                 }
00330 
00331 #ifdef OSG_DEBUG_VRML
00332                 indentLog(getIndent(), PINFO);
00333                 PINFO << "Got this from nodecore attachment : "
00334                       << pField << std::endl;
00335 #endif
00336             }
00337 
00338             if(pField != NULL)
00339             {
00340                 pDesc = pTmpFC->getType().findFieldDescription(szFieldname);
00341             }
00342         }
00343     }
00344     else if(pFC->getType().isNodeCore() == true)
00345     {
00346         pNodeCore = NodeCorePtr::dcast(pFC);
00347 
00348         pTmpFC = pNodeCore->findAttachment(
00349             GenericAtt::getClassType().getGroupId());
00350 
00351         if(pTmpFC != NullFC)
00352         {
00353             pField = pTmpFC->getField(szFieldname);
00354         }
00355 
00356         if(pField != NULL)
00357         {
00358             pDesc = pTmpFC->getType().findFieldDescription(szFieldname);
00359         }
00360 
00361 #ifdef OSG_DEBUG_VRML
00362         indentLog(getIndent(), PINFO);
00363         PINFO << "Got this from nodecore attachment : "
00364               << pField << std::endl;
00365 #endif
00366     }
00367 
00368 #ifdef OSG_DEBUG_VRML
00369     decIndent();
00370 #endif
00371 }
00372 
00373 /*-------------------------------------------------------------------------*/
00374 /*                              Prototypes                                 */
00375 
00376 bool VRMLNodeDesc::prototypeAddField(const Char8  *OSG_VRML_ARG(szFieldType),
00377                                      const UInt32  uiFieldTypeId,
00378                                      const Char8  *szFieldName)
00379 {
00380     FieldDescription *pDesc = NULL;
00381     FieldType        *pType = NULL;
00382 
00383     Field *pField = getField(_pNodeProto,
00384                              _pNodeCoreProto,
00385                              _pGenAtt,
00386                               szFieldName);
00387 
00388 
00389 #ifdef OSG_DEBUG_VRML
00390     indentLog(getIndent(), PINFO);
00391     PINFO << "VRMLNodeDesc::prototypeAddField | getField "
00392           << szFieldName
00393           << "  returned : "
00394           << pField
00395           << std::endl;
00396 #endif
00397 
00398     if(pField == NULL)
00399     {
00400         pType = FieldFactory::the().getFieldType(uiFieldTypeId);
00401 
00402         if(pType == NULL)
00403         {
00404             PWARNING << "VRMLNodeDesc::prototypeAddField "
00405                      << "Could not get fieldtype "
00406                      << uiFieldTypeId << " "
00407                      << szFieldName << " "
00408                      << std::endl;
00409 
00410             return false;
00411         }
00412 
00413 #ifdef OSG_DEBUG_VRML
00414         indentLog(getIndent(), PINFO);
00415         PINFO << "VRMLNodeDesc::prototypeAddField | got fieldtype : "
00416               << uiFieldTypeId
00417               << " "
00418               << pType->getName()
00419               << " "
00420               << pType->getId()
00421               << std::endl;
00422 #endif
00423 
00424         pDesc = new FieldDescription(*pType,
00425                                      szFieldName,
00426                                      0, 0,
00427                                      false,
00428                                      (FieldIndexAccessMethod)
00429                                      &GenericAtt::getDynamicField);
00430 
00431         _pGenAtt->addField(*pDesc);
00432 
00433         _pCurrField = getField(_pNodeProto,
00434                                _pNodeCoreProto,
00435                                _pGenAtt,
00436                                 szFieldName);
00437 
00438         delete pDesc;
00439 
00440 #ifdef OSG_DEBUG_VRML
00441         indentLog(getIndent(), PINFO);
00442         PINFO << "VRMLNodeDesc::prototypeAddField | field added : "
00443               << szFieldType
00444               << " "
00445               << uiFieldTypeId
00446               << " "
00447               << szFieldName
00448               << " "
00449               << _pCurrField
00450               << std::endl;
00451 #endif
00452 
00453         if(_pCurrField != NULL)
00454             return true;
00455         else
00456             return false;
00457     }
00458     else
00459     {
00460         if((_pGenAtt != NullFC                     ) &&
00461            (_pGenAtt->getField(szFieldName) != NULL))
00462         {
00463             PWARNING << "VRMLNodeDesc::prototypeAddField | "
00464                      << "Could not add field "
00465                      << szFieldName
00466                      << " a second time"
00467                      << std::endl;
00468         }
00469 
00470         return false;
00471     }
00472 }
00473 
00474 void VRMLNodeDesc::prototypeAddFieldValue(const Char8 *szFieldVal)
00475 {
00476     if(_pCurrField       != NULL)
00477     {
00478         _pCurrField->pushValueByStr(szFieldVal);
00479     }
00480 }
00481 
00482 void VRMLNodeDesc::endProtoInterface(void)
00483 {
00484 }
00485 
00486 /*-------------------------------------------------------------------------*/
00487 /*                                Node                                     */
00488 
00489 FieldContainerPtr VRMLNodeDesc::beginNode(const Char8      *,
00490                                           const Char8      *,
00491                                           FieldContainerPtr)
00492 {
00493     FieldContainerPtr returnValue = NullFC;
00494     NodePtr           pNode       = NullFC;
00495     NodeCorePtr       pCore       = NullFC;
00496     GenericAttPtr     pAtt        = NullFC;
00497 
00498     if(_pNodeProto != NullFC)
00499     {
00500         returnValue = _pNodeProto->shallowCopy();
00501 
00502         if(_pNodeCoreProto != NullFC)
00503         {
00504             FieldContainerPtr pCoreClone = _pNodeCoreProto->shallowCopy();
00505 
00506             pNode = NodePtr    ::dcast(returnValue);
00507             pCore = NodeCorePtr::dcast(pCoreClone );
00508 
00509             beginEditCP(pNode, Node::CoreFieldMask);
00510             {
00511                 pNode->setCore(pCore);
00512             }
00513             endEditCP  (pNode, Node::CoreFieldMask);
00514         }
00515 
00516         if(_pGenAtt != NullFC)
00517         {
00518             FieldContainerPtr pAttClone = _pGenAtt->emptyCopy();
00519 
00520             pAtt = GenericAttPtr::dcast(pAttClone);
00521 
00522             if(pAtt != NullFC)
00523             {
00524                 pAtt->setInternal(true);
00525             }
00526 
00527             if(pCore != NullFC)
00528             {
00529                 pCore->addAttachment(pAtt);
00530             }
00531             else
00532             {
00533                 pNode->addAttachment(pAtt);
00534             }
00535         }
00536     }
00537 
00538     return returnValue;
00539 }
00540 
00541 void VRMLNodeDesc::endNode(FieldContainerPtr)
00542 {
00543 }
00544 
00545 /*-------------------------------------------------------------------------*/
00546 /*                             Field Value                                 */
00547 
00548 void VRMLNodeDesc::addFieldValue(      Field *pField,
00549                                     const Char8   *szFieldVal)
00550 {
00551     if(pField != NULL)
00552     {
00553         pField->pushValueByStr(szFieldVal);
00554     }
00555 }
00556 
00557 bool VRMLNodeDesc::use(FieldContainerPtr)
00558 {
00559     return false;
00560 }
00561 
00562 
00563 /*-------------------------------------------------------------------------*/
00564 /*                                Dump                                     */
00565 
00566 void VRMLNodeDesc::dump(const Char8 *szNodeName)
00567 {
00568     fprintf(stderr, "\tDefault %s\n", szNodeName);
00569 
00570     fprintf(stderr, "\t\tGenAtt        %p\n", &(*_pGenAtt));
00571     fprintf(stderr, "\t\tNodeProto     %p\n", &(*_pNodeProto));
00572     fprintf(stderr, "\t\tNodeCoreProto %p\n", &(*_pNodeCoreProto));
00573 
00574     std::string stringVal;
00575 
00576     if(_pGenAtt != NullFC)
00577     {
00578         fprintf(stderr, "\t\t%u Desc\n",
00579                 _pGenAtt->getType().getNumFieldDescs());
00580 
00581         for(UInt32 i = 2; i <= _pGenAtt->getType().getNumFieldDescs(); i++)
00582         {
00583             FieldDescription *pFieldDesc =
00584                 _pGenAtt->getType().getFieldDescription(i);
00585             Field            *pField     =
00586                 _pGenAtt->getDynamicField(i);
00587 
00588             stringVal.erase(stringVal.begin(),
00589                             stringVal.end());
00590 
00591             pField->getValueByStr(stringVal);
00592 
00593             fprintf(stderr, "\t\t%s %s %s\n",
00594                     pFieldDesc->getCName(),
00595                     pFieldDesc->getFieldType().getCName(),
00596                     stringVal.c_str());
00597         }
00598     }
00599 }
00600 
00601 /*-------------------------------------------------------------------------*/
00602 /*                                Get                                      */
00603 
00604 Field *VRMLNodeDesc::getField(      FieldContainerPtr  pFC1,
00605                                     FieldContainerPtr  pFC2,
00606                                     GenericAttPtr      pGenAtt,
00607                               const Char8             *szFieldname)
00608 {
00609     Field *returnValue = NULL;
00610 
00611     if(szFieldname == NULL)
00612     {
00613         return returnValue;
00614     }
00615 
00616 #ifdef OSG_DEBUG_VRML
00617     indentLog(getIndent(), PINFO);
00618     PINFO << "VRMLNodeDesc::getField " << std::endl;
00619 
00620     incIndent();
00621 
00622     indentLog(getIndent(), PINFO);
00623     PINFO << "Trying to find field : " << szFieldname << std::endl;
00624 #endif
00625 
00626     if(pFC1 != NullFC)
00627     {
00628         returnValue = pFC1->getField(szFieldname);
00629     }
00630 
00631 #ifdef OSG_DEBUG_VRML
00632     incIndent();
00633 
00634     indentLog(getIndent(), PINFO);
00635     PINFO << "Got this from node : " << returnValue << std::endl;
00636 #endif
00637 
00638     if(returnValue != NULL)
00639         return returnValue;
00640 
00641     if(pFC2 != NullFC)
00642     {
00643         returnValue = pFC2->getField(szFieldname);
00644 
00645 #ifdef OSG_DEBUG_VRML
00646         indentLog(getIndent(), PINFO);
00647         PINFO << "Got this from nodecore : " << returnValue << std::endl;
00648 #endif
00649     }
00650     else
00651     {
00652 #ifdef OSG_DEBUG_VRML
00653         indentLog(getIndent(), PINFO);
00654         PINFO << "No core to check" << std::endl;
00655 #endif
00656     }
00657 
00658 
00659     if(returnValue != NULL)
00660         return returnValue;
00661 
00662     if(pGenAtt != NullFC)
00663     {
00664         returnValue = pGenAtt->getField(szFieldname);
00665     }
00666 
00667 #ifdef OSG_DEBUG_VRML
00668     indentLog(getIndent(), PINFO);
00669     PINFO << "Got this from attachment : " << returnValue << std::endl;
00670 
00671     decIndent();
00672     decIndent();
00673 #endif
00674 
00675     return returnValue;
00676 }
00677 
00678 
00679 
00680 
00681 //---------------------------------------------------------------------------
00682 //  Class
00683 //---------------------------------------------------------------------------
00684 
00690 /*-------------------------------------------------------------------------*/
00691 /*                            Constructors                                 */
00692 
00693 VRMLShapeDesc::VRMLShapeDesc(void) :
00694     Inherited     (),
00695 
00696     _pMaterialDesc(NULL)
00697 {
00698 }
00699 
00700 /*-------------------------------------------------------------------------*/
00701 /*                             Destructor                                  */
00702 
00703 VRMLShapeDesc::~VRMLShapeDesc(void)
00704 {
00705 }
00706 
00707 /*-------------------------------------------------------------------------*/
00708 /*                               Helper                                    */
00709 
00710 void VRMLShapeDesc::init(const Char8 *OSG_VRML_ARG(szName))
00711 {
00712 #ifdef OSG_DEBUG_VRML
00713     indentLog(getIndent(), PINFO);
00714     PINFO << "ShapeDesc::init : " << szName << std::endl;
00715 #endif
00716 
00717     _pNodeProto     = Node::create();
00718     _pNodeCoreProto = MaterialGroup::create();
00719 
00720     _pGenAtt        = GenericAtt::create();
00721     _pGenAtt->setInternal(true);
00722 }
00723 
00724 void VRMLShapeDesc::setMaterialDesc(VRMLMaterialDesc *pMaterialDesc)
00725 {
00726     _pMaterialDesc = pMaterialDesc;
00727 }
00728 
00729 /*-------------------------------------------------------------------------*/
00730 /*                                Get                                      */
00731 
00732 bool VRMLShapeDesc::prototypeAddField(const Char8  *szFieldType,
00733                                       const UInt32  uiFieldTypeId,
00734                                       const Char8  *szFieldname)
00735 {
00736     bool returnValue = false;
00737 
00738 #ifdef OSG_DEBUG_VRML
00739     indentLog(getIndent(), PINFO);
00740     PINFO << "VRMLShapeDesc::prototypeAddField | add request : "
00741           << szFieldname
00742           << std::endl;
00743 #endif
00744 
00745     _pCurrField = NULL;
00746 
00747     if(szFieldname == NULL)
00748         return false;
00749 
00750     incIndent();
00751 
00752     if(stringcasecmp("geometry", szFieldname) == 0)
00753     {
00754         _pCurrField = _pNodeProto->getField("children");
00755         returnValue = true;
00756 
00757 #ifdef OSG_DEBUG_VRML
00758         indentLog(getIndent(), PINFO);
00759         PINFO << "VRMLShapeDesc::prototypeAddField | request internal : "
00760               << szFieldname
00761               << " "
00762               << _pCurrField
00763               << std::endl;
00764 #endif
00765     }
00766 
00767     if(stringcasecmp("appearance", szFieldname) == 0)
00768     {
00769         _pCurrField = _pNodeCoreProto->getField("material");
00770         returnValue = true;
00771 
00772 #ifdef OSG_DEBUG_VRML
00773         indentLog(getIndent(), PINFO);
00774 
00775         PINFO << "VRMLShapeDesc::prototypeAddField | request internal : "
00776               << szFieldname
00777               << " "
00778               << _pCurrField
00779               << std::endl;
00780 #endif
00781     }
00782 
00783     if(_pCurrField == NULL)
00784     {
00785         returnValue =  Inherited::prototypeAddField(szFieldType,
00786                                                     uiFieldTypeId,
00787                                                     szFieldname);
00788     }
00789 
00790 #ifdef OSG_DEBUG_VRML
00791     decIndent();
00792 #endif
00793 
00794     return returnValue;
00795 }
00796 
00797 void VRMLShapeDesc::getFieldAndDesc(
00798           FieldContainerPtr   pFC,
00799     const Char8             * szFieldname,
00800           Field             *&pField,
00801     const FieldDescription  *&pDesc)
00802 {
00803     if(szFieldname == NULL)
00804         return;
00805 
00806     if(pFC == NullFC)
00807         return;
00808 
00809 #ifdef OSG_DEBUG_VRML
00810     indentLog(getIndent(), PINFO);
00811     PINFO << "VRMLShapeDesc::getFieldAndDesc : looking for "
00812           << szFieldname
00813           << std::endl;
00814 
00815     incIndent();
00816 #endif
00817 
00818     if(stringcasecmp("geometry", szFieldname) == 0)
00819     {
00820 #ifdef OSG_DEBUG_VRML
00821         indentLog(getIndent(), PINFO);
00822         PINFO << "VRMLShapeDesc::getFieldAndDesc : request internal "
00823               << szFieldname
00824               << std::endl;
00825 #endif
00826 
00827         pField = pFC->getField("children");
00828 
00829         if(pField != NULL)
00830             pDesc = pFC->getType().findFieldDescription("children");
00831     }
00832     else if(stringcasecmp("appearance", szFieldname) == 0)
00833     {
00834 #ifdef OSG_DEBUG_VRML
00835         indentLog(getIndent(), PINFO);
00836         PINFO << "VRMLShapeDesc::getFieldAndDesc : request internal "
00837               << szFieldname
00838               << std::endl;
00839 #endif
00840 
00841         NodePtr pNode = NodePtr::dcast(pFC);
00842 
00843         if(pNode != NullFC)
00844         {
00845             if(pNode->getCore() != NullFC)
00846             {
00847                 pField = pNode->getCore()->getField("material");
00848 
00849                 if(pField != NULL)
00850                 {
00851                     pDesc =
00852                         pNode->getCore()->getType().findFieldDescription(
00853                             "material");
00854                 }
00855             }
00856         }
00857         else
00858         {
00859             VRMLNodeDesc::getFieldAndDesc(pFC,
00860                                           szFieldname,
00861                                           pField,
00862                                           pDesc);
00863         }
00864     }
00865     else
00866     {
00867         VRMLNodeDesc::getFieldAndDesc(pFC,
00868                                       szFieldname,
00869                                       pField,
00870                                       pDesc);
00871     }
00872 
00873 #ifdef OSG_DEBUG_VRML
00874     decIndent();
00875 #endif
00876 }
00877 
00878 /*-------------------------------------------------------------------------*/
00879 /*                                Node                                     */
00880 
00881 FieldContainerPtr VRMLShapeDesc::beginNode(const Char8            *,
00882                                            const Char8            *,
00883                                                  FieldContainerPtr)
00884 {
00885     NodePtr           pNode     = NullFC;
00886     NodeCorePtr       pNodeCore = NullFC;
00887 
00888     if(_pNodeProto != NullFC)
00889     {
00890         pNode = NodePtr::dcast(_pNodeProto->shallowCopy());
00891 
00892         if(_pNodeCoreProto != NullFC)
00893         {
00894             pNodeCore = NodeCorePtr::dcast(_pNodeCoreProto->shallowCopy());
00895 
00896             beginEditCP(pNode, Node::CoreFieldMask);
00897             {
00898                 pNode->setCore(pNodeCore);
00899             }
00900             endEditCP  (pNode, Node::CoreFieldMask);
00901         }
00902     }
00903 
00904 #ifdef OSG_DEBUG_VRML
00905     indentLog(getIndent(), PINFO);
00906     PINFO << "Begin Shape " << &(*pNode) << std::endl;
00907 
00908     incIndent();
00909 #endif
00910 
00911     return pNode;
00912 }
00913 
00914 void VRMLShapeDesc::endNode(FieldContainerPtr pFC)
00915 {
00916     if(pFC != NullFC)
00917     {
00918         NodePtr pNode = NodePtr::dcast(pFC);
00919 
00920         if(pNode != NullFC && pNode->getCore() == NullFC)
00921         {
00922             PWARNING << "warning empty material, using default\n" << std::endl;
00923 
00924             MaterialGroupPtr pMatGroup = MaterialGroup::create();
00925 
00926             beginEditCP(pMatGroup);
00927             {
00928                 pMatGroup->setMaterial(_pMaterialDesc->getDefaultMaterial());
00929             }
00930             endEditCP(pMatGroup);
00931 
00932             beginEditCP(pNode, Node::CoreFieldMask);
00933             {
00934                 pNode->setCore(pMatGroup);
00935             }
00936             endEditCP  (pNode, Node::CoreFieldMask);
00937         }
00938         else
00939         {
00940             MaterialGroupPtr pMatGroup;
00941 
00942             pMatGroup = MaterialGroupPtr::dcast(pNode->getCore());
00943 
00944             if(pMatGroup != NullFC)
00945             {
00946                 if(pMatGroup->getMaterial() == NullFC)
00947                 {
00948                     pMatGroup->setMaterial(
00949                         _pMaterialDesc->getDefaultMaterial());
00950                 }
00951             }
00952         }
00953     }
00954 
00955 #ifdef OSG_DEBUG_VRML
00956     decIndent();
00957 
00958     indentLog(getIndent(), PINFO);
00959     PINFO << "End Shape " << &(*pFC) << std::endl;
00960 #endif
00961 }
00962 
00963 /*-------------------------------------------------------------------------*/
00964 /*                                Dump                                     */
00965 
00966 void VRMLShapeDesc::dump(const Char8 *)
00967 {
00968 }
00969 
00970 
00971 
00972 
00973 //---------------------------------------------------------------------------
00974 //  Class
00975 //---------------------------------------------------------------------------
00976 
00982 /*-------------------------------------------------------------------------*/
00983 /*                            Constructors                                 */
00984 
00985 VRMLGeometryDesc::VRMLGeometryDesc(bool bIsFaceSet) :
00986     Inherited     (),
00987 
00988     _bIsFaceSet   (bIsFaceSet),
00989 
00990     _bInIndex     (false),
00991     _uiNumVertices(0),
00992 
00993     _pTypeField   (NullFC    ),
00994     _pLengthField (NullFC    )
00995 {
00996 }
00997 
00998 /*-------------------------------------------------------------------------*/
00999 /*                             Destructor                                  */
01000 
01001 VRMLGeometryDesc::~VRMLGeometryDesc(void)
01002 {
01003 }
01004 
01005 /*-------------------------------------------------------------------------*/
01006 /*                               Helper                                    */
01007 
01008 void VRMLGeometryDesc::init(const Char8 *OSG_VRML_ARG(szName))
01009 {
01010 #ifdef OSG_DEBUG_VRML
01011     indentLog(getIndent(), PINFO);
01012     PINFO << "GeoDesc::init : " << szName << std::endl;
01013 #endif
01014 
01015     _pNodeProto     = Node::create();
01016     _pNodeCoreProto = Geometry::create();
01017 
01018     _pGenAtt = GenericAtt::create();
01019     _pGenAtt->setInternal(true);
01020 }
01021 
01022 /*-------------------------------------------------------------------------*/
01023 /*                                Get                                      */
01024 
01025 bool VRMLGeometryDesc::prototypeAddField(const Char8  *szFieldType,
01026                                          const UInt32  uiFieldTypeId,
01027                                          const Char8  *szFieldname)
01028 {
01029     bool bFound = false;
01030 
01031     _pCurrField = NULL;
01032 
01033     if(szFieldname == NULL)
01034         return false;
01035 
01036     if(stringcasecmp("coord", szFieldname) == 0)
01037     {
01038         bFound = true;
01039     }
01040     else if(stringcasecmp("normal", szFieldname) == 0)
01041     {
01042         bFound = true;
01043     }
01044     else if(stringcasecmp("color", szFieldname) == 0)
01045     {
01046         bFound = true;
01047     }
01048     else if(stringcasecmp("texCoord", szFieldname) == 0)
01049     {
01050         bFound = true;
01051     }
01052 
01053     if(bFound == true)
01054     {
01055 #ifdef OSG_DEBUG_VRML
01056         indentLog(getIndent(), PINFO);
01057         PINFO << "GeoDesc::prototypeAddField : internal "
01058               << szFieldname << std::endl;
01059 #endif
01060 
01061         return true;
01062     }
01063     else
01064     {
01065         return Inherited::prototypeAddField(szFieldType,
01066                                             uiFieldTypeId,
01067                                             szFieldname);
01068     }
01069 }
01070 
01071 
01072 void VRMLGeometryDesc::getFieldAndDesc(
01073           FieldContainerPtr   pFC,
01074     const Char8             * szFieldname,
01075           Field             *&pField,
01076     const FieldDescription  *&pDesc)
01077 {
01078 #ifdef OSG_DEBUG_VRML
01079     indentLog(getIndent(), PINFO);
01080     PINFO << "GeoDesc::getFieldAndDesc : request "
01081           << szFieldname
01082           << std::endl;
01083 #endif
01084 
01085     if(szFieldname == NULL)
01086         return;
01087 
01088     if(pFC == NullFC)
01089         return;
01090 
01091     NodePtr pNode = NodePtr::dcast(pFC);
01092 
01093     if(pNode == NullFC)
01094     {
01095         PWARNING << "GeoDesc::getFieldAndDesc : No Node" << std::endl;
01096         return;
01097     }
01098 
01099     NodeCorePtr pNodeCore = pNode->getCore();
01100 
01101     GeometryPtr pGeo      = GeometryPtr::dcast(pNodeCore);
01102 
01103     if(pGeo == NullFC)
01104     {
01105         PWARNING << "GeoDesc::getFieldAndDesc : No Geo" << std::endl;
01106         return;
01107     }
01108 
01109     _bInIndex = false;
01110 
01111     if(stringcasecmp("coord", szFieldname) == 0)
01112     {
01113 #ifdef OSG_DEBUG_VRML
01114         indentLog(getIndent(), PINFO);
01115         PINFO << "GeoDesc::getFieldAndDesc : internal "
01116               << szFieldname << std::endl;
01117 #endif
01118         pField = pGeo->getField("positions");
01119 
01120         if(pField != NULL)
01121             pDesc = pGeo->getType().findFieldDescription("positions");
01122     }
01123     else if(stringcasecmp("normal", szFieldname) == 0)
01124     {
01125 #ifdef OSG_DEBUG_VRML
01126         indentLog(getIndent(), PINFO);
01127         PINFO << "GeoDesc::getFieldAndDesc : internal "
01128               << szFieldname << std::endl;
01129 #endif
01130 
01131         pField = pGeo->getField("normals");
01132 
01133         if(pField != NULL)
01134             pDesc = pGeo->getType().findFieldDescription("normals");
01135     }
01136     else if(stringcasecmp("color", szFieldname) == 0)
01137     {
01138 #ifdef OSG_DEBUG_VRML
01139         indentLog(getIndent(), PINFO);
01140         PINFO << "GeoDesc::getFieldAndDesc : internal "
01141               << szFieldname << std::endl;
01142 #endif
01143 
01144         pField = pGeo->getField("colors");
01145 
01146         if(pField != NULL)
01147             pDesc = pGeo->getType().findFieldDescription("colors");
01148     }
01149     else if(stringcasecmp("texCoord", szFieldname) == 0)
01150     {
01151 #ifdef OSG_DEBUG_VRML
01152         indentLog(getIndent(), PINFO);
01153         PINFO << "GeoDesc::getFieldAndDesc : internal "
01154               << szFieldname << std::endl;
01155 #endif
01156 
01157         pField = pGeo->getField("texCoords");
01158 
01159         if(pField != NULL)
01160             pDesc = pGeo->getType().findFieldDescription("texCoords");
01161     }
01162     else
01163     {
01164         VRMLNodeDesc::getFieldAndDesc(pGeo,
01165                                       szFieldname,
01166                                       pField,
01167                                       pDesc);
01168     }
01169 }
01170 
01171 /*-------------------------------------------------------------------------*/
01172 /*                                Node                                     */
01173 
01174 FieldContainerPtr VRMLGeometryDesc::beginNode(
01175     const Char8       *,
01176     const Char8       *,
01177     FieldContainerPtr)
01178 {
01179     FieldContainerPtr pFC         = NullFC;
01180     NodePtr           pNode       = NullFC;
01181     NodeCorePtr       pNodeCore   = NullFC;
01182     GenericAttPtr     pAtt        = NullFC;
01183 
01184     if(_pNodeProto != NullFC)
01185     {
01186         FieldContainerPtr pAttClone = _pGenAtt->clone();
01187 
01188         pAtt = GenericAttPtr::dcast(pAttClone);
01189 
01190         if(pAtt != NullFC)
01191         {
01192             pAtt->setInternal(true);
01193         }
01194 
01195         pFC = _pNodeProto->shallowCopy();
01196 
01197         pNode = NodePtr::dcast(pFC);
01198 
01199         pFC = _pNodeCoreProto->shallowCopy();
01200 
01201         pNodeCore = NodeCorePtr::dcast(pFC);
01202 
01203         beginEditCP(pNode);
01204         {
01205             pNode    ->setCore      (pNodeCore);
01206             pNodeCore->addAttachment(pAtt);
01207         }
01208         endEditCP  (pNode);
01209     }
01210 
01211 #ifdef OSG_DEBUG_VRML
01212     indentLog(getIndent(), PINFO);
01213     PINFO << "Begin Geo " << &(*pNode) << std::endl;
01214 
01215     incIndent();
01216 #endif
01217 
01218     return pNode;
01219 }
01220 
01221 void VRMLGeometryDesc::endNode(FieldContainerPtr pFC)
01222 {
01223     NodePtr     pNode = NullFC;
01224     GeometryPtr pGeo  = NullFC;
01225 
01226     if(pFC == NullFC)
01227     {
01228         return;
01229     }
01230 
01231     pNode = NodePtr::dcast(pFC);
01232 
01233     if(pNode == NullFC)
01234     {
01235         return;
01236     }
01237 
01238     pGeo = GeometryPtr::dcast(pNode->getCore());
01239 
01240     if(pGeo == NullFC)
01241     {
01242         return;
01243     }
01244 
01245           Field            *pField = NULL;
01246     const FieldDescription *pDesc  = NULL;
01247 
01248     MFInt32  *pCoordIndex           = NULL;
01249     MFInt32  *pNormalIndex          = NULL;
01250     MFInt32  *pColorIndex           = NULL;
01251     MFInt32  *pTexCoordIndex        = NULL;
01252     SFBool   *pConvex               = NULL;
01253     SFBool   *pCcw                  = NULL;
01254     SFBool   *pNormalPerVertex      = NULL;
01255     SFBool   *pColorPerVertex       = NULL;
01256     SFReal32 *pCreaseAngle          = NULL;
01257 
01258     Inherited::getFieldAndDesc(pFC,
01259                                "coordIndex",
01260                                pField,
01261                                pDesc);
01262 
01263     if(pField != NULL)
01264     {
01265         pCoordIndex = static_cast<MFInt32 *>(pField);
01266     }
01267 
01268     Inherited::getFieldAndDesc(pFC,
01269                                "normalIndex",
01270                                pField,
01271                                pDesc);
01272