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

OSGOSGWriter.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *                     Copyright 2000-2002 by OpenSG Forum                   *
00006  *                                                                           *
00007  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00008  *                                                                           *
00009 \*---------------------------------------------------------------------------*/
00010 /*---------------------------------------------------------------------------*\
00011  *                                License                                    *
00012  *                                                                           *
00013  * This library is free software; you can redistribute it and/or modify it   *
00014  * under the terms of the GNU Library General Public License as published    *
00015  * by the Free Software Foundation, version 2.                               *
00016  *                                                                           *
00017  * This library is distributed in the hope that it will be useful, but       *
00018  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00020  * Library General Public License for more details.                          *
00021  *                                                                           *
00022  * You should have received a copy of the GNU Library General Public         *
00023  * License along with this library; if not, write to the Free Software       *
00024  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00025  *                                                                           *
00026 \*---------------------------------------------------------------------------*/
00027 /*---------------------------------------------------------------------------*\
00028  *                                Changes                                    *
00029  *                                                                           *
00030  *                                                                           *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035 \*---------------------------------------------------------------------------*/
00036 
00037 //---------------------------------------------------------------------------
00038 //  Includes
00039 //---------------------------------------------------------------------------
00040 
00041 #include "OSGOSGWriter.h"
00042 #include <OSGAttachment.h>
00043 #include <OSGSimpleAttachments.h>
00044 #include "OSGVRMLNodeDescs.h"
00045 
00046 OSG_USING_NAMESPACE
00047 
00048 #if 0
00049 #if defined(OSG_WIN32_ICL)
00050 #pragma warning (disable : 383)
00051 #endif
00052 
00053 #if defined(OSG_WIN32_ICL)
00054 #pragma warning (default : 383)
00055 #endif
00056 #endif
00057 
00058 const UInt32 OSGWriter::DefaultSFWidth = TypeTraits<UInt32>::getMax();
00059 const UInt32 OSGWriter::DefaultMFWidth = 60;
00060 
00061 /*-------------------------------------------------------------------------*/
00062 /*                             Constructor                                 */
00063 
00066 OSGWriter::FCInfoHelper::FCInfoHelper(void) :
00067     written      (false),
00068     hasName      (false),
00069     containerName(     )
00070 {
00071 }
00072 
00075 OSGWriter::OSGWriter(std::ostream &stream, UInt32 indentStep) :
00076     _visitedFCMap(                 ),
00077     _state       (0, DefaultSFWidth),
00078     _indent      (0, indentStep    ),
00079     _outStream   (stream           )
00080 {
00081 }
00082 
00083 /*-------------------------------------------------------------------------*/
00084 /*                             Destructor                                  */
00085 
00088 OSGWriter::~OSGWriter(void)
00089 {
00090 }
00091 
00092 /*-------------------------------------------------------------------------*/
00093 /*                             Methods                                     */
00094 
00098 void OSGWriter::write(FieldContainerPtr container)
00099 {
00100     _visitedFCMap.clear();
00101     _indent.setIndent(0);
00102 
00103     _outStream << "#OSG V1.0 " << std::endl;
00104 
00105     visitContainer(container);
00106     writeContainer(container);
00107 }
00108 
00109 
00113 void OSGWriter::write(std::vector<FieldContainerPtr> containers)
00114 {
00115     _visitedFCMap.clear();
00116     _indent.setIndent(0);
00117 
00118     _outStream << "#OSG V1.0 " << std::endl;
00119 
00120     std::vector<FieldContainerPtr>::reverse_iterator iter;
00121 
00122     for(iter = containers.rbegin(); iter != containers.rend(); ++iter)
00123     {
00124         visitContainer( *iter );
00125     }
00126 
00127     for(iter = containers.rbegin(); iter != containers.rend(); ++iter)
00128     {
00129         writeContainer( *iter );
00130     }
00131 }
00132 
00133 
00138 void OSGWriter::FCInfoHelper::setName(const FieldContainerPtr pFC)
00139 {
00140     const FieldContainerType& fcType = pFC->getType();
00141     AttachmentContainerPtr pAttCon;
00142     NamePtr                pNameAtt;
00143 
00144     if(fcType.isDerivedFrom(AttachmentContainer::getClassType()))
00145     {
00146         pAttCon = AttachmentContainerPtr::dcast(pFC);
00147         if(pAttCon != NullFC)
00148         {
00149             pNameAtt = NamePtr::dcast(pAttCon->findAttachment(
00150                 Name::getClassType().getGroupId()));
00151 
00152             if(pNameAtt != NullFC)
00153             {
00154                 containerName = pNameAtt->getFieldPtr()->getValue().c_str();
00155                 return;
00156             }
00157         }
00158     }
00159 
00160     //no NameAttachment. Build name from Type and Id
00161     containerName = pFC->getTypeName() +
00162         TypeTraits<UInt32>::putToString(pFC.getFieldContainerId());
00163 }
00164 
00165 
00166 void OSGWriter::visitContainer(const FieldContainerPtr pFC)
00167 {
00168 
00169     if(pFC == NullFC)
00170     {
00171         return;
00172     }
00173 
00174     typedef std::pair<FCInfoHelperMap::iterator, bool> MapInsertInfo;
00175 
00176     std::string containerName;
00177     const FieldContainerType& fcType    = pFC->getType();
00178     UInt32              numFields = fcType.getNumFieldDescs();
00179     MapInsertInfo       insertInfo;
00180 
00181     insertInfo = _visitedFCMap.insert(std::make_pair(pFC, FCInfoHelper()));
00182     if(insertInfo.second == true)
00183     {
00184         //the FC was NOT visited before
00185         for(UInt32 field=1; field<=numFields; field++)
00186         {
00187             const FieldDescription* fieldDesc =
00188                 fcType.getFieldDescription(field);
00189             if(fieldDesc->isInternal())
00190             {
00191                 continue;
00192             }
00193             visitField(pFC->getField(field));
00194         }
00195     }
00196     else
00197     {
00198         //the FC was in the map => FC is shared
00199         FCInfoHelperMap::iterator iter = _visitedFCMap.find(pFC);
00200         if(iter == _visitedFCMap.end())
00201         {
00202             SWARNING << "OSGWriter::visitContainer(): FieldContainerPtr "
00203                      << "not found in map" << std::endl;
00204             return;
00205         }
00206         if(iter->second.hasName == false)
00207         {
00208             iter->second.setName(pFC);
00209             iter->second.hasName = true;
00210         }
00211     }
00212 }
00213 
00214 void OSGWriter::visitField(const Field* pF)
00215 {
00216     if(pF == NULL)
00217     {
00218         return;
00219     }
00220 
00221     const FieldType& fType       = pF->getType();
00222 //    const DataType & contentType = pF->getContentType();
00223 
00224     //handle SFAttachmentMap as special case here
00225     //if(fType.isDerivedFrom(SFAttachmentMap::getClassType()))
00226     if(strstr(fType.getCName(), "AttachmentMap") != NULL)
00227     {
00228         //visit the Attachment FCs
00229 
00230         const SFAttachmentMap *sfAttMap = (const SFAttachmentMap*) pF;
00231               AttachmentMap    attMap   = sfAttMap->getValue();
00232 
00233         AttachmentMap::const_iterator iter = attMap.begin();
00234         AttachmentMap::const_iterator end  = attMap.end();
00235 
00236         for(; iter!=end; ++iter)
00237         {
00238             visitContainer(iter->second);
00239         }
00240     }
00241     //else if(contentType.isDerivedFrom(FieldContainerPtr::getClassType()))
00242     else if(strstr(fType.getCName(), "Ptr") != NULL)
00243     {
00244         //this Field points to FC
00245 
00246         //to access the content of a field one must know the cardinality
00247         if(pF->getCardinality() == FieldType::SINGLE_FIELD)
00248         {
00249             const SFFieldContainerPtr* sfFCPtr =
00250                 (const SFFieldContainerPtr*) pF;
00251             visitContainer(sfFCPtr->getValue());
00252         }
00253         else if(pF->getCardinality() == FieldType::MULTI_FIELD)
00254         {
00255             const MFFieldContainerPtr* mfFCPtr =
00256                 (const MFFieldContainerPtr*) pF;
00257             UInt32 mfSize = mfFCPtr->size();
00258             for(UInt32 i=0; i < mfSize; i++)
00259             {
00260                 visitContainer((*(mfFCPtr))[i]);
00261             }
00262         }
00263     }
00264 }
00265 
00266 void OSGWriter::writeContainer(const FieldContainerPtr pFC)
00267 {
00268     if(pFC == NullFC)
00269     {
00270         return;
00271     }
00272 
00273     const FieldContainerType& fcType    = pFC->getType();
00274     UInt32              numFields = fcType.getNumFieldDescs();
00275 
00276     FCInfoHelperMap::iterator iter = _visitedFCMap.find(pFC);
00277     if(iter == _visitedFCMap.end())
00278     {
00279         SWARNING << "OSGWriter::writeContainer(): FieldContainerPtr "
00280                  << "not found in map" << std::endl;
00281         return;
00282     }
00283 
00284     if(!iter->second.written)
00285     {
00286         //FC is not written yet
00287         iter->second.written = true;
00288         if(iter->second.hasName)
00289         {
00290             _outStream << _indent                    << "DEF "
00291                        << iter->second.containerName << " "
00292                        << pFC->getTypeName()         << " {"
00293                        << std::endl;
00294         }
00295         else{
00296             _outStream << _indent <<  pFC->getTypeName() << " {"
00297                        << std::endl;
00298         }
00299 
00300         _indent++;
00301 
00302         for(UInt32 field=1; field<=numFields; field++)
00303         {
00304             const FieldDescription* fieldDesc =
00305                 fcType.getFieldDescription(field);
00306             if(fieldDesc->isInternal())
00307             {
00308                 continue;
00309             }
00310             writeField(pFC->getField(field), fieldDesc);
00311         }
00312         _indent--;
00313         _outStream << _indent << "}" << std::endl;
00314     }
00315     else
00316     {
00317         //FC is already written -> its shared -> write reference
00318         if(!iter->second.hasName)
00319         {
00320             SWARNING << "OSGWriter::writeContainer(): FieldContainer is "
00321                      << "shared, but not named"
00322                      << std::endl;
00323             return;
00324         }
00325 
00326         _outStream << _indent
00327                    << "USE "
00328                    << iter->second.containerName 
00329                    << std::endl;
00330     }
00331 
00332 }
00333 
00334 
00335 void OSGWriter::writeField(const Field* pF, const FieldDescription* fieldDesc)
00336 {
00337 
00338     if(pF == NULL)
00339     {
00340         return;
00341     }
00342 
00343     const FieldType& fType = pF->getType();
00344 //    const DataType&  contentType = pF->getContentType();
00345 
00346     //handle SFAttachmentMap as special case here
00347     //if(fType.isDerivedFrom(SFAttachmentMap::getClassType()))
00348     if(strstr(fType.getCName(), "AttachmentMap") != NULL)
00349     {
00350         //write Attachments
00351 
00352         const SFAttachmentMap *sfAttMap = (const SFAttachmentMap*) pF;
00353               AttachmentMap    attMap   = sfAttMap->getValue();
00354 
00355         AttachmentMap::const_iterator iter = attMap.begin();
00356         AttachmentMap::const_iterator end  = attMap.end();
00357 
00358         _outStream << _indent << fieldDesc->getName() << " [ ";
00359         _indent++;
00360         _state.setIndent(_indent.getIndent());
00361         
00362         //if the Attachment Map is empty write [] as its content
00363         if(iter==end)
00364         {
00365             _outStream << " ] " << std::endl;
00366             _indent--; 
00367         }
00368         else
00369         {
00370             _outStream << std::endl;
00371         
00372             for(; iter!=end; ++iter)
00373             {
00374                 if(iter->second->getInternal().getValue() != true)
00375                 {
00376                     writeContainer(iter->second);
00377                 }
00378             }
00379             _indent--; 
00380             
00381             _outStream << _indent << " ] " << std::endl;
00382         }
00383     }
00384     //else if(contentType.isDerivedFrom(FieldContainerPtr::getClassType()))
00385     else if(strstr(fType.getCName(), "Ptr") != NULL)
00386     {
00387         //this Field points to FC
00388 
00389         _state.setIndent(_indent.getIndent());
00390         _outStream << _indent << fieldDesc->getName();
00391 
00392         //to access the content of a field via a Field*
00393         //one must know the cardinality
00394         if(pF->getCardinality() == FieldType::SINGLE_FIELD)
00395         {
00396             const SFFieldContainerPtr* sfFCPtr =
00397                 (const SFFieldContainerPtr*) pF;
00398             if(sfFCPtr->getValue() == NullFC)
00399             {
00400                 _outStream << " NULL" << std::endl;
00401             }
00402             else
00403             {
00404                 _outStream << std::endl;
00405                 _indent++;
00406                 writeContainer(sfFCPtr->getValue());
00407                 _indent--;
00408             }
00409         }
00410         else if(pF->getCardinality() == FieldType::MULTI_FIELD)
00411         {
00412             _outStream << " [" << std::endl;
00413             _indent++;
00414             const MFFieldContainerPtr* mfFCPtr =
00415                 (const MFFieldContainerPtr*) pF;
00416             UInt32 mfSize = mfFCPtr->size();
00417             for(UInt32 i=0; i < mfSize; i++)
00418             {
00419                 if((*(mfFCPtr))[i] == NullFC)
00420                 {
00421                     _outStream << _indent << "NULL" << std::endl;
00422                 }
00423                 else
00424                 {
00425                     writeContainer((*(mfFCPtr))[i]);
00426                 }
00427             }
00428             _indent--;
00429             _outStream << _indent << "]" << std::endl;
00430         }
00431     }
00432     else
00433     {
00434         //this Field contains data -> write it out
00435 
00436         _state.setIndent(_indent.getIndent());
00437         _outStream << _indent << fieldDesc->getName();
00438 
00439         std::string fieldValue;
00440 
00441         //to access the content of a field via a Field*
00442         //one must know the cardinality
00443         if(pF->getCardinality() == FieldType::SINGLE_FIELD)
00444         {
00445             _state.setIndent(0);
00446             _state.setWidth(DefaultSFWidth);
00447             pF->getValueByStr(fieldValue, _state);
00448             _outStream << " " << fieldValue << std::endl;
00449         }
00450         else if(pF->getCardinality() == FieldType::MULTI_FIELD)
00451         {
00452             _outStream << " [" << std::endl;
00453 
00454             _indent++;
00455             _state.setIndent(_indent.getIndent());
00456             _state.setWidth(DefaultMFWidth);
00457             pF->getValueByStr(fieldValue, _state);
00458             _outStream << fieldValue << std::endl;
00459             _indent--;
00460 
00461             _outStream << _indent << "]" << std::endl;
00462         }
00463     }
00464 }
00465 
00466 
00467 /*-------------------------------------------------------------------------*/
00468 /*                              cvs id's                                   */
00469 
00470 #ifdef __sgi
00471 #pragma set woff 1174
00472 #endif
00473 
00474 #ifdef OSG_LINUX_ICC
00475 #pragma warning( disable : 177 )
00476 #endif
00477 
00478 namespace
00479 {
00480     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00481     static Char8 cvsid_hpp[] = OSGOSGWRITER_HEADER_CVSID;
00482 }

Generated on Thu Aug 25 04:08:02 2005 for OpenSG by  doxygen 1.4.3