/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// // ODA Platform #include "OdaCommon.h" #include "TvDatabaseCleaner.h" #include "TvInsert.h" void OdTvDatabaseCleaner::cleanTvDatabase(OdTvDatabaseId& tvDbId) { OdTvDatabasePtr pTvDb = tvDbId.openObject(OdTv::kForWrite); OdTvGsViewIdArray activeViews; OdTvDevicesIteratorPtr pDevicesIterator = pTvDb->getDevicesIterator(); OdTvBlockIdSet blockArray; OdTvBlockIdMap blockVisitedMap; while (!pDevicesIterator->done()) { OdTvGsDeviceId deviceId = pDevicesIterator->getDevice(); OdTvGsDevicePtr pDevice = deviceId.openObject(OdTv::kForWrite); OdTvGsViewId activeViewId = pDevice->getActiveView(); if (!activeViewId.isNull()) activeViews.append(activeViewId); for (int i = pDevice->numViews() - 1; i >= 0; i--) { OdTvGsViewId viewId = pDevice->viewAt(i); OdTvGsViewPtr pView = viewId.openObject(OdTv::kForWrite); if (clearModelsLevel(pView, blockArray, blockVisitedMap) && viewId != activeViewId) { pView->inheritClipRegionFrom( OdTvGsViewId() ); pDevice->removeView(viewId); } } pDevicesIterator->step(); } OdTvModelsIteratorPtr pModelsIterator = pTvDb->getModelsIterator(); while (!pModelsIterator->done()) { OdTvModelId modelId = pModelsIterator->getModel(); pModelsIterator->step(); OdTvModelPtr pModel = modelId.openObject(OdTv::kForWrite); if (clearEntitiesLevel(pModel, blockArray, blockVisitedMap) && !modelIsFromActiveView(modelId, activeViews)) { pTvDb->removeModel(modelId); } } OdTvBlocksIteratorPtr pBlocksIterator = pTvDb->getBlocksIterator(); while (!pBlocksIterator->done()) { OdTvBlockId blockId = pBlocksIterator->getBlock(); pBlocksIterator->step(); if( blockArray.find( blockId ) != blockArray.end() ) continue; OdTvBlockIdMap::iterator itBlock = blockVisitedMap.find(blockId); if (itBlock == blockVisitedMap.end()) { if (clearEntitiesLevel(blockId.openObject(OdTv::kForWrite), blockArray, blockVisitedMap)) { pTvDb->removeBlock(blockId); } } else if (itBlock->second) { pTvDb->removeBlock(blockId); } } } bool OdTvDatabaseCleaner::cleanTvModel(OdTvModelId& modelId) { bool bIsEmpty = true; OdTvBlockIdSet blocksSet; OdTvBlockIdMap blockVisitedMap; OdTvModelPtr pModel = modelId.openObject(OdTv::kForWrite); if (pModel.isNull()) return false; //clear entites if need bIsEmpty = clearEntitiesLevel(pModel, blocksSet, blockVisitedMap); //clear empty blocks OdTvDatabaseId tvDbId = pModel->getDatabase(); OdTvDatabasePtr pDb = tvDbId.openObject(OdTv::kForWrite); if (!pDb.isNull()) { OdTvBlocksIteratorPtr pBlocksIterator = tvDbId.openObject()->getBlocksIterator(); while (!pBlocksIterator->done()) { OdTvBlockId blockId = pBlocksIterator->getBlock(); pBlocksIterator->step(); if (blocksSet.find(blockId) != blocksSet.end()) pDb->removeBlock(blockId); } } return bIsEmpty; } void OdTvDatabaseCleaner::cleanTvDatabaseForAppend(OdTvDatabaseId& tvDbId, std::set& foreignViews, std::set& foreignModels, std::set& foreignBlocks) { OdTvDatabasePtr pTvDb = tvDbId.openObject(OdTv::kForWrite); OdTvBlockIdSet blockArray; OdTvBlockIdMap blockVisitedMap; OdTvDevicesIteratorPtr pDevicesIterator = pTvDb->getDevicesIterator(); while (!pDevicesIterator->done()) { OdTvGsDeviceId deviceId = pDevicesIterator->getDevice(); OdTvGsDevicePtr pDevice = deviceId.openObject(OdTv::kForWrite); for (int i = pDevice->numViews() - 1; i >= 0; i--) { OdTvGsViewId viewId = pDevice->viewAt(i); OdTvGsViewPtr pView = viewId.openObject(OdTv::kForWrite); if (clearModelsLevelForAppend(pView, foreignModels, blockArray, blockVisitedMap) && foreignViews.find(viewId) == foreignViews.end()) { pDevice->removeView(viewId); } } pDevicesIterator->step(); } OdTvModelsIteratorPtr pModelsIterator = pTvDb->getModelsIterator(); while (!pModelsIterator->done()) { OdTvModelId modelId = pModelsIterator->getModel(); pModelsIterator->step(); if (foreignModels.find(modelId) == foreignModels.end()) { OdTvModelPtr pModel = modelId.openObject(OdTv::kForWrite); if (clearEntitiesLevel(pModel, blockArray, blockVisitedMap)) { pTvDb->removeModel(modelId); } } } OdTvBlocksIteratorPtr pBlocksIterator = pTvDb->getBlocksIterator(); while (!pBlocksIterator->done()) { OdTvBlockId blockId = pBlocksIterator->getBlock(); pBlocksIterator->step(); if (foreignBlocks.find(blockId) == foreignBlocks.end() && blockArray.find(blockId) == blockArray.end()) { OdTvBlockIdMap::iterator itBlock = blockVisitedMap.find(blockId); if (itBlock == blockVisitedMap.end()) { if (clearEntitiesLevel(blockId.openObject(OdTv::kForWrite), blockArray, blockVisitedMap)) { pTvDb->removeBlock(blockId); } } else if (itBlock->second) pTvDb->removeBlock(blockId); } } } bool OdTvDatabaseCleaner::clearModelsLevel(OdTvGsViewPtr pView, OdTvBlockIdSet& blockArray, OdTvBlockIdMap& blockVisitedMap) { bool bIsEmpty = true; const OdVector< OdTvGsViewId >* pClipHeirs = pView->clipRegionInheritantes(); if( pClipHeirs && !pClipHeirs->empty() ) bIsEmpty = false; for (int i = pView->numModels() - 1; i >= 0; i--) { OdTvModelId modelId = pView->modelAt(i); OdTvModelPtr pModel = modelId.openObject(OdTv::kForWrite); if (clearEntitiesLevel(pModel, blockArray, blockVisitedMap) && !pView->getActive()) { pView->eraseModel(modelId); } else { bIsEmpty = false; } } return bIsEmpty; } bool OdTvDatabaseCleaner::clearModelsLevelForAppend( OdTvGsViewPtr pView, std::set& foreignModels, OdTvBlockIdSet& blockArray, OdTvBlockIdMap& blockVisitedMap) { bool bIsEmpty = true; for (int i = pView->numModels() - 1; i >= 0; i--) { OdTvModelId modelId = pView->modelAt(i); if (foreignModels.find(modelId) == foreignModels.end()) { OdTvModelPtr pModel = modelId.openObject(OdTv::kForWrite); if (clearEntitiesLevel(pModel, blockArray, blockVisitedMap)) { pView->eraseModel(modelId); } else { bIsEmpty = false; } } } return bIsEmpty; } bool OdTvDatabaseCleaner::clearGeometryLevel(OdTvEntityPtr pEntity) { bool bIsEmpty = true; OdTvGeometryDataIteratorPtr pGeometryIterator = pEntity->getGeometryDataIterator(); while (!pGeometryIterator->done()) { OdTvGeometryDataId geometryDataId = pGeometryIterator->getGeometryData(); pGeometryIterator->step(); if (geometryDataId.getType() == OdTv::kSubEntity) { OdTvEntityPtr pSubEntity = geometryDataId.openAsSubEntity(OdTv::kForWrite); if (clearGeometryLevel(pSubEntity)) { pEntity->removeGeometryData(geometryDataId); } else { bIsEmpty = false; } } else { bIsEmpty = false; } } return bIsEmpty; } bool OdTvDatabaseCleaner::modelIsFromActiveView(OdTvModelId modelId, OdTvGsViewIdArray& activesViews) { for (unsigned int i = 0; i < activesViews.size(); i++) { OdTvGsViewId activeView = activesViews[i]; OdTvGsViewPtr pActiveView = activeView.openObject(OdTv::kForRead); for (int j = 0; j < pActiveView->numModels(); j++) { if (pActiveView->modelAt(j) == modelId) return true; } } return false; }