LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/cad/libopencad - cadtables.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 74 89 83.1 %
Date: 2024-11-21 22:18:42 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *  Project: libopencad
       3             :  *  Purpose: OpenSource CAD formats support library
       4             :  *  Author: Alexandr Borzykh, mush3d at gmail.com
       5             :  *  Author: Dmitry Baryshnikov, bishop.dev@gmail.com
       6             :  *  Language: C++
       7             :  *******************************************************************************
       8             :  *  The MIT License (MIT)
       9             :  *
      10             :  *  Copyright (c) 2016 Alexandr Borzykh
      11             :  *  Copyright (c) 2016-2018 NextGIS, <info@nextgis.com>
      12             :  *
      13             :   * SPDX-License-Identifier: MIT
      14             :  *******************************************************************************/
      15             : #include "cadtables.h"
      16             : #include "opencad_api.h"
      17             : 
      18             : #include <cassert>
      19             : #include <iostream>
      20             : #include <memory>
      21             : #include <set>
      22             : 
      23             : using namespace std;
      24             : 
      25           8 : CADTables::CADTables()
      26             : {
      27           8 : }
      28             : 
      29         144 : void CADTables::AddTable( TableType eType, const CADHandle& hHandle )
      30             : {
      31         144 :     mapTables[eType] = hHandle;
      32         144 : }
      33             : 
      34           8 : int CADTables::ReadTable( CADFile * const pCADFile, CADTables::TableType eType )
      35             : {
      36           8 :     auto iterAskedTable = mapTables.find( eType );
      37           8 :     if( iterAskedTable == mapTables.end() )
      38           0 :         return CADErrorCodes::TABLE_READ_FAILED;
      39             : 
      40             :     // TODO: read different tables
      41           8 :     switch( eType )
      42             :     {
      43           8 :         case LayersTable:
      44           8 :             return ReadLayersTable( pCADFile, iterAskedTable->second.getAsLong() );
      45           0 :         default:
      46           0 :             std::cerr << "Unsupported table.";
      47           0 :             break;
      48             :     }
      49             : 
      50           0 :     return CADErrorCodes::SUCCESS;
      51             : }
      52             : 
      53          26 : size_t CADTables::GetLayerCount() const
      54             : {
      55          26 :     return aLayers.size();
      56             : }
      57             : 
      58          27 : CADLayer& CADTables::GetLayer( size_t iIndex )
      59             : {
      60          27 :     return aLayers[iIndex];
      61             : }
      62             : 
      63           8 : CADHandle CADTables::GetTableHandle( enum TableType eType )
      64             : {
      65             :     // FIXME: need to add try/catch to prevent crashes on not found elem.
      66           8 :     return mapTables[eType];
      67             : }
      68             : 
      69           8 : int CADTables::ReadLayersTable( CADFile * const pCADFile, long dLayerControlHandle )
      70             : {
      71             :     // Reading Layer Control obj, and aLayers.
      72          16 :     unique_ptr<CADObject> pCADObject( pCADFile->GetObject( dLayerControlHandle ) );
      73             : 
      74             :     CADLayerControlObject* spLayerControl =
      75           8 :             dynamic_cast<CADLayerControlObject *>(pCADObject.get());
      76           8 :     if( !spLayerControl )
      77             :     {
      78           0 :         return CADErrorCodes::TABLE_READ_FAILED;
      79             :     }
      80             : 
      81          18 :     for( size_t i = 0; i < spLayerControl->hLayers.size(); ++i )
      82             :     {
      83          10 :         if( !spLayerControl->hLayers[i].isNull() )
      84             :         {
      85          20 :             CADLayer oCADLayer( pCADFile );
      86             : 
      87             :             // Init CADLayer from CADLayerObject properties
      88          10 :             CADObject* pCADLayerObject = pCADFile->GetObject(
      89          10 :                         spLayerControl->hLayers[i].getAsLong() );
      90             :             unique_ptr<CADLayerObject> oCADLayerObj(
      91          20 :                     dynamic_cast<CADLayerObject *>( pCADLayerObject ) );
      92             : 
      93          10 :             if(oCADLayerObj)
      94             :             {
      95          10 :                 oCADLayer.setName( oCADLayerObj->sLayerName );
      96          10 :                 oCADLayer.setFrozen( oCADLayerObj->bFrozen );
      97          10 :                 oCADLayer.setOn( oCADLayerObj->bOn );
      98          10 :                 oCADLayer.setFrozenByDefault( oCADLayerObj->bFrozenInNewVPORT );
      99          10 :                 oCADLayer.setLocked( oCADLayerObj->bLocked );
     100          10 :                 oCADLayer.setLineWeight( oCADLayerObj->dLineWeight );
     101          10 :                 oCADLayer.setColor( oCADLayerObj->dCMColor );
     102          10 :                 oCADLayer.setId( aLayers.size() + 1 );
     103          10 :                 oCADLayer.setHandle( oCADLayerObj->hObjectHandle.getAsLong() );
     104             : 
     105          10 :                 aLayers.push_back( oCADLayer );
     106             :             }
     107             :             else
     108             :             {
     109           0 :                 delete pCADLayerObject;
     110             :             }
     111             :         }
     112             :     }
     113             : 
     114           8 :     auto iterBlockMS = mapTables.find( BlockRecordModelSpace );
     115           8 :     if( iterBlockMS == mapTables.end() )
     116           0 :         return CADErrorCodes::TABLE_READ_FAILED;
     117             : 
     118           8 :     CADObject* pCADBlockObject = pCADFile->GetObject(
     119           8 :                 iterBlockMS->second.getAsLong() );
     120             :     unique_ptr<CADBlockHeaderObject> spModelSpace(
     121          16 :             dynamic_cast<CADBlockHeaderObject *>( pCADBlockObject ) );
     122           8 :     if(!spModelSpace)
     123             :     {
     124           0 :         delete pCADBlockObject;
     125           0 :         return CADErrorCodes::TABLE_READ_FAILED;
     126             :     }
     127             : 
     128           8 :     if(spModelSpace->hEntities.size() < 2)
     129             :     {
     130           0 :         return CADErrorCodes::TABLE_READ_FAILED;
     131             :     }
     132             : 
     133           8 :     auto dCurrentEntHandle = spModelSpace->hEntities[0].getAsLong();
     134           8 :     auto dLastEntHandle    = spModelSpace->hEntities[1].getAsLong();
     135             :     // To avoid infinite loops
     136           8 :     std::set<long> oVisitedHandles;
     137          36 :     while( dCurrentEntHandle != 0 &&
     138          36 :            oVisitedHandles.find(dCurrentEntHandle) == oVisitedHandles.end() )
     139             :     {
     140          18 :         oVisitedHandles.insert(dCurrentEntHandle);
     141             : 
     142          18 :         CADObject* pCADEntityObject = pCADFile->GetObject( dCurrentEntHandle, true );
     143             :         unique_ptr<CADEntityObject> spEntityObj(
     144          18 :                     dynamic_cast<CADEntityObject *>( pCADEntityObject ) );
     145             : 
     146          18 :         if( !spEntityObj )
     147             :         {
     148           0 :             delete pCADEntityObject;
     149           0 :             DebugMsg( "Entity object is null\n" );
     150           0 :             break;
     151             :         } 
     152          18 :         else if ( dCurrentEntHandle == dLastEntHandle )
     153             :         {
     154           8 :             FillLayer( spEntityObj.get() );
     155           8 :             break;
     156             :         }
     157             : 
     158          10 :         FillLayer( spEntityObj.get() );
     159             : 
     160          10 :         if( spEntityObj->stCed.bNoLinks )
     161             :         {
     162           5 :             ++dCurrentEntHandle;
     163             :         }
     164             :         else
     165             :         {
     166           5 :             dCurrentEntHandle = spEntityObj->stChed.hNextEntity.getAsLong( spEntityObj->stCed.hObjectHandle );
     167             :         }
     168             :     }
     169             : 
     170           8 :     DebugMsg( "Read aLayers using LayerControl object count: %d\n",
     171           8 :               static_cast<int>(aLayers.size()) );
     172             : 
     173           8 :     return CADErrorCodes::SUCCESS;
     174             : }
     175             : 
     176          18 : void CADTables::FillLayer( const CADEntityObject * pEntityObject )
     177             : {
     178          18 :     if(nullptr == pEntityObject)
     179             :     {
     180           0 :         return;
     181             :     }
     182             : 
     183          21 :     for( CADLayer& oLayer : aLayers )
     184             :     {
     185          63 :         if( pEntityObject->stChed.hLayer.getAsLong(
     186          21 :                     pEntityObject->stCed.hObjectHandle ) == oLayer.getHandle() )
     187             :         {
     188          36 :             DebugMsg( "Object with type: %s is attached to layer named: %s\n",
     189          36 :                       getNameByType( pEntityObject->getType() ).c_str(),
     190          36 :                       oLayer.getName().c_str() );
     191             : 
     192          18 :             oLayer.addHandle( pEntityObject->stCed.hObjectHandle.getAsLong(),
     193             :                               pEntityObject->getType() );
     194          18 :             break;
     195             :         }
     196             :     }
     197             : }

Generated by: LCOV version 1.14