/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #include #include "DgnImportXRef.h" #include "DgnImportCommon.h" #include "DgnImportContext.h" #include #include #include "DgnImportImpl.h" #include #include #include #include #include #include #include #include #include #include #include "DbSymUtl.h" #include #include "DgLevelTableRecord.h" #include "DbUnderlayDefinition.h" #include "DbUnderlayReference.h" #include "DbViewport.h" #include "DbIdMapping.h" #include "DbDimAssoc.h" #include "DgProxyElement.h" #include "Gi/GiBaseVectorizer.h" #include "Gi/GiGeometrySimplifier.h" #include "Ge/GeLineSeg2d.h" #include "Gi/GiFastExtCalc.h" #include "DbText.h" #include "DbMText.h" #include "GiContextForDbDatabase.h" #include "Db3dPolyline.h" #include "Db3dPolylineVertex.h" #include "DbLayerTable.h" #include "DbSortentsTable.h" #include "DgRasterAttach.h" #include "Dg3DObject.h" #include "DgComplexString.h" #include "DgComplexShape.h" namespace TD_DGN_IMPORT { //--------------------------------------------------------------------------------------------------- bool getXRefPalette( OdDgReferenceAttachmentHeader* pXRef, OdDgDatabase* pDb, ODCOLORREF* pPalette ) { bool bRet = false; if( pDb && pXRef && pPalette ) { OdDgColorTablePtr pRefColorTable = pDb->getColorTable(OdDg::kForRead); if( !pRefColorTable.isNull() ) { memcpy( pPalette, pRefColorTable->palette(), 256*sizeof(ODCOLORREF)); } else { memcpy( pPalette, OdDgColorTable::defaultPalette(), 256*sizeof(ODCOLORREF)); } OdDgColorTable::correctPaletteForWhiteBackground(pPalette); // Check color correction for reference attachment palette bool bUseColorCorrection = false; double dInvertLighting = 0; double dInvertSaturation = 0; OdRxObjectPtrArray arrLinkages; pXRef->getLinkages( OdDgAttributeLinkage::kDoubleArray, arrLinkages ); for( OdUInt32 iLink = 0; iLink < arrLinkages.size(); iLink++ ) { if( arrLinkages[iLink]->isKindOf(OdDgDoubleArrayLinkage::desc()) ) { OdDgDoubleArrayLinkagePtr pDblArrLinkage = arrLinkages[iLink]; if( !pDblArrLinkage.isNull() && pDblArrLinkage->getArrayId() == 0x09 && pDblArrLinkage->getItemCount() == 2 ) { dInvertLighting = pDblArrLinkage->getItem(0); dInvertSaturation = pDblArrLinkage->getItem(1); if( (dInvertLighting >= 0) && (dInvertLighting < 101) && (dInvertSaturation >= 0) && (dInvertSaturation <101) ) { bUseColorCorrection = true; dInvertLighting = (OdUInt32)(dInvertLighting); dInvertSaturation = (OdUInt32)(dInvertSaturation); } break; } } } if( bUseColorCorrection ) { for( OdUInt32 iColor = 0; iColor < 256; iColor++ ) { ODCOLORREF curColor = pPalette[iColor]; // Saturation correction if( !OdZero(dInvertSaturation) ) { OdUInt8 uRed = ODGETRED( curColor ); OdUInt8 uGreen = ODGETGREEN( curColor ); OdUInt8 uBlue = ODGETBLUE( curColor ); OdUInt8 uMax = (uRed > uGreen) ? uRed : uGreen; if( uBlue > uMax ) { uMax = uBlue; } uRed = uRed + (OdUInt8)(( uMax - uRed )*dInvertSaturation / 100.0); uGreen = uGreen + (OdUInt8)(( uMax - uGreen )*dInvertSaturation / 100.0); uBlue = uBlue + (OdUInt8)(( uMax - uBlue )*dInvertSaturation / 100.0); curColor = ODRGB( uRed, uGreen, uBlue ); } // Lighting correction if( !OdZero(dInvertLighting) ) { OdUInt8 uRed = ODGETRED( curColor ); OdUInt8 uGreen = ODGETGREEN( curColor ); OdUInt8 uBlue = ODGETBLUE( curColor ); uRed = (OdUInt8)(uRed *(100.0 - dInvertLighting) / 100.0); uGreen = (OdUInt8)(uGreen*(100.0 - dInvertLighting) / 100.0); uBlue = (OdUInt8)(uBlue *(100.0 - dInvertLighting) / 100.0); curColor = ODRGB( uRed, uGreen, uBlue ); } pPalette[iColor] = curColor; } } bRet = true; } return bRet; } //--------------------------------------------------------------------------------------------------- OdDgLevelTablePtr mergeLevelTables(const OdDgLevelTable* pNativeLevelTable, const OdDgLevelTable* pXRefLevelTable) { OdDgLevelTablePtr pRet = OdDgLevelTable::createObject(); pRet->setDatabaseDefaults(pXRefLevelTable->database()); OdDgElementIteratorPtr pIter = pNativeLevelTable->createIterator(); for (; !pIter->done(); pIter->step()) { OdDgLevelTableRecordPtr pNativeLevel = pIter->item().openObject(OdDg::kForRead); if( pNativeLevel.isNull() ) continue; OdDgElementId idXRefLevel = pXRefLevelTable->getAt(pNativeLevel->getName()); OdDgLevelTableRecordPtr pResultLevel; if (idXRefLevel.isNull()) pResultLevel = pNativeLevel->clone(); else { OdDgLevelTableRecordPtr pXRefLevel = idXRefLevel.openObject(OdDg::kForRead); if(pXRefLevel.isNull()) pResultLevel = pNativeLevel->clone(); else pResultLevel = pXRefLevel->clone(); } pRet->add(pResultLevel, true); } return pRet; } //--------------------------------------------------------------------------------------------------- OdDgLevelTablePtr getActualXRefLevelTable(const OdDgReferenceAttachmentHeader* pXRef, OdDgDatabase* pDgnDb ) { OdDgLevelTablePtr pNativeLevelTable = pDgnDb->getLevelTable(OdDg::kForRead); OdDgLevelTablePtr pRet = pNativeLevelTable; OdDgReferenceAttachmentHeaderPtr pBaseXRef = pXRef; if (OdDgnImportContext::getXRefNestedDepth() > 0) { OdArray arrXRefPathId; OdArray arrXRefPath; for (OdUInt32 k = 1; k < OdDgnImportContext::getXRefNestedDepth(); k++) { OdDgElementId idPathXRef = OdDgnImportContext::getXRefId(k); if (!idPathXRef.isNull()) { arrXRefPath.push_back((OdUInt64)(idPathXRef.getHandle())); arrXRefPathId.push_back(idPathXRef); } else { arrXRefPath.push_back((OdUInt64)(0)); arrXRefPathId.push_back(OdDgElementId()); } } arrXRefPath.push_back((OdUInt64)(pXRef->elementId().getHandle())); arrXRefPathId.push_back(pXRef->elementId()); OdUInt32 uPathSize = arrXRefPath.size(); for (OdUInt32 i = 0; i < uPathSize; i++) { OdDgElementId idBaseXRef = arrXRefPathId[0]; if (idBaseXRef.isNull()) continue; pBaseXRef = idBaseXRef.openObject(OdDg::kForRead); if( arrXRefPathId.size() == 1 ) { if (!pBaseXRef->getLevelTable().isNull()) { pRet = pBaseXRef->getLevelTable(); break; } } else { OdDgElementIteratorPtr pXRefIter = pBaseXRef->createIterator(); for (; !pXRefIter->done(); pXRefIter->step()) { OdDgElementPtr pChild = pXRefIter->item().openObject(OdDg::kForRead); if (!pChild.isNull() && pChild->isKindOf(OdDgReferenceOverride::desc())) { OdDgReferenceOverridePtr pXRefOverride = pChild; OdUInt64Array arrPath; pXRefOverride->getPathOfXRef(arrPath); if (arrPath.size() == arrXRefPath.size()) { bool bCorrectOverride = true; for (OdUInt32 n = 0; n < arrXRefPath.size(); n++) { if (arrPath[n] != arrXRefPath[n]) { bCorrectOverride = false; break; } } if (bCorrectOverride) { if (!pXRefOverride->getLevelTable().isNull()) pRet = pXRefOverride->getLevelTable(); break; } } } } } arrXRefPath.removeFirst(); arrXRefPathId.removeFirst(); } } else { if (!pXRef->getLevelTable().isNull()) pRet = pXRef->getLevelTable(); } if( pRet != pNativeLevelTable ) { pRet = mergeLevelTables(pNativeLevelTable, pRet); OdDgnImportContext::setOverridedLevelTable(pRet->elementId()); std::map< OdDgElementId, OdDgElementId > mapLevelOverrides; OdDgElementIteratorPtr pLevelIter = pNativeLevelTable->createIterator(); for(; !pLevelIter->done(); pLevelIter->step() ) { OdDgLevelTableRecordPtr pNativeLevel = pLevelIter->item().openObject(OdDg::kForRead); if( !pNativeLevel.isNull() ) { OdDgElementId idLevelOverride = pRet->getAt(pNativeLevel->getName()); if( !idLevelOverride.isNull() ) { mapLevelOverrides[pNativeLevel->elementId()] = idLevelOverride; } } } if( mapLevelOverrides.size() > 0 ) { OdDgnImportContext::pushLevelTableOverride(mapLevelOverrides); OdDgnImportContext::setUseLevelOverrideFlag(true); } else { OdDgnImportContext::setUseLevelOverrideFlag(false); } } else { OdDgnImportContext::setUseLevelOverrideFlag(false); } return pRet; } //--------------------------------------------------------------------------------------------------- bool getActualXRefLevelMask( const OdDgReferenceAttachmentHeader* pXRef, OdUInt32 uViewNumber, OdDgLevelMaskPtr& pLevelMask ) { // try to find from view group and views bool bRet = false; OdDgViewPtr pCurView = OdDgnImportContext::getActiveView(); if( !pCurView.isNull() ) { OdDgElementIteratorPtr pViewIter = pCurView->createIterator(); bool bPathCorrect = true; if( OdDgnImportContext::getXRefNestedDepth() > 0 ) { OdArray arrXRefPath; for( OdUInt32 k = 0; k < OdDgnImportContext::getXRefNestedDepth(); k++ ) { bool bLevelGroupIsPresent = false; OdDgElementId idPathXRef = OdDgnImportContext::getXRefId(k); if( !idPathXRef.isNull() ) { for(; !pViewIter->done(); pViewIter->step() ) { OdDgElementPtr pElm = pViewIter->item().openObject(OdDg::kForRead); if( pElm->isKindOf(OdDgReferenceAttachmentLevelMaskGroup::desc()) ) { OdDgReferenceAttachmentLevelMaskGroupPtr pLevelMaskGroup = pElm; if( pLevelMaskGroup->getReferenceAttachmentId() == (OdUInt64)(idPathXRef.getHandle()) ) { bLevelGroupIsPresent = true; pViewIter = pLevelMaskGroup->createIterator(); break; } } else if( pElm->isKindOf(OdDgComplexProxyElement::desc()) ) { OdRxObjectPtrArray arrLinkages; pElm->getLinkages( OdDgAttributeLinkage::kReferenceAttachmentPath, arrLinkages ); if( arrLinkages.size() > 0 ) { OdDgReferenceAttachPathLinkagePtr pPath = arrLinkages[0]; if( pPath->getPathItem(pPath->getPathLength() - 1) == (OdUInt64)(idPathXRef.getHandle()) ) { OdDgComplexProxyElementPtr pProxy = pElm; bLevelGroupIsPresent = true; pViewIter = pProxy->createIterator(); break; } } } } if( !bLevelGroupIsPresent ) { bPathCorrect = false; break; } } else { bPathCorrect = false; break; } } } if( !pViewIter.isNull() ) { for(; !pViewIter->done(); pViewIter->step() ) { OdDgElementPtr pElm = pViewIter->item().openObject(OdDg::kForRead); if( pElm->isKindOf(OdDgLevelMask::desc()) ) { OdDgLevelMaskPtr pCurLevelMask = pElm; if( pCurLevelMask->getReferenceAttachHandleId() == (OdUInt64)(pXRef->elementId().getHandle()) ) { pLevelMask = pCurLevelMask; bRet = true; break; } } } } } if( bRet ) return bRet; OdDgReferenceAttachmentHeaderPtr pBaseXRef = pXRef; OdDgElementIteratorPtr pLevelMaskIter; if( OdDgnImportContext::getXRefNestedDepth() > 0 ) { OdArray arrXRefPath; for( OdUInt32 k = 1; k < OdDgnImportContext::getXRefNestedDepth(); k++ ) { OdDgElementId idPathXRef = OdDgnImportContext::getXRefId(k); if( !idPathXRef.isNull() ) { arrXRefPath.push_back( (OdUInt64)(idPathXRef.getHandle())); } else { arrXRefPath.push_back( (OdUInt64)(0)); } } arrXRefPath.push_back( (OdUInt64)(pXRef->elementId().getHandle())); OdDgElementId idBaseXRef = OdDgnImportContext::getXRefId(0); pBaseXRef = idBaseXRef.openObject(OdDg::kForRead); OdDgElementIteratorPtr pXRefIter = pBaseXRef->createIterator(); for(; !pXRefIter->done(); pXRefIter->step() ) { OdDgElementPtr pChild = pXRefIter->item().openObject(OdDg::kForRead); if( !pChild.isNull() && pChild->isKindOf( OdDgReferenceOverride::desc() ) ) { OdDgReferenceOverridePtr pXRefOverride = pChild; OdUInt64Array arrPath; pXRefOverride->getPathOfXRef(arrPath); if( arrPath.size() == arrXRefPath.size() ) { bool bCorrectOverride = true; for( OdUInt32 n = 0; n < arrXRefPath.size(); n++ ) { if( arrPath[n] != arrXRefPath[n] ) { bCorrectOverride = false; break; } } if( bCorrectOverride ) { pLevelMaskIter = pXRefOverride->createIterator(); break; } } } } } else { pLevelMaskIter = pBaseXRef->createIterator(); } if( pLevelMaskIter.isNull() ) pLevelMaskIter = pXRef->createIterator(); if( !pLevelMaskIter.isNull() ) { for(; !pLevelMaskIter->done(); pLevelMaskIter->step() ) { OdDgElementPtr pLevelMaskElm = pLevelMaskIter->item().openObject(OdDg::kForRead); if( !pLevelMaskElm.isNull() && pLevelMaskElm->isKindOf(OdDgLevelMask::desc()) ) { OdDgLevelMaskPtr pCurLevelMask = pLevelMaskElm; if( pCurLevelMask->getViewIndex() == uViewNumber ) { bRet = true; pLevelMask = pCurLevelMask; break; } } } } return bRet; } //--------------------------------------------------------------------------------------------------- class OdClippingBoundaryCreate : public OdStaticRxObject { class Loops : public OdGiGeometrySimplifier { public: void polylineProc(OdInt32 nbPoints, const OdGePoint3d* pVertexList, const OdGeVector3d* = 0, const OdGeVector3d* = 0, OdGsMarker = 0 ) { polylineOut(nbPoints, pVertexList); } void polylineOut(OdInt32 nPoints, const OdGePoint3d* pPoints) { if(nPoints > 1) { if(m_nCount && pPoints[0]==m_points.last() && pPoints[0]!=pPoints[nPoints-1]) { ++pPoints; --nPoints; m_counts.last() += nPoints; } else { ++m_nCount; m_counts.append(nPoints); } m_points.insert(m_points.end(), pPoints, pPoints+nPoints); } } void meshProc(OdInt32 rows, OdInt32 columns, const OdGePoint3d* pVertexList, const OdGiEdgeData* /*pEdgeData*/, const OdGiFaceData* /*pFaceData*/, const OdGiVertexData* /*pVertexData*/ ) { ODA_ASSERT(rows == 2 && columns == 2); OdGePoint3dArray points(5, 5); points.resize(5); OdGePoint3d *pArray = points.asArrayPtr(); pArray[0] = pVertexList[0]; pArray[1] = pVertexList[1]; pArray[2] = pVertexList[3]; pArray[3] = pVertexList[2]; pArray[4] = pVertexList[0]; polylineOut(5, pArray); } void shellProc( OdInt32 nbVertex, const OdGePoint3d* pVertexList, OdInt32 faceListSize, const OdInt32* pFaceList, const OdGiEdgeData* /*pEdgeData*/, const OdGiFaceData* pFaceData, const OdGiVertexData* pVertexData) { setVertexData(nbVertex, pVertexList, pVertexData); generateShellWires(faceListSize, pFaceList, NULL, pFaceData); } int m_nCount; OdIntArray m_counts; OdGePoint3dArray m_points; TD_USING(OdGiGeometrySimplifier::polylineOut); } m_loopsGen; OdSmartPtr m_pDeviation; public: OdClippingBoundaryCreate() { m_loopsGen.setDrawContext(drawContext()); output().setDestGeometry(m_loopsGen); SETBIT(m_flags, kDrawLayerOff | kDrawLayerFrozen, true); } bool buildBoundary(OdDbObjectId id) { m_loopsGen.m_nCount = 0; m_loopsGen.m_counts.clear(); m_loopsGen.m_points.clear(); OdDbObjectPtr pObj = id.openObject(); OdDbEntityPtr pEnt = pObj; if(pEnt.get()) { OdGeExtents3d extEntity; pEnt->getGeomExtents( extEntity ); if( extEntity.isValidExtents() ) { m_dDeviation = extEntity.maxPoint().distanceTo( extEntity.minPoint() ) / 1000.0; } else { m_dDeviation = 1e-6; } draw(pObj); } return (m_loopsGen.m_nCount!=0); } inline int loops() const { return m_loopsGen.m_nCount; } inline const int* counts() const { return m_loopsGen.m_counts.getPtr(); } inline const OdGePoint3d* points() const { return m_loopsGen.m_points.getPtr(); } double deviation(const OdGiDeviationType deviationType, const OdGePoint3d& pointOnCurve) const { return m_dDeviation; } private: double m_dDeviation; }; //--------------------------------------------------------------------------------------------------- void setViewportRefClipBoundary( const OdDbViewport* pViewport, OdDbBlockReferencePtr& pViewportReference, const OdGeMatrix3d& matMSToPS ) { bool bClipViewport = false; OdGiClipBoundary viewportClip; viewportClip.m_bClippingBack = false; viewportClip.m_bClippingFront = false; viewportClip.m_bDrawBoundary = true; viewportClip.m_dBackClipZ = 0; viewportClip.m_dFrontClipZ = 0; viewportClip.m_ptPoint = pViewport->centerPoint(); viewportClip.m_vNormal = OdGeVector3d::kZAxis; viewportClip.m_xInverseBlockRefXForm = OdGeMatrix3d::kIdentity; viewportClip.m_xToClipSpace = matMSToPS; bool bCreateRectangleClip = true; if( pViewport->isNonRectClipOn() ) { OdClippingBoundaryCreate cbClipBoundaryCreate; if( cbClipBoundaryCreate.buildBoundary(pViewport->nonRectClipEntityId()) ) { OdGePoint3dArray arrClip3dPts; OdInt32 nPoints = cbClipBoundaryCreate.counts()[0]; for( OdInt32 i = 0; i < nPoints; i++ ) { OdGePoint3d ptClip = cbClipBoundaryCreate.points()[i]; viewportClip.m_Points.push_back( ptClip.convert2d() ); } bCreateRectangleClip = false; bClipViewport = true; } } if( bCreateRectangleClip ) { OdGePoint3d ptCenter(pViewport->viewCenter().x, pViewport->viewCenter().y, 0.0); double dFieldHeight = pViewport->viewHeight() / 2.0; double dFieldWidth = dFieldHeight * pViewport->width() / pViewport->height(); OdGePoint3d ptClip = ptCenter - OdGeVector3d::kXAxis*dFieldWidth - OdGeVector3d::kYAxis*dFieldHeight; ptClip.transformBy(matMSToPS); viewportClip.m_Points.push_back( ptClip.convert2d()); ptClip = ptCenter - OdGeVector3d::kXAxis*dFieldWidth + OdGeVector3d::kYAxis*dFieldHeight; ptClip.transformBy(matMSToPS); viewportClip.m_Points.push_back( ptClip.convert2d()); ptClip = ptCenter + OdGeVector3d::kXAxis*dFieldWidth + OdGeVector3d::kYAxis*dFieldHeight; ptClip.transformBy(matMSToPS); viewportClip.m_Points.push_back( ptClip.convert2d()); ptClip = ptCenter + OdGeVector3d::kXAxis*dFieldWidth - OdGeVector3d::kYAxis*dFieldHeight; ptClip.transformBy(matMSToPS); viewportClip.m_Points.push_back( ptClip.convert2d()); bClipViewport = true; } if( bClipViewport ) { if( pViewportReference->extensionDictionary().isNull() ) { pViewportReference->createExtensionDictionary(); } OdDbDictionaryPtr pDict = OdDbDictionary::cast(pViewportReference->extensionDictionary().openObject(OdDb::kForWrite)); if( !pDict.isNull() ) { OdDbDictionaryPtr pFDict = OdDbDictionary::cast(pDict->getAt(OD_T("ACAD_FILTER"), OdDb::kForWrite)); if( pFDict.isNull() ) { pFDict = OdDbDictionary::createObject(); pDict->setAt( OD_T("ACAD_FILTER"), pFDict ); } if( !pFDict.isNull() ) { OdDbSpatialFilterPtr pSp = OdDbSpatialFilter::cast(pFDict->getAt(OD_T("SPATIAL"), OdDb::kForWrite)); if( pSp.isNull() ) { pSp = OdDbSpatialFilter::createObject(); pFDict->setAt( OD_T("SPATIAL"), pSp ); } if( !pSp.isNull() ) { pSp->setDefinition( viewportClip ); } } } } } //--------------------------------------------------------------------------------------------------- bool importDwgLayoutXRef( OdDbBlockTableRecord* owner, OdDgReferenceAttachmentHeader* pXRef, OdDbDatabase* pXRefDb, const OdString& xRefFileName, const OdString& strLayoutName, OdGeMatrix3d& matTransform, OdDbBlockTableRecordPtr& pXRefDef ) { bool bRet = false; OdDbDatabase* pDWGDb = owner->database(); if( !pDWGDb || !pXRefDb ) { return bRet; } pXRefDb->setCurrentLayout( strLayoutName ); if( pXRefDb->getTILEMODE() ) { return bRet; } OdDbObjectId idLayout = pXRefDb->currentLayoutId(); if( idLayout.isNull() ) { return bRet; } OdDbLayoutPtr pLayout = idLayout.openObject(OdDb::kForRead); if( pLayout.isNull() ) { return bRet; } OdDbObjectId idLayoutBlock = pLayout->getBlockTableRecordId(); if( idLayoutBlock.isNull() ) { return bRet; } OdDbBlockTableRecordPtr pLayoutBlock = idLayoutBlock.openObject( OdDb::kForRead ); if( pLayoutBlock.isNull() ) { return bRet; } // Create block OdDbObjectId idBlockTable = pDWGDb->getBlockTableId(); if( idBlockTable.isNull() ) { return bRet; } OdDbBlockTablePtr pBlockTable = idBlockTable.openObject(OdDb::kForWrite); if( pBlockTable.isNull() ) { return bRet; } OdString strDefNameBase = xRefFileName; strDefNameBase.replace(L'\\',L'/'); if( strDefNameBase.reverseFind(L'/') != -1 ) { strDefNameBase = strDefNameBase.right( strDefNameBase.getLength() - strDefNameBase.reverseFind(L'/') - 1 ); } strDefNameBase = strDefNameBase.trimLeft(); strDefNameBase = strDefNameBase.trimRight(); if( strDefNameBase.getLength() > 4 && strDefNameBase[ strDefNameBase.getLength() - 4] == L'.' ) { strDefNameBase = strDefNameBase.left( strDefNameBase.getLength() - 4 ); } OdString strDefName = strDefNameBase; OdUInt32 uCount = 1; OdDgnImportContext::getCellBlockNextIndex(strDefName, uCount); while( strDefName.isEmpty() || !pBlockTable->getAt( strDefName).isNull() ) { if( strDefNameBase.isEmpty() ) { strDefName.format(L"AnonymusLayout%d", uCount ); } else { strDefName.format(L"_%d", uCount ); strDefName = strDefNameBase + strDefName; } uCount++; } OdDgnImportContext::setCellBlockNextIndex(strDefNameBase, uCount + 1); OdString repairedName; if( OdDbSymUtil::repairSymbolName(repairedName, strDefName, pDWGDb ) == eOk && !repairedName.isEmpty() ) { strDefNameBase = repairedName; strDefName = strDefNameBase; } pXRefDef = OdDbBlockTableRecord::createObject(); pXRefDef->setName( strDefName ); pBlockTable->add( pXRefDef ); // wBlockClone all objects of layout except viewports OdDbObjectIteratorPtr pIter = pLayoutBlock->newIterator(); OdDbObjectIdArray arrItemsToClone; OdDbObjectIdArray arrViewportIds; for(; !pIter->done(); pIter->step() ) { OdDbEntityPtr pItem = pIter->entity(); if( pItem->isKindOf( OdDbViewport::desc()) ) { arrViewportIds.push_back( pItem->objectId() ); continue; } arrItemsToClone.push_back( pItem->objectId() ); } OdDbIdMappingPtr pMap = OdDbIdMapping::createObject(); pMap->setDestDb( pDWGDb ); pXRefDb->wblockCloneObjects( arrItemsToClone, pXRefDef->objectId(), *pMap, OdDb::kDrcIgnore, false ); // Convert viewports to XRefs for( OdUInt32 i = 0; i < arrViewportIds.size(); i++ ) { if( arrViewportIds[i] == pLayout->overallVportId() ) { continue; } OdDbViewportPtr pViewport = arrViewportIds[i].openObject( OdDb::kForRead ); OdGeMatrix3d matTransform = OdDbPointRef::mswcsToPswcs( pViewport ); // Generate name for viewport OdString strViewportBlockName; strViewportBlockName.format(L"_viewport_%d", i); strViewportBlockName = strDefName + strViewportBlockName; if( OdDbSymUtil::repairSymbolName(repairedName, strViewportBlockName, pDWGDb ) == eOk && !repairedName.isEmpty() ) { strViewportBlockName = repairedName; } OdDbBlockTableRecordPtr pViewportDef = OdDbXRefManExt::addNewXRefDefBlock(pDWGDb, xRefFileName, strViewportBlockName, false); OdDbBlockReferencePtr pViewportReference = OdDbBlockReference::createObject(); pViewportReference->setDatabaseDefaults(pDWGDb); pXRefDef->appendOdDbEntity(pViewportReference); pViewportReference->setBlockTableRecord(pViewportDef->objectId()); pViewportReference->setBlockTransform( matTransform ); pViewportReference->setVisibility( pViewport->isOn() ? OdDb::kVisible : OdDb::kInvisible ); // Init viewport clip setViewportRefClipBoundary( pViewport, pViewportReference, matTransform ); } bRet = true; return bRet; } //--------------------------------------------------------------------------------------------------- void importDwgXRef( OdDbBlockTableRecord* owner, OdDgReferenceAttachmentHeader* pXRef, OdGeMatrix3d& matTransform, OdDbBlockReferencePtr& pBlockReference ) { OdString databaseShortName = pXRef->getFileName(); OdString databaseFullName = pXRef->getFullFileName(); OdDgDatabase* pDgnDb = pXRef->database(); OdString xRefFileName; if( !databaseFullName.isEmpty() ) { xRefFileName = pDgnDb->appServices()->findFile( databaseFullName, pDgnDb, OdDgHostAppServices::kXRefDrawing ); } if( xRefFileName.isEmpty() ) { xRefFileName = pDgnDb->appServices()->findFile( databaseShortName, pDgnDb, OdDgHostAppServices::kXRefDrawing ); } OdString strFileExt = OdString::kEmpty; if( xRefFileName.getLength() > 4 ) { strFileExt = xRefFileName.right(4); strFileExt.makeUpper(); } bool bCorrectFile = !strFileExt.isEmpty() && ( (strFileExt == L".DWG") || (strFileExt == L".DXF")); if( bCorrectFile ) { bool bCreateXRefToModelSpace = false; OdString strModelName = pXRef->getModelName(); OdDbBlockTableRecordPtr pXRefDef; OdDbDatabase* pDwgDb = owner->database(); OdDbDatabasePtr pXRefDb; if( strModelName.isEmpty() ) { bCreateXRefToModelSpace = true; } else { pXRefDb = pDwgDb->appServices()->readFile(xRefFileName); bCreateXRefToModelSpace = !importDwgLayoutXRef( owner, pXRef, pXRefDb, xRefFileName, strModelName, matTransform, pXRefDef ); } if( bCreateXRefToModelSpace ) { OdDbObjectId idBlockDefTable = owner->database()->getBlockTableId(); if( !idBlockDefTable.isNull() ) { OdDbBlockTablePtr pBlockDefTable = idBlockDefTable.openObject(OdDb::kForWrite); OdDbSymbolTableIteratorPtr pBlockDefIter = pBlockDefTable->newIterator(); for(; !pBlockDefIter->done(); pBlockDefIter->step() ) { OdDbSymbolTableRecordPtr pRec = pBlockDefIter->getRecord(OdDb::kForRead); if( !pRec->isKindOf(OdDbBlockTableRecord::desc()) ) { continue; } OdDbBlockTableRecordPtr pBlockDef = pRec; if( !pBlockDef.isNull() && pBlockDef->isFromExternalReference() && (pBlockDef->pathName() == xRefFileName) ) { pXRefDef = pBlockDef; break; } } if( pXRefDef.isNull() ) { OdString strXRefBlockNameBase = xRefFileName; OdUInt32 iPosition = strXRefBlockNameBase.find(L':'); OdUInt32 iPositionSlash = strXRefBlockNameBase.reverseFind(L'\\'); OdUInt32 iPositionBSlash = strXRefBlockNameBase.reverseFind(L'/'); if( iPosition != -1 ) { iPosition = strXRefBlockNameBase.reverseFind( L'\\' ); if( iPosition != -1 ) strXRefBlockNameBase.deleteChars( 0, iPosition + 1 ); else { iPosition = strXRefBlockNameBase.reverseFind( L'/' ); if( iPosition != -1 ) strXRefBlockNameBase.deleteChars( 0, iPosition + 1 ); } } else if( iPositionSlash != -1 ) strXRefBlockNameBase.deleteChars( 0, iPositionSlash + 1 ); else if( iPositionBSlash != -1 ) strXRefBlockNameBase.deleteChars( 0, iPositionBSlash + 1 ); if( strXRefBlockNameBase.getLength() > 4 && (strXRefBlockNameBase[strXRefBlockNameBase.getLength() - 4] == OdChar('.')) ) { strXRefBlockNameBase = strXRefBlockNameBase.left( strXRefBlockNameBase.getLength() - 4 ); } OdString strXRefBlockName = strXRefBlockNameBase; OdUInt32 uCount = 1; while( !pBlockDefTable->getAt( strXRefBlockName ).isNull() ) { strXRefBlockName.format(L"_%d", uCount ); strXRefBlockName = strXRefBlockNameBase + strXRefBlockName; } OdString repairedName; if( OdDbSymUtil::repairSymbolName(repairedName, strXRefBlockName, pDwgDb ) == eOk && !repairedName.isEmpty() ) strXRefBlockName = repairedName; pXRefDef = OdDbXRefManExt::addNewXRefDefBlock(pDwgDb, xRefFileName, strXRefBlockName, false); } } } if( !pXRefDef.isNull() ) { pBlockReference = OdDbBlockReference::createObject(); pBlockReference->setDatabaseDefaults(pDwgDb); owner->appendOdDbEntity(pBlockReference); pBlockReference->setBlockTableRecord(pXRefDef->objectId()); // Calculate scale OdDgReferenceAttachmentHeader::OdDgReferenceForeignUnits iDefaultUnits = pXRef->getForeignUnits(); double dDefaultUnitScale = OdDgReferenceAttachmentHeader::getForeignUnitsScale( iDefaultUnits ); double dScale = dDefaultUnitScale; if( iDefaultUnits == OdDgReferenceAttachmentHeader::kDesignCenterUnits ) { if( pXRefDb.isNull() ) { pXRefDb = pDwgDb->appServices()->readFile(xRefFileName, false, true); } OdDb::UnitsValue iBaseUnit = OdDb::kUnitsUndefined; if( !pXRefDb.isNull() ) { iBaseUnit = pXRefDb->getINSUNITS(); } if( iBaseUnit <= OdDb::kUnitsUndefined || iBaseUnit > OdDb::kUnitsMax ) { dScale = dDefaultUnitScale; } else { dScale = oddbGetUnitsConversion( iBaseUnit, OdDb::kUnitsMeters ); } } OdDgModelPtr pXRefOwnerModel; OdDgElementId idXRefOwner = pXRef->ownerId(); if( !idXRefOwner.isNull() ) { OdDgElementPtr pOwner = idXRefOwner.openObject(OdDg::kForRead); if( pOwner->isKindOf(OdDgModel::desc() ) ) { pXRefOwnerModel = pOwner; } } if( !pXRefOwnerModel.isNull() ) { OdDgModel::WorkingUnit coincidedUnit; coincidedUnit = OdDgModel::kWuWorldUnit; dScale *= pXRefOwnerModel->getMeasuresConversion( coincidedUnit, pXRefOwnerModel->getWorkingUnit() ); dScale *= pXRef->getScale(); } // if (!pXRefOwnerModel.isNull()) { if (pXRef->getViewportFlag()) matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin()).asVector() ); else matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin() + pXRefOwnerModel->getInsertionBase().asVector()).asVector()); } else { matTransform = OdGeMatrix3d::translation(-pXRef->getReferenceOrigin().asVector()); } matTransform = OdGeMatrix3d::scaling( dScale ) * matTransform; matTransform = pXRef->getTransformation() * matTransform; matTransform = OdGeMatrix3d::translation( pXRef->getMasterOrigin().asVector() ) * matTransform; } } else { OdString msg; msg.format(OD_T("%ls is missing"), xRefFileName.isEmpty() ? databaseShortName.c_str() : xRefFileName.c_str()); //pDgnDb->appServices()->warning(msg); } } //--------------------------------------------------------------------------------------------------- void importDgnUnderlay( OdDbBlockTableRecord* owner, OdDgReferenceAttachmentHeader* pXRef, OdGeMatrix3d& matTransform, OdDbBlockReferencePtr& pBlockReference ) { OdString databaseShortName = pXRef->getFileName(); OdString databaseFullName = pXRef->getFullFileName(); OdString modelName = pXRef->getModelName(); OdDgModelPtr pModel = pXRef->getReferencedModel(); if( !pModel.isNull() ) { modelName = pModel->getName(); databaseFullName = pModel->database()->getFilename(); } OdDgDatabase* pDgnDb = pXRef->database(); OdString xRefFileName; if( !databaseFullName.isEmpty() ) { xRefFileName = pDgnDb->appServices()->findFile( databaseFullName, pDgnDb, OdDgHostAppServices::kXRefDrawing ); } if( xRefFileName.isEmpty() ) { xRefFileName = pDgnDb->appServices()->findFile( databaseShortName, pDgnDb, OdDgHostAppServices::kXRefDrawing ); } OdDbObjectId idDgnDef; OdDbDatabase* pDwgDb = owner->database(); OdDbDictionaryPtr pDict = pDwgDb->getNamedObjectsDictionaryId().safeOpenObject(); OdDbObjectId idDefDict = pDict->getAt(OdDbDgnDefinition::dictionaryKey( OdDbDgnDefinition::desc())); if(!idDefDict.isNull()) { OdDbDictionaryPtr pDgnUnderlayDict = idDefDict.openObject(OdDb::kForRead); if( !pDgnUnderlayDict.isNull() ) { OdDbDictionaryIteratorPtr pIter = pDgnUnderlayDict->newIterator(); for(; !pIter->done(); pIter->next() ) { OdDbDgnDefinitionPtr pCurDgnUnderlay = pIter->object(); if( (pCurDgnUnderlay->getSourceFileName() == xRefFileName) && (pCurDgnUnderlay->getItemName() == modelName) ) { idDgnDef = pCurDgnUnderlay->objectId(); break; } } } } if( idDgnDef.isNull() ) { OdDbDgnDefinitionPtr pDgnDef = OdDbDgnDefinition::createObject(); pDgnDef->setSourceFileName(xRefFileName); pDgnDef->setItemName(modelName); // Post to database OdUInt32 uIndex = 0; for (;;) { try { OdString sName; sName.format(L"dgnUnderlay_%d", uIndex++); OdDbObjectId idDef = pDgnDef->postDefinitionToDb(owner->database(), sName); if( !idDef.isNull() ) { idDgnDef = idDef; } break; } catch (const OdError ) { } } } if( !idDgnDef.isNull() ) { double dModelMeasuresConversion = 1.0; double dEntireScale = 1.0; if( !pModel.isNull() ) { dModelMeasuresConversion = pModel->getMeasuresConversion( OdDgModel::kWuUnitOfResolution, pModel->getWorkingUnit() ); dEntireScale = pXRef->getEntireScale(); } if (!pModel.isNull()) { if (pXRef->getViewportFlag()) matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin()).asVector() * dModelMeasuresConversion); else matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin() + pModel->getInsertionBase().asVector()).asVector() * dModelMeasuresConversion); } else { matTransform = OdGeMatrix3d::translation(-pXRef->getReferenceOrigin().asVector() * dModelMeasuresConversion); } matTransform = OdGeMatrix3d::scaling( dEntireScale ) * matTransform; matTransform = pXRef->getTransformation() * matTransform; matTransform = OdGeMatrix3d::translation( pXRef->getMasterOrigin().asVector() ) * matTransform; OdDbDgnReferencePtr pDgnRef = OdDbDgnReference::createObject(); pDgnRef->setDatabaseDefaults(owner->database()); owner->appendOdDbEntity(pDgnRef); pDgnRef->setDefinitionId(idDgnDef); pDgnRef->setTransform( matTransform ); } } bool isEqualLevelTables(const OdDgDatabase* pDb, const OdDgLevelTable* pXRefLevelTable, OdArray& arrLevelDif, bool bRefurnFalseIfSymbologyDif = false) { bool bRet = true; OdDgLevelTablePtr pLevelTable = pDb->getLevelTable(); OdDgElementIteratorPtr pIter = pXRefLevelTable->createIterator(); OdDgnImportViewFlags curFlags = OdDgnImportContext::getActualViewFlags(); for( ; !pIter->done(); pIter->step() ) { OdDgLevelTableRecordPtr pLevel = pIter->item().openObject(OdDg::kForRead); if( pLevel.isNull() ) continue; OdDgElementId idNativeLevel = pLevelTable->getAt(pLevel->getName()); if( idNativeLevel.isNull() ) { bRet = false; break; } OdDgLevelTableRecordPtr pNativeLevel = idNativeLevel.openObject(OdDg::kForRead); if (pNativeLevel.isNull()) { bRet = false; break; } if( curFlags.getUseLevelSymbologyFlag() ) { if (pLevel->getUseOverrideColorFlag() != pNativeLevel->getUseOverrideColorFlag()) { if( bRefurnFalseIfSymbologyDif ) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if(pLevel->getUseOverrideColorFlag()) { if (pLevel->getOverrideColorIndex() != pNativeLevel->getOverrideColorIndex()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } } else if (pLevel->getElementColorIndex() != pNativeLevel->getElementColorIndex()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if (pLevel->getUseOverrideLineStyleFlag() != pNativeLevel->getUseOverrideLineStyleFlag()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if (pLevel->getUseOverrideLineStyleFlag()) { if (pLevel->getOverrideLineStyleEntryId() != pNativeLevel->getOverrideLineStyleEntryId()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } } else if (pLevel->getElementLineStyleEntryId() != pNativeLevel->getElementLineStyleEntryId()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if (pLevel->getUseOverrideLineWeightFlag() != pNativeLevel->getUseOverrideLineWeightFlag()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if( pLevel->getUseOverrideLineWeightFlag() ) { if (pLevel->getOverrideLineWeight() != pNativeLevel->getOverrideLineWeight()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } } else if (pLevel->getElementLineWeight() != pNativeLevel->getElementLineWeight()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } } else { if (pLevel->getElementColorIndex() != pNativeLevel->getElementColorIndex()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if (pLevel->getElementLineStyleEntryId() != pNativeLevel->getElementLineStyleEntryId()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } if (pLevel->getElementLineWeight() != pNativeLevel->getElementLineWeight()) { if (bRefurnFalseIfSymbologyDif) { bRet = false; break; } arrLevelDif.push_back(pNativeLevel->getName()); continue; } } } return bRet; } //--------------------------------------------------------------------------------------------------- bool updateLayerProperties(OdDbLayerTableRecord* pLayer, const OdDgLevelTableRecord* pLevel, bool bUseLevelSymbology = false) { bool bRet = false; OdUInt32 uColorIndex; OdUInt32 uLineWeight; OdUInt32 uLineStyleEntryId; if( bUseLevelSymbology) { if (pLevel->getUseOverrideColorFlag()) uColorIndex = pLevel->getOverrideColorIndex(); else uColorIndex = pLevel->getElementColorIndex(); if (pLevel->getUseOverrideLineWeightFlag()) uLineWeight = pLevel->getOverrideLineWeight(); else uLineWeight = pLevel->getElementLineWeight(); if (pLevel->getUseOverrideLineStyleFlag()) uLineStyleEntryId = pLevel->getOverrideLineStyleEntryId(); else uLineStyleEntryId = pLevel->getElementLineStyleEntryId(); } else { uColorIndex = pLevel->getElementColorIndex(); uLineWeight = pLevel->getElementLineWeight(); uLineStyleEntryId = pLevel->getElementLineStyleEntryId(); } OdCmColor dwgColor; setDwgColorByDgnIndex(pLevel->database(), dwgColor, uColorIndex); if (dwgColor != pLayer->color()) { pLayer->setColor(dwgColor); bRet = true; } OdDb::LineWeight uCurWeight = odDgnImportLineweightMapping(uLineWeight); if( uCurWeight != pLayer->lineWeight() ) { pLayer->setLineWeight(uCurWeight); bRet = true; } OdUInt32 entryId = uLineStyleEntryId; OdDbObjectId ltpId; if (entryId < 8 && entryId >= 0) { if (entryId == 0) ltpId = pLayer->database()->getLinetypeContinuousId(); else ltpId = OdDbLinetypeTable::cast(pLayer->database()->getLinetypeTableId().openObject())->getAt(OdString().format(OD_T("DGN%u"), entryId)); } else if (entryId == OdDg::kLineStyleByLevel) ltpId = pLayer->database()->getLinetypeByLayerId(); else if (entryId == OdDg::kLineStyleByCell) ltpId = pLayer->database()->getLinetypeByBlockId(); else { ltpId = pLayer->database()->getLinetypeContinuousId(); OdDgElementId idLineStyle = pLevel->database()->getLineStyleTable()->getAt(pLevel->getElementLineStyleEntryId()); if( pLevel->database() ) { OdDgElementId idDgLineStyle = pLevel->database()->getLineStyleTable(OdDg::kForRead)->getAt(entryId); if (!idDgLineStyle.isNull()) { OdDbObjectId ltpId = OdDgnImportContext::getObjectId(idDgLineStyle); if (ltpId.isNull()) ltpId = pLayer->database()->getLinetypeContinuousId(); else if (ltpId == OdDgnImportContext::getDgnContinuousLineStyleId()) ltpId = pLayer->database()->getLinetypeContinuousId(); } } } if( ltpId != pLayer->linetypeObjectId() ) { pLayer->setLinetypeObjectId(ltpId); bRet = true; } return bRet; } //--------------------------------------------------------------------------------------------------- bool isBlockDefHasLayerDifDependences(const OdDbObjectId& idBlockDef, const std::map< OdDbObjectId, OdDbObjectId>& mapLayersToCopy) { bool bRet = false; if (idBlockDef.isNull()) return bRet; OdDbBlockTableRecordPtr pBlock = idBlockDef.openObject(OdDb::kForRead); OdDbObjectIteratorPtr pIter = pBlock->newIterator(); for (; !pIter->done(); pIter->step()) { OdDbEntityPtr pEnt = pIter->entity(); std::map< OdDbObjectId, OdDbObjectId>::const_iterator pLayerIter = mapLayersToCopy.find(pEnt->layerId()); if (pLayerIter == mapLayersToCopy.end()) { if (pEnt->isA() == OdDbBlockReference::desc()) { OdDbBlockReferencePtr pBlockRef = pEnt; OdDbObjectId idRefBlockDef = pBlockRef->blockTableRecord(); if( isBlockDefHasLayerDifDependences(idRefBlockDef, mapLayersToCopy) ) { bRet = true; break; } } continue; } bRet = true; break; } return bRet; } //--------------------------------------------------------------------------------------------------- OdDbObjectId createBlockDefForLayerDif(const OdDbObjectId& idBlockDef, const std::map< OdDbObjectId, OdDbObjectId>& mapLayerCopy, OdUInt64 uViewportHandle, std::map& mapClonedBlocks) { OdDbObjectId idRet; std::map::iterator pBlockMapIter = mapClonedBlocks.find(idBlockDef); if (pBlockMapIter != mapClonedBlocks.end()) return pBlockMapIter->second; if (idBlockDef.isNull() || !isBlockDefHasLayerDifDependences(idBlockDef, mapLayerCopy) ) return idRet; OdDbDatabase* pDb = idBlockDef.database(); OdDbBlockTablePtr pBlockTable = pDb->getBlockTableId().openObject(OdDb::kForWrite); OdDbBlockTableRecordPtr pBlock = idBlockDef.openObject(OdDb::kForRead); OdDbBlockTableRecordPtr pBlockClone = pBlock->clone(); OdString strVpBlockNameBase; strVpBlockNameBase.format(L"_VP%d", uViewportHandle); strVpBlockNameBase = pBlockClone->getName() + strVpBlockNameBase; OdString strVpBlockName = strVpBlockNameBase; OdUInt32 iCount = 1; while (!pBlockTable->getAt(strVpBlockName).isNull()) { OdString strNum; strNum.format(L"_%d", iCount); strVpBlockName = strVpBlockNameBase + strNum; iCount++; } OdString repairedName; if (OdDbSymUtil::repairSymbolName(repairedName, strVpBlockName, pDb) == eOk && !repairedName.isEmpty()) strVpBlockName = repairedName; pBlockClone->setName(strVpBlockName); OdDbObjectIteratorPtr pIter = pBlockClone->newIterator(); for(; !pIter->done(); pIter->step()) { OdDbEntityPtr pEntClone = pIter->entity(); std::map< OdDbObjectId, OdDbObjectId>::const_iterator pLayerIter = mapLayerCopy.find(pEntClone->layerId()); if( pLayerIter != mapLayerCopy.end() ) { if (pLayerIter != mapLayerCopy.end()) pEntClone->setLayer(pLayerIter->second); } if(pEntClone->isA() == OdDbBlockReference::desc() ) { OdDbBlockReferencePtr pBlockRef = pEntClone; OdDbObjectId idBlockDef = pBlockRef->blockTableRecord(); if (!idBlockDef.isNull()) { OdDbObjectId idNewBlockDef = createBlockDefForLayerDif(idBlockDef, mapLayerCopy, uViewportHandle, mapClonedBlocks); if (!idNewBlockDef.isNull()) pBlockRef->setBlockTableRecord(idNewBlockDef); } } } pBlockTable->add(pBlockClone); idRet = pBlockClone->id(); mapClonedBlocks[idBlockDef] = idRet; return idRet; } //--------------------------------------------------------------------------------------------------- void createLayerDifViewport(const OdDbDatabase* pDb, const OdArray& arrLevelDif, const OdDbObjectIdArray& arrThawLayers, const OdDgLevelTable* pDgnLevelTable, OdUInt64 uViewportHandle, std::map& mapLayersForUpdate, std::map& mapLayerNamesForUpdate) { if( (arrLevelDif.isEmpty() && arrThawLayers.isEmpty()) || !pDgnLevelTable) return; OdDbLayerTablePtr pDwgLayerTable = pDb->getLayerTableId().openObject(OdDb::kForWrite); OdDgnImportViewFlags curFlags = OdDgnImportContext::getActualViewFlags(); for (OdUInt32 i = 0; i < arrLevelDif.size(); i++) { OdDbObjectId idLayer = pDwgLayerTable->getAt(arrLevelDif[i]); OdDgElementId idLevel = pDgnLevelTable->getAt(arrLevelDif[i]); if (idLayer.isNull() || idLevel.isNull()) continue; OdDgLevelTableRecordPtr pLevel = idLevel.openObject(OdDg::kForRead); OdDbLayerTableRecordPtr pLayer = idLayer.openObject(OdDb::kForRead); OdDbLayerTableRecordPtr pLayerClone = pLayer->clone(); if (!updateLayerProperties(pLayerClone, pLevel, curFlags.getUseLevelSymbologyFlag())) continue; OdString strVpLayerNameBase; strVpLayerNameBase.format(L"_VP%d", uViewportHandle); strVpLayerNameBase = pLayerClone->getName() + strVpLayerNameBase; OdString strVpLayerName = strVpLayerNameBase; OdUInt32 iCount = 1; while (!pDwgLayerTable->getAt(strVpLayerName).isNull()) { OdString strNum; strNum.format(L"_%d", iCount); strVpLayerName = strVpLayerNameBase + strNum; iCount++; } OdString repairedName; if (OdDbSymUtil::repairSymbolName(repairedName, strVpLayerName, pDb) == eOk && !repairedName.isEmpty()) strVpLayerName = repairedName; OdString strDesc; strDesc.format(L"for viewport 0x%x", uViewportHandle); strDesc = L"Layer \"" + pLayer->getName() + L"\" override " + strDesc; pLayerClone->setName(strVpLayerName); pLayerClone->setDescription(strDesc); pLayerClone->setIsFrozen(false); pLayerClone->setIsOff(false); pDwgLayerTable->add(pLayerClone); mapLayersForUpdate[pLayer->id()] = pLayerClone->id(); mapLayerNamesForUpdate[pLevel->getName()] = pLayerClone->id(); } // Add thad layers for (OdUInt32 j = 0; j < arrThawLayers.size(); j++) { std::map::iterator pIter = mapLayersForUpdate.find(arrThawLayers[j]); if (pIter != mapLayersForUpdate.end()) continue; OdDbLayerTableRecordPtr pLayer = arrThawLayers[j].openObject(OdDb::kForRead); OdDbLayerTableRecordPtr pLayerClone = pLayer->clone(); OdDgElementId idLevel = pDgnLevelTable->getAt(pLayer->getName()); OdDgLevelTableRecordPtr pLevel; if( !idLevel.isNull() ) pLevel = idLevel.openObject(OdDg::kForRead); OdString strVpLayerNameBase; strVpLayerNameBase.format(L"_VP%d", uViewportHandle); strVpLayerNameBase = pLayerClone->getName() + strVpLayerNameBase; OdString strVpLayerName = strVpLayerNameBase; OdUInt32 iCount = 1; while (!pDwgLayerTable->getAt(strVpLayerName).isNull()) { OdString strNum; strNum.format(L"_%d", iCount); strVpLayerName = strVpLayerNameBase + strNum; iCount++; } OdString repairedName; if (OdDbSymUtil::repairSymbolName(repairedName, strVpLayerName, pDb) == eOk && !repairedName.isEmpty()) strVpLayerName = repairedName; OdString strDesc; strDesc.format(L"for viewport 0x%x", uViewportHandle); strDesc = L"Layer \"" + pLayer->getName() + L"\" override " + strDesc; pLayerClone->setName(strVpLayerName); pLayerClone->setDescription(strDesc); pLayerClone->setIsFrozen(false); pLayerClone->setIsOff(false); pDwgLayerTable->add(pLayerClone); mapLayersForUpdate[pLayer->id()] = pLayerClone->id(); if (!pLevel.isNull()) mapLayerNamesForUpdate[pLevel->getName()] = pLayerClone->id(); } } //--------------------------------------------------------------------------------------------------- bool hasViewportLevels(const OdDgGraphicsElement* pDgElement) { bool bRet = false; if( !pDgElement ) return bRet; OdDgElementId idLevel = pDgElement->getLevelId(); if(pDgElement->isKindOf(OdDgCellHeader2d::desc()) || pDgElement->isKindOf(OdDgCellHeader3d::desc()) || pDgElement->isKindOf(OdDgSolid::desc()) || pDgElement->isKindOf(OdDgSurface::desc()) || pDgElement->isKindOf(OdDgComplexShape::desc()) || pDgElement->isKindOf(OdDgComplexString::desc()) ) { OdDgElementIteratorPtr pIter = createComplexElementIterator(pDgElement); if( !pIter.isNull() ) { for (; !pIter->done(); pIter->step()) { OdDgGraphicsElementPtr pGrItem = OdDgGraphicsElement::cast(pIter->item().openObject(OdDg::kForRead)); bRet = hasViewportLevels(pGrItem); if (bRet) break; } } } else if( !idLevel.isNull() ) { OdDbObjectId idLayer = OdDgnImportContext::getViewportLayer(idLevel); bRet = !idLayer.isNull(); } return bRet; } //--------------------------------------------------------------------------------------------------- void copyModelSpaceLayerDifsForViewport(OdDbBlockTableRecord* pBlockDef, const std::map mapLayersForUpdate, OdUInt64 uViewportHandle) { if( OdDgnImportContext::getModelSpaceId().isNull() ) return; OdDgModelPtr pDgnModel = OdDgnImportContext::getModelSpaceId().openObject(OdDg::kForRead); if( pDgnModel.isNull() ) return; // Set global line style scale double dActualLineTypeScale = 1.0; bool bRestoreGlobalLineScale = !pDgnModel.isNull() && !OdDgnImportContext::getGlobalLineScale(dActualLineTypeScale); if (bRestoreGlobalLineScale) { dActualLineTypeScale = pDgnModel->getLinestyleScale(); if (pDgnModel->getCompoundLineScaleFlag()) { if (OdZero(dActualLineTypeScale)) dActualLineTypeScale = 1.0; double dAnnotationScale = pDgnModel->getAnnotationScale(); if (OdZero(dAnnotationScale)) dAnnotationScale = 1.0; dActualLineTypeScale *= dAnnotationScale; } else if (pDgnModel->getAnnotationLineScaleFlag()) dActualLineTypeScale = pDgnModel->getAnnotationScale(); if (OdZero(dActualLineTypeScale)) dActualLineTypeScale = pDgnModel->database()->getLineStyleScale(); if (OdZero(dActualLineTypeScale)) dActualLineTypeScale = 1.0; OdDgnImportContext::pushGlobalLineScale(dActualLineTypeScale); } // std::map mapClonedBlocks; OdDgElementIdArray arrRasterRefsBefore; OdDgElementIdArray arrRasterRefsAfter; for (OdDgElementIteratorPtr pIter = pDgnModel->createControlElementsIterator(); !pIter->done(); pIter->step()) { OdRxObjectPtr unknownElement = pIter->item().openObject(OdDg::kForRead); if (unknownElement->isKindOf(OdDgRasterAttachmentHeader::desc())) { OdDgRasterAttachmentHeaderPtr pRasterHeader = unknownElement; if (!pRasterHeader.isNull()) { if (pRasterHeader->getRasterPlane() == OdDgRasterAttachmentHeader::kBackground) { arrRasterRefsBefore.push_back(pIter->item()); } else if (pRasterHeader->getRasterPlane() == OdDgRasterAttachmentHeader::kForeground) { arrRasterRefsAfter.push_back(pIter->item()); } } } } OdUInt32 i = 0; for (i = 0; i < arrRasterRefsBefore.size(); i++) { OdDgElementPtr pRasterAttachment = arrRasterRefsBefore[i].openObject(OdDg::kForRead); if (!pRasterAttachment.isNull()) { OdDbObjectId idObject = OdDgnImportContext::getObjectId(pRasterAttachment->elementId()); if (!idObject.isNull()) { OdDbEntityPtr pEnt = OdDbEntity::cast(idObject.openObject(OdDb::kForRead)); if (!pEnt.isNull()) { std::map::const_iterator pLayerIter = mapLayersForUpdate.find(pEnt->layerId()); OdDbEntityPtr pEntClone; if (pLayerIter != mapLayersForUpdate.end()) { pEntClone = pEnt->clone(); if( pEntClone->visibility() == OdDb::kInvisible ) pEntClone->setVisibility(OdDb::kVisible); pEntClone->setLayer(pLayerIter->second); pBlockDef->appendOdDbEntity(pEntClone); } } } } } for (OdDgElementIteratorPtr pIter = pDgnModel->createGraphicsElementsIterator(); !pIter->done(); pIter->step()) { OdDgGraphicsElementPtr pDgElement = OdDgGraphicsElement::cast(pIter->item().openObject()); if (!pDgElement.isNull()) { OdDbObjectId idObject = OdDgnImportContext::getObjectId(pDgElement->elementId()); if( !idObject.isNull() ) { OdDbEntityPtr pEnt = OdDbEntity::cast(idObject.openObject(OdDb::kForRead)); if( !pEnt.isNull() ) { std::map::const_iterator pLayerIter = mapLayersForUpdate.find(pEnt->layerId()); OdDbEntityPtr pEntClone; if (pLayerIter != mapLayersForUpdate.end()) { pEntClone = pEnt->clone(); if ((pEntClone->visibility() == OdDb::kInvisible) && !checkVisibility(pDgElement)) pEntClone->setVisibility(OdDb::kVisible); pEntClone->setLayer(pLayerIter->second); pBlockDef->appendOdDbEntity(pEntClone); } if( pEnt->isA() == OdDbBlockReference::desc() ) { OdDbBlockReferencePtr pBlockRef = pEnt; OdDbObjectId idBlockDef = pBlockRef->blockTableRecord(); if( !idBlockDef.isNull() ) { OdDbObjectId idBlockClone = createBlockDefForLayerDif(idBlockDef, mapLayersForUpdate, uViewportHandle, mapClonedBlocks); if (!idBlockClone.isNull()) { if( pEntClone.isNull() ) { pEntClone = pEnt->clone(); if ((pEntClone->visibility() == OdDb::kInvisible) && !checkVisibility(pDgElement)) pEntClone->setVisibility(OdDb::kVisible); pBlockDef->appendOdDbEntity(pEntClone); } OdDbBlockReferencePtr pCloneBlockRef = pEntClone; pCloneBlockRef->setBlockTableRecord(idBlockClone); } } } } } else { if( hasViewportLevels(pDgElement) ) ((OdDgnImportPE*)pDgElement->queryX(OdDgnImportPE::desc()))->importElement(pDgElement, pBlockDef); } } } for (i = 0; i < arrRasterRefsAfter.size(); i++) { OdDgElementPtr pRasterAttachment = arrRasterRefsAfter[i].openObject(OdDg::kForRead); if (!pRasterAttachment.isNull()) { OdDbObjectId idObject = OdDgnImportContext::getObjectId(pRasterAttachment->elementId()); if (!idObject.isNull()) { OdDbEntityPtr pEnt = OdDbEntity::cast(idObject.openObject(OdDb::kForRead)); if (!pEnt.isNull()) { std::map::const_iterator pLayerIter = mapLayersForUpdate.find(pEnt->layerId()); OdDbEntityPtr pEntClone; if (pLayerIter != mapLayersForUpdate.end()) { pEntClone = pEnt->clone(); if (pEntClone->visibility() == OdDb::kInvisible) pEntClone->setVisibility(OdDb::kVisible); pEntClone->setLayer(pLayerIter->second); pBlockDef->appendOdDbEntity(pEntClone); } } } } } if (bRestoreGlobalLineScale) OdDgnImportContext::popGlobalLineScale(); } //--------------------------------------------------------------------------------------------------- void createViewportLevelDifferenceBlock(OdDbBlockTableRecord* pDbPaperSpace, const OdDbObjectId& idModelSpace, const std::map mapLayersForUpdate, const OdDgLevelTable* pXRefLevelTable, OdUInt64 uViewportHandle, const OdGeMatrix3d& matTransform, bool bUseClip, OdGiClipBoundary& clipBoundary ) { if( idModelSpace.isNull() ) return; OdDbDatabasePtr pDb = idModelSpace.database(); OdDbBlockTablePtr pBlockDefTable = pDb->getBlockTableId().openObject(OdDb::kForWrite); // Craete block name OdString strBlockDefNameBase; strBlockDefNameBase.format(L"LayerDifsForViewport_%d", uViewportHandle); OdString strBlockDefName = strBlockDefNameBase; OdUInt32 uCount = 1; while (!pBlockDefTable->getAt(strBlockDefName).isNull()) { strBlockDefName.format(L"_%d", uCount); strBlockDefName = strBlockDefNameBase + strBlockDefName; uCount++; } OdString repairedName; if( OdDbSymUtil::repairSymbolName(repairedName, strBlockDefName, pDb) == eOk && !repairedName.isEmpty() ) { strBlockDefNameBase = repairedName; strBlockDefName = strBlockDefNameBase; } // Craete block definition OdDbBlockTableRecordPtr pBlockDef = OdDbBlockTableRecord::createObject(); pBlockDef->setName(strBlockDefName); pBlockDefTable->add(pBlockDef); // Add model space entities to block def. copyModelSpaceLayerDifsForViewport(pBlockDef, mapLayersForUpdate, uViewportHandle); // Create block reference. OdDbBlockReferencePtr pBlockReference = OdDbBlockReference::createObject(); pBlockReference->setBlockTableRecord(pBlockDef->id()); pBlockReference->setBlockTransform(matTransform); pDbPaperSpace->appendOdDbEntity(pBlockReference); // Clip block reference. if( bUseClip ) { if (pBlockReference->extensionDictionary().isNull()) pBlockReference->createExtensionDictionary(); OdDbDictionaryPtr pDict = OdDbDictionary::cast(pBlockReference->extensionDictionary().openObject(OdDb::kForWrite)); if (!pDict.isNull()) { OdDbDictionaryPtr pFDict = OdDbDictionary::cast(pDict->getAt(OD_T("ACAD_FILTER"), OdDb::kForWrite)); if (pFDict.isNull()) { pFDict = OdDbDictionary::createObject(); pDict->setAt(OD_T("ACAD_FILTER"), pFDict); } if (!pFDict.isNull()) { OdDbSpatialFilterPtr pSp = OdDbSpatialFilter::cast(pFDict->getAt(OD_T("SPATIAL"), OdDb::kForWrite)); if (pSp.isNull()) { pSp = OdDbSpatialFilter::createObject(); pFDict->setAt(OD_T("SPATIAL"), pSp); } if (!pSp.isNull()) { double dFrontClip = ODDB_INFINITE_XCLIP_DEPTH; double dBackClip = ODDB_INFINITE_XCLIP_DEPTH; pSp->setDefinition(clipBoundary); } } } } } void synchronizeLevelTablesForSelfReference(const OdDgLevelTable* pXRefLevelTable, OdDbDatabase* pDwgDb) { if (!pXRefLevelTable || !pDwgDb ) return; OdDbLayerTablePtr pLayerTable = pDwgDb->getLayerTableId().openObject(OdDb::kForRead); OdDgElementIteratorPtr pLevelIter = pXRefLevelTable->createIterator(); for (; !pLevelIter->done(); pLevelIter->step()) { OdDgLevelTableRecordPtr pLevel = pLevelIter->item().openObject(OdDg::kForRead, true); OdDbObjectId idLayer = pLayerTable->getAt(pLevel->getName()); if( !idLayer.isNull() ) { OdDgnImportPathToDwgObject dwgPath; dwgPath.m_bExists = true; dwgPath.m_idPath.objectIds().push_back(idLayer); OdDgnImportContext::getDgnImporter()->addObjectPath(pLevel->elementId(), dwgPath); } } } //--------------------------------------------------------------------------------------------------- void importDgnXRef( OdDbBlockTableRecord* owner, OdDgReferenceAttachmentHeader* pXRef, OdGeMatrix3d& matTransform, OdDbBlockReferencePtr& pBlockReference, OdUInt8 uXRefImportMode, OdDgnImport* pBaseImporter ) { OdDgModelPtr pModel = pXRef->getReferencedModel(); OdString strFilename = pModel->database()->getFilename(); if( uXRefImportMode == 3 ) // Create dgn underlay { importDgnUnderlay( owner, pXRef, matTransform, pBlockReference ); return; } // Try to find model of x-ref into map OdString strGroupName = pXRef->getNamedGroupName(); if( !strGroupName.isEmpty() ) { strFilename += strGroupName; } OdInt32 uViewNumber = -1; if (!OdDgnImportContext::getActiveView().isNull()) uViewNumber = OdDgnImportContext::getActiveView()->getIndex(); OdDgnImportViewFlags xRefFlags; OdDgnImportViewFlags oldViewFlags = OdDgnImportContext::getActualViewFlags(); xRefFlags.init(pXRef, (OdUInt32)(uViewNumber), OdDgnImportContext::getActualViewFlags()); OdDgnImportContext::pushViewFlags(xRefFlags); bool bOldUseLevelOverrides = OdDgnImportContext::getUseLevelOverrideFlag(); OdDgElementId idOldLevelOverride = OdDgnImportContext::getOverridedLevelTable(); OdDgLevelTablePtr pXRefLevelTable = getActualXRefLevelTable(pXRef, pModel->database()); OdArray arrLevelDif; bool bEqualLevelTables = isEqualLevelTables(pModel->database(), pXRefLevelTable, arrLevelDif, OdDgnImportContext::getViewportImportMode() == 0); OdDgLevelTablePtr pLevelTableForXRefRegistration = bEqualLevelTables && arrLevelDif.isEmpty() ? pModel->database()->getLevelTable(OdDg::kForRead) : pXRefLevelTable; bool bUseLevelOverrides = OdDgnImportContext::getUseLevelOverrideFlag(); DgnImporter* pImport = OdDgnImportContext::getDgnImporter(); OdRxVariantValue tmpVar = (OdRxVariantValue)pImport->properties()->getAt("ImportViewIndex"); OdInt8 uImportViewNumber = tmpVar->getInt8(); OdString strLevelMaskExt = OdString::kEmpty; OdGiClipBoundary clipBoundary; bool useClipBoundary = false; bool bInverceClip = false; OdDgReferenceAttachClipBoundaryPEPtr pBoundaryPE; // Try to import reference attachment as viewport bool bAllowToImportViewport = strGroupName.isEmpty() && bEqualLevelTables && (oldViewFlags == xRefFlags) && (OdDgnImportContext::getXRefNestedDepth() < 2); if (bAllowToImportViewport) { OdString strDbName = pXRef->database()->getFilename(); if( (strDbName != strFilename) || (OdDgnImportContext::getModelSpaceId().getHandle() != pModel->elementId().getHandle()) ) bAllowToImportViewport = false; if( bAllowToImportViewport ) { double dValue = pXRef->getPaletteValue(); double dSaturation = pXRef->getPaletteSaturation(); bool bFixedColors = pXRef->getPaletteModificationMode() == OdDgReferenceAttachmentHeader::kFixedValueAndSaturation; bool bUseHue = pXRef->getHueFixForAllColorsFlag(); double dHueValue = pXRef->getPaletteHue(); if (bFixedColors || bUseHue || !OdZero(dValue - 100.0) || !OdZero(dSaturation - 100.0)) bAllowToImportViewport = false; } } OdDbObjectIdArray arrFreezeLayers; OdDbObjectIdArray arrThawLayers; OdDgLevelMaskPtr pLevelMask; if (bAllowToImportViewport) { getActualXRefLevelMask(pXRef, uImportViewNumber, pLevelMask); if( !pLevelMask.isNull() ) { OdDgElementIteratorPtr pLevelIter = pXRef->database()->getLevelTable()->createIterator(); for (; !pLevelIter->done(); pLevelIter->step()) { OdDgLevelTableRecordPtr pXRefLevel = pLevelIter->item().openObject(OdDg::kForRead); OdDgLevelMask::OdDgLevelStatus uStatus = pLevelMask->getLevelIsVisible(pXRefLevel->elementId(), !pXRefLevel->getIsDisplayedFlag() ); bool bFreezeLayer = uStatus == OdDgLevelMask::kLevelHidden; if (!bFreezeLayer) bFreezeLayer = pXRefLevel->getIsFrozenFlag(); OdDbObjectId idDbXReflayer = OdDgnImportContext::getObjectId(pXRefLevel->elementId()); if (!idDbXReflayer.isNull()) { if (bFreezeLayer) { arrFreezeLayers.push_back(idDbXReflayer); OdString strXRefLayerName = pXRefLevel->getName(); for (OdUInt32 n = 0; n < arrLevelDif.size(); n++) { if (arrLevelDif[n] == strXRefLayerName) { arrLevelDif.removeAt(n); break; } } } else { OdDbLayerTableRecordPtr pDbXRefLayer = idDbXReflayer.openObject(OdDb::kForRead); if (pDbXRefLayer->isFrozen()) { if( OdDgnImportContext::getViewportImportMode() == 0 ) { bAllowToImportViewport = false; break; } arrThawLayers.push_back(idDbXReflayer); } } } } } } if( bAllowToImportViewport ) { OdDbObjectId idModelSpace = OdDgnImportContext::getObjectId(OdDgnImportContext::getModelSpaceId()); OdGeExtents3d extXRef; if( !idModelSpace.isNull() ) { if( pXRef->getUnloadFlag() ) pXRef->reload(false); OdDgElementId idActiveView; OdDgViewPtr pActiveView = OdDgnImportContext::getActiveView(); if (!pActiveView.isNull()) idActiveView = pActiveView->elementId(); pXRef->getGeomExtents(idActiveView, extXRef); if( !extXRef.isValidExtents() ) { extXRef.addPoint(OdGePoint3d(-1.0, -1.0, -1.0)); extXRef.addPoint(OdGePoint3d(1.0, 1.0, 1.0)); } if (pXRef->getViewportFlag()) { matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin()).asVector() * pModel->getMeasuresConversion(OdDgModel::kWuUnitOfResolution, pModel->getWorkingUnit())); } else { matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin() + pModel->getInsertionBase().asVector()).asVector() * pModel->getMeasuresConversion(OdDgModel::kWuUnitOfResolution, pModel->getWorkingUnit())); } matTransform = OdGeMatrix3d::scaling(pXRef->getEntireScale()) * matTransform; matTransform = pXRef->getTransformation() * matTransform; matTransform = OdGeMatrix3d::translation(pXRef->getMasterOrigin().asVector()) * matTransform; OdGeMatrix3d matTransformBack = matTransform; matTransformBack = matTransformBack.invert(); OdGePoint3d ptCenter = extXRef.center(); OdGePoint3d ptTarget = ptCenter; OdGePoint3d ptDir = ptTarget + OdGeVector3d::kZAxis; OdGePoint3d ptUp = ptTarget + OdGeVector3d::kYAxis; ptTarget.transformBy(matTransformBack); ptDir.transformBy(matTransformBack); ptUp.transformBy(matTransformBack); OdGeVector3d vrDir = ptDir - ptTarget; if (vrDir.isZeroLength()) vrDir = OdGeVector3d::kZAxis; OdGeVector3d vrUp = ptUp - ptTarget; OdGeVector3d vrUpBase = OdGeVector3d::kYAxis; OdGeMatrix3d matYBase = OdGeMatrix3d::planeToWorld(vrDir); vrUpBase.transformBy(matYBase); double dTwistAngle = vrUp.angleTo(vrUpBase, vrDir); OdGePoint3d ptViewBottom = extXRef.center() - OdGeVector3d::kYAxis * (extXRef.maxPoint().y - extXRef.minPoint().y) / 2.0; OdGePoint3d ptViewTop = extXRef.center() + OdGeVector3d::kYAxis * (extXRef.maxPoint().y - extXRef.minPoint().y) / 2.0; ptViewBottom.transformBy(matTransformBack); ptViewTop.transformBy(matTransformBack); double dViewHeight = ptViewBottom.distanceTo(ptViewTop); OdDbViewportPtr pViewport = OdDbViewport::createObject(); pViewport->setDatabaseDefaults(owner->database()); pViewport->setCenterPoint(OdGePoint3d(ptCenter.x, ptCenter.y, 0.0)); pViewport->setElevation(ptCenter.z); pViewport->setWidth(extXRef.maxPoint().x - extXRef.minPoint().x); pViewport->setHeight(extXRef.maxPoint().y - extXRef.minPoint().y); pViewport->setViewTarget(ptTarget); pViewport->setViewDirection(vrDir); pViewport->setColorIndex(7); pViewport->setViewHeight(dViewHeight); pViewport->setTwistAngle(dTwistAngle); pViewport->setBackClipOff(); pViewport->setFrontClipOff(); pViewport->setOn(); if( pXRef->getCameraOnFlag() ) pViewport->setPerspectiveOn(); else pViewport->setPerspectiveOff(); if (pXRef->getUseLevelFlag()) { OdDbObjectId layerId = OdDgnImportContext::getObjectId(pXRef->getLevelId()); if (layerId.isNull()) pViewport->setLayer(owner->database()->getLayerZeroId()); else pViewport->setLayer(layerId); } else pViewport->setLayer(owner->database()->getLayerZeroId()); if (xRefFlags.getUseTransparencyFlag()) { pViewport->setTransparent(); pViewport->setTransparency(pXRef->getTransparency()); } if( pXRef->getUseViewFlagsFlag() && ((OdUInt32)uViewNumber < 8) ) { OdDgReferenceAttachmentViewFlags viewFlags = pXRef->getViewFlags(uViewNumber); OdUInt16 uDisplayMode = viewFlags.getDisplayMode(); switch (uDisplayMode) { case 3: pViewport->setRenderMode(OdDb::kHiddenLine); break; case 4: pViewport->setRenderMode(OdDb::kFlatShaded); break; case 6: // Smooth shading case 7: // Phong shading { pViewport->setRenderMode(OdDb::kGouraudShaded); } break; default: pViewport->setRenderMode(OdDb::k2DOptimized); break; } } owner->appendOdDbEntity(pViewport); std::map mapLayersForUpdate; std::map mapLayerNamesForUpdate; if (!arrLevelDif.isEmpty() || !arrThawLayers.isEmpty()) { createLayerDifViewport(idModelSpace.database(), arrLevelDif, arrThawLayers, pXRefLevelTable, pViewport->objectId().getHandle(), mapLayersForUpdate, mapLayerNamesForUpdate); if( !mapLayersForUpdate.empty()) { std::map::const_iterator pLayerDifIter = mapLayersForUpdate.begin(); for(; pLayerDifIter != mapLayersForUpdate.end(); pLayerDifIter++) arrFreezeLayers.push_back(pLayerDifIter->first); } } if( !arrFreezeLayers.isEmpty() ) pViewport->freezeLayersInViewport(arrFreezeLayers); // clip pBoundaryPE = OdDgReferenceAttachClipBoundaryPEPtr(OdRxObjectPtr(pXRef)); if (!pBoundaryPE.isNull()) useClipBoundary = pBoundaryPE->extractBoundary(pXRef, clipBoundary, 1e-6, false, NULL, bInverceClip, true, matTransform, true); bool bRectClip = false; pViewport->setNonRectClipOn(); OdDb3dPolylinePtr pClipPolyline = OdDb3dPolyline::createObject(); pClipPolyline->setDatabaseDefaults(owner->database()); if (useClipBoundary) { if( bInverceClip ) { OdGePoint3d ptClip = extXRef.minPoint(); OdDb3dPolylineVertexPtr pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip.x = extXRef.maxPoint().x; pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip = extXRef.maxPoint(); pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip.x = extXRef.minPoint().x; pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip = extXRef.minPoint(); pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); } for (OdUInt32 k = 0; k < clipBoundary.m_Points.size(); k++) { OdGePoint3d ptClip(clipBoundary.m_Points[k].x, clipBoundary.m_Points[k].y, 0.0); ptClip.transformBy(matTransform*clipBoundary.m_xInverseBlockRefXForm); OdDb3dPolylineVertexPtr pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); } if( bInverceClip ) { OdGePoint3d ptClip = extXRef.minPoint(); OdDb3dPolylineVertexPtr pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); } else if( (clipBoundary.m_Points.size() == 4) || ((clipBoundary.m_Points.size() == 5) && (clipBoundary.m_Points.first().isEqualTo(clipBoundary.m_Points.last()))) ) { OdGeVector2d vrCheck; bRectClip = true; for( OdUInt32 n = 0; n < clipBoundary.m_Points.size() - 1; n++ ) { vrCheck = clipBoundary.m_Points[n + 1] - clipBoundary.m_Points[n]; if( !vrCheck.isParallelTo(OdGeVector2d::kXAxis) && !vrCheck.isParallelTo(OdGeVector2d::kYAxis) ) { bRectClip = false; break; } } } } else { bRectClip = true; OdGePoint3d ptClip = extXRef.minPoint(); OdDb3dPolylineVertexPtr pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip.x = extXRef.maxPoint().x; pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip = extXRef.maxPoint(); pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip.x = extXRef.minPoint().x; pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); ptClip = extXRef.minPoint(); pVertex = OdDb3dPolylineVertex::createObject(); pVertex->setPosition(ptClip); pClipPolyline->appendVertex(pVertex); } OdDbObjectId idLayerTable = owner->database()->getLayerTableId(); if (!idLayerTable.isNull() ) { OdDbLayerTablePtr pLayerTable = idLayerTable.openObject(OdDb::kForWrite); OdString strViewportClipLayer(L"ViewportBorder"); OdDbObjectId idViewportClipLayer = pLayerTable->getAt(strViewportClipLayer, true); if (idViewportClipLayer.isNull()) { OdDbLayerTableRecordPtr pViewportClipLayer = OdDbLayerTableRecord::createObject(); pViewportClipLayer->setName(strViewportClipLayer); pViewportClipLayer->setIsOff(true); pLayerTable->add(pViewportClipLayer); idViewportClipLayer = pViewportClipLayer->objectId(); } if (bRectClip) pViewport->setLayer(idViewportClipLayer); else if (!idViewportClipLayer.isNull()) pClipPolyline->setLayer(idViewportClipLayer); } OdDbObjectId idClipObject = owner->appendOdDbEntity(pClipPolyline); pViewport->setNonRectClipEntityId(idClipObject); if (bRectClip) { pViewport->setNonRectClipEntityId(OdDbObjectId()); pClipPolyline->erase(true); } if( !mapLayersForUpdate.empty() ) { bool bShowNewLevels = false; if (pXRef->getNewLevelDisplayMode() != OdDgReferenceAttachmentHeader::kConfigVariable) bShowNewLevels = pXRef->getNewLevelDisplayMode() == OdDgReferenceAttachmentHeader::kAlways; else bShowNewLevels = OdDgnImportContext::getShowNewXRefLevelsFlag(); OdDgnImportContext::pushLevelMask(pLevelMask, pXRefLevelTable, bShowNewLevels); OdDgnImportContext::setViewportLevelOverrides(mapLayerNamesForUpdate); createViewportLevelDifferenceBlock(owner, idModelSpace, mapLayersForUpdate, pXRefLevelTable, pViewport->objectId().getHandle(), matTransform, useClipBoundary, clipBoundary); OdDgnImportContext::resetViewportLevelOverrides(); OdDgnImportContext::popLevelMask(); } if (bUseLevelOverrides) { OdDgnImportContext::popLevelTableOverride(); OdDgnImportContext::setUseLevelOverrideFlag(bOldUseLevelOverrides); OdDgnImportContext::setOverridedLevelTable(idOldLevelOverride); } OdDgnImportContext::popViewFlags(); return; } } // Import XRef as reference attachment if( uXRefImportMode == 2 && OdDgnImportContext::isLevelMask() ) { // Set Level Mask OdDgLevelMaskPtr pLevelMask; if( getActualXRefLevelMask( pXRef, uImportViewNumber, pLevelMask ) ) { uImportViewNumber = -1; } OdDgDatabasePtr pXRefDb = pXRef->getReferencedDatabase(); bool bShowNewLevels = false; if (pXRef->getNewLevelDisplayMode() != OdDgReferenceAttachmentHeader::kConfigVariable) bShowNewLevels = pXRef->getNewLevelDisplayMode() == OdDgReferenceAttachmentHeader::kAlways; else bShowNewLevels = OdDgnImportContext::getShowNewXRefLevelsFlag(); if (!pXRefDb.isNull() && pXRefLevelTable.isNull() ) OdDgnImportContext::pushLevelMask(pLevelMask, pXRefDb->getLevelTable(OdDg::kForRead), bShowNewLevels); else OdDgnImportContext::pushLevelMask(pLevelMask, pXRefLevelTable, bShowNewLevels); strLevelMaskExt = OdDgnImportContext::getLevelMaskString(); } bool bAllowToEraseBlockDef = false; OdDgDatabase* pDb = pModel->database(); // Set global line scale OdDgModelPtr pOwnerModel; OdDgElementId idOwner = pXRef->ownerId(); while (!idOwner.isNull()) { OdDgElementPtr pOwner = idOwner.openObject(OdDg::kForRead); if (pOwner->isKindOf(OdDgModel::desc())) { pOwnerModel = pOwner; break; } idOwner = pOwner->ownerId(); } double dLineStyleScale = 1.0; if (!pModel.isNull() && !pOwnerModel.isNull()) { double dCurLineStyleScale = 1.0; if (!OdDgnImportContext::getGlobalLineScale(dCurLineStyleScale)) { dCurLineStyleScale = pOwnerModel->getLinestyleScale(); } double dAssocLineStyleScale = pModel->getLinestyleScale(); if (pXRef->getLineStyleScaleFlag()) { if (OdZero(dAssocLineStyleScale)) { dAssocLineStyleScale = pModel->database()->getLineStyleScale(); } if (OdZero(dAssocLineStyleScale)) { dAssocLineStyleScale = 1.0; } dLineStyleScale *= dAssocLineStyleScale / pXRef->getScale(); } else { switch (pXRef->getLineStyleScaleMode()) { case OdDgReferenceAttachmentHeader::kLSMaster: { dLineStyleScale *= dCurLineStyleScale; }; break; case OdDgReferenceAttachmentHeader::kLSReference: { dLineStyleScale *= dAssocLineStyleScale; }; break; case OdDgReferenceAttachmentHeader::kLSMasterReference: { dLineStyleScale *= dCurLineStyleScale * dAssocLineStyleScale; }; break; } } } OdUInt32 uLevelTableDiff = 0; if( !arrLevelDif.isEmpty() ) { OdDgLevelTablePtr pNativeXRefLevelTable = pXRef->getLevelTable(); if (pNativeXRefLevelTable && ((OdUInt64)(pNativeXRefLevelTable->elementId().getHandle()) != 0)) uLevelTableDiff = (OdUInt32)(pNativeXRefLevelTable->elementId().getHandle()); else uLevelTableDiff = OdDgnImportContext::getNextXRefLevelTableDiffIndex(); } // Try to get cached block OdDbObjectId idBlockDefinition = OdDgnImportContext::getDwgModelBlockId(strFilename, pModel->elementId(), uLevelTableDiff, strLevelMaskExt, dLineStyleScale); if( idBlockDefinition.isNull() ) // Import model of x-ref as block definition { bAllowToEraseBlockDef = true; OdDbObjectId idBlockDefTable = owner->database()->getBlockTableId(); if( !idBlockDefTable.isNull() ) { OdDbBlockTablePtr pBlockDefTable = idBlockDefTable.openObject(OdDb::kForWrite); OdString strBlockDefNameBase = pModel->getName(); strBlockDefNameBase = strBlockDefNameBase.trimLeft(); strBlockDefNameBase = strBlockDefNameBase.trimRight(); OdString strBlockDefName = strBlockDefNameBase; OdUInt32 uCount = 1; while( !pBlockDefTable->getAt( strBlockDefName ).isNull() ) { if( strBlockDefNameBase.isEmpty() ) { strBlockDefName.format(L"DgnModel_%d",uCount ); } else { strBlockDefName.format(L"_%d",uCount ); strBlockDefName = strBlockDefNameBase + strBlockDefName; } uCount++; } OdString repairedName; if( OdDbSymUtil::repairSymbolName(repairedName, strBlockDefName, owner->database() ) == eOk && !repairedName.isEmpty() ) { strBlockDefNameBase = repairedName; strBlockDefName = strBlockDefNameBase; } OdDgnImportContext::pushXRef(strFilename, pModel->elementId(), pLevelTableForXRefRegistration, pXRef->elementId(), pXRef->getNestDepth(), strLevelMaskExt ); bool bRestorePalette = false; // Correct color table if( pDb && ( ((pDb->getOriginalFileVersion() > 7) && (OdDgnImportContext::getXRefNestedDepth() < 2)) || pDb->getColorTable(OdDg::kForRead).isNull()) ) { ODCOLORREF pXRefPalette[256]; if( getXRefPalette( pXRef, pDb, pXRefPalette ) ) { OdDgnImportContext::pushPalette(); bRestorePalette = true; OdDgnImportContext::setPalette( pXRefPalette ); } } bool bUpdateGlobalLineScaleFlag = false; if (!pModel.isNull() && !pOwnerModel.isNull()) { OdDgnImportContext::pushGlobalLineScale(dLineStyleScale); bUpdateGlobalLineScaleFlag = true; } if( (uXRefImportMode == 1) && (pModel->database() != pOwnerModel->database() ) && strGroupName.isEmpty() && bEqualLevelTables ) // Retain X-Ref { if( pImport ) { OdString strNewFileName; if( pDb ) { strNewFileName = pDb->getFilename(); if( strNewFileName.getLength() > 3 ) { strNewFileName = strNewFileName.left( strNewFileName.getLength() - 4); } strNewFileName += L".dwg"; } ExHostAppServices* pHostAppServices = static_cast(pImport->properties()->getAt("Services").get()); bool bXRefPresent = false; OdRxVariantValue tmpVar = (OdRxVariantValue)pImport->properties()->getAt("ExplodeTextNodes"); bool bExplodeTextNodes = tmpVar; tmpVar = (OdRxVariantValue)pImport->properties()->getAt("DontImportInvisibleElements"); bool bDontImportInvisible = tmpVar; tmpVar = (OdRxVariantValue)pImport->properties()->getAt("ImportViewIndex"); OdInt8 iImportViewIndex = tmpVar->getInt8(); if( pHostAppServices ) { OdString strXRefName = pHostAppServices->findFile(strNewFileName); if( !strXRefName.isEmpty() ) { bXRefPresent = true; strNewFileName = strXRefName; } } OdDgnImportLineWeightsMapPtr pLWMap = pImport->properties()->getAt("LineWeightsMap"); OdDgnImportRscFontExchangeMapPtr pRscFontMap = pImport->properties()->getAt("RscFontExchangeMap"); bool bSkipXRef = false; if( !bXRefPresent ) { if( pBaseImporter == NULL ) pBaseImporter = createDgnImporter(); OdDgnImportPtr importer = pBaseImporter->clone(); if( !importer.isNull() ) { importer->properties()->putAt(L"Services", pHostAppServices); importer->properties()->putAt(L"DgnPath", OdRxVariantValue(pDb->getFilename())); importer->properties()->putAt(L"XRefImportMode", OdRxVariantValue(OdUInt8(uXRefImportMode))); importer->properties()->putAt(L"ExplodeTextNodes", OdRxVariantValue(bExplodeTextNodes)); importer->properties()->putAt(L"ImportViewIndex", OdRxVariantValue(iImportViewIndex)); importer->properties()->putAt(L"DontImportInvisibleElements", OdRxVariantValue(bDontImportInvisible)); importer->properties()->putAt(L"3dEllipseImportMode", OdRxVariantValue(OdDgnImportContext::getEllipse3dImportMode())); importer->properties()->putAt(L"2dEllipseImportMode", OdRxVariantValue(OdDgnImportContext::getEllipse2dImportMode())); importer->properties()->putAt(L"3dShapeImportMode", OdRxVariantValue(OdDgnImportContext::getShape3dImportMode())); importer->properties()->putAt(L"2dShapeImportMode", OdRxVariantValue(OdDgnImportContext::getShape2dImportMode())); importer->properties()->putAt(L"3dObjectImportMode", OdRxVariantValue(OdDgnImportContext::getObject3dImportMode())); importer->properties()->putAt(L"3dClosedBSplineCurveImportMode", OdRxVariantValue(OdDgnImportContext::getClosedBSplineCurve3dImportMode())); importer->properties()->putAt(L"2dClosedBSplineCurveImportMode", OdRxVariantValue(OdDgnImportContext::getClosedBSplineCurve2dImportMode())); importer->properties()->putAt(L"ConvertDgnColorIndicesToTrueColors", OdRxVariantValue(OdDgnImportContext::getConvertColorIndexToTrueColorFlag())); importer->properties()->putAt(L"ConvertEmptyDataFieldsToSpaces", OdRxVariantValue(OdDgnImportContext::getConvertEmptyDataFieldsToSpacesFlag())); importer->properties()->putAt(L"ImportDgTextsAsDbMTexts", OdRxVariantValue(OdDgnImportContext::isImportDgTextAsDbMText())); importer->properties()->putAt(L"CropXRefExtraClipByExtents", OdRxVariantValue(OdDgnImportContext::getCropXRefExtraClipByExtentsFlag())); importer->properties()->putAt(L"ShowNewXRefLevels", OdRxVariantValue(OdDgnImportContext::getShowNewXRefLevelsFlag())); importer->properties()->putAt(L"SupportPriorityFor2dElements", OdRxVariantValue(OdDgnImportContext::getSupportPriorityFor2dElementsFlag())); importer->properties()->putAt(L"KeepComplexStringInvisibleItems", OdRxVariantValue(OdDgnImportContext::getKeepComplexStringInvisibleItemsFlag())); OdDgnImportLineWeightsMapPtr pLineWeightsMap = importer->properties()->getAt(L"LineWeightsMap"); pLineWeightsMap->copyLineWeightsMap(pLWMap); OdDgnImportRscFontExchangeMapPtr pNewRscFontMap = importer->properties()->getAt(L"RscFontExchangeMap"); pNewRscFontMap->copyRscFontExchangeMap(pRscFontMap); OdDgElementId idActiveXRef = OdDgnImportContext::getActiveXRefId(); OdDgnImportContext::setActiveXRefId(pXRef->elementId()); OdDgnImportContext::setInternalImportFlag(true); OdDgnImport::ImportResult res = importer->import(); OdDgnImportContext::setInternalImportFlag(false); OdDgnImportContext::setActiveXRefId(idActiveXRef); pLineWeightsMap = 0; OdDbDatabasePtr pXRefDb; if (res == OdDgnImport::success) { pXRefDb = importer->properties()->getAt(L"Database"); } if (!pXRefDb.isNull()) { pXRefDb->writeFile(strNewFileName, OdDb::kDwg, OdDb::kDHL_CURRENT); } else { bSkipXRef = true; } } } pLWMap = 0; OdDbObjectId idBlockDefTable = owner->database()->getBlockTableId(); if( !idBlockDefTable.isNull() && !bSkipXRef ) { OdDbBlockTablePtr pBlockDefTable = idBlockDefTable.openObject(OdDb::kForWrite); OdDbDatabase* pDwgDb = owner->database(); OdDbBlockTableRecordPtr pXRefDef; OdDbSymbolTableIteratorPtr pBlockDefIter = pBlockDefTable->newIterator(); for(; !pBlockDefIter->done(); pBlockDefIter->step() ) { OdDbBlockTableRecordPtr pBlockDef = pBlockDefIter->getRecord(OdDb::kForRead); if( !pBlockDef.isNull() && pBlockDef->isFromExternalReference() && (pBlockDef->pathName() == strNewFileName) ) { pXRefDef = pBlockDef; break; } } if( pXRefDef.isNull() ) { OdString strXRefBlockNameBase = strNewFileName; OdUInt32 iPosition = strXRefBlockNameBase.find(L':'); OdUInt32 iPositionSlash = strXRefBlockNameBase.reverseFind(L'\\'); OdUInt32 iPositionBSlash = strXRefBlockNameBase.reverseFind(L'/'); if( iPosition != -1 ) { iPosition = strXRefBlockNameBase.reverseFind( L'\\' ); if( iPosition != -1 ) strXRefBlockNameBase.deleteChars( 0, iPosition + 1 ); else { iPosition = strXRefBlockNameBase.reverseFind( L'/' ); if( iPosition != -1 ) strXRefBlockNameBase.deleteChars( 0, iPosition + 1 ); } } else if( iPositionSlash != -1 ) strXRefBlockNameBase.deleteChars( 0, iPositionSlash + 1 ); else if( iPositionBSlash != -1 ) strXRefBlockNameBase.deleteChars( 0, iPositionBSlash + 1 ); if( strXRefBlockNameBase.getLength() > 4 && (strXRefBlockNameBase[strXRefBlockNameBase.getLength() - 4] == L'.') ) { strXRefBlockNameBase = strXRefBlockNameBase.left( strXRefBlockNameBase.getLength() - 4 ); } OdString strXRefBlockName = strXRefBlockNameBase; OdUInt32 uCount = 1; while( !pBlockDefTable->getAt( strXRefBlockName ).isNull() ) { strXRefBlockName.format(L"_%d", uCount ); strXRefBlockName = strXRefBlockNameBase + strXRefBlockName; } if( OdDbSymUtil::repairSymbolName(repairedName, strXRefBlockName, pDwgDb ) == eOk && !repairedName.isEmpty() ) strXRefBlockName = repairedName; pXRefDef = OdDbXRefManExt::addNewXRefDefBlock(pDwgDb, strNewFileName, strXRefBlockName, false); } idBlockDefinition = pXRefDef->objectId(); } } } else { // Prepare level table and copy x-ref blocks if( pImport ) { OdDgDatabase* pDgnDb = pModel->database(); OdDbDatabase* pDwgDb = owner->database(); // Prepare importer and context to XRef import pImport->pushIdMap(); OdDgnImportContext::prepareToImport(pImport, true); if( pXRef->database() != pModel->database() ) { bool bUseNativeLevels = true; if (!arrLevelDif.isEmpty()) bUseNativeLevels = false; if( !OdDgnImportContext::popResourcesByFilename(pDgnDb, pXRefLevelTable, bUseNativeLevels) ) { pImport->copyTextStyles(pDgnDb, pDwgDb); pImport->copyLineStyles(pDgnDb, pDwgDb); pImport->copyLayers(pXRefLevelTable, pDwgDb, true, pDgnDb->getFilename()); pImport->copyBlocks(pDgnDb, pDwgDb); if( bUseNativeLevels ) OdDgnImportContext::pushResourcesByFileName(pDgnDb, pXRefLevelTable); } else if (!bUseNativeLevels) { pImport->copyLayers(pXRefLevelTable, pDwgDb, true, pDgnDb->getFilename()); } } else { synchronizeLevelTablesForSelfReference(pXRefLevelTable, pDwgDb); } } // Import model to block definition OdDbBlockTableRecordPtr pBlockDef = OdDbBlockTableRecord::createObject(); pBlockDef->setName( strBlockDefName ); pBlockDefTable->add( pBlockDef ); if( strGroupName.isEmpty() ) { DgnImporter::copySpaceBlock( pModel, pBlockDef, true, uImportViewNumber, false, true); } else { DgnImporter::copyNamedGroup( pModel, strGroupName, pBlockDef, uImportViewNumber); } if( pImport ) { // Update dimension association and restore importer and context. OdRxVariantValue tmpVar = (OdRxVariantValue)pImport->properties()->getAt("BreakDimensionAssociation"); if( !tmpVar->getBool() ) { pImport->setDimensionAssociation( pModel->database(), owner->database()); } else { OdDgnImportContext::clearDimAssocDescriptors(); OdDgnImportContext::clearBlockForSharedCellOverrideMap(); } OdDgnImportContext::restoreAfterImport(); pImport->popIdMap(); } idBlockDefinition = pBlockDef->objectId(); } // Restore data OdDgnImportContext::popXRef(); if( bUpdateGlobalLineScaleFlag ) { OdDgnImportContext::popGlobalLineScale(); } if( bRestorePalette ) { OdDgnImportContext::popPalette(); } OdDgnImportContext::addDwgModelBlockId(strFilename, pModel->elementId(), uLevelTableDiff, strLevelMaskExt, dLineStyleScale, idBlockDefinition); } } if (bUseLevelOverrides) { OdDgnImportContext::popLevelTableOverride(); OdDgnImportContext::setUseLevelOverrideFlag(bUseLevelOverrides); OdDgnImportContext::setOverridedLevelTable(idOldLevelOverride); } OdDgnImportContext::popViewFlags(); if( uXRefImportMode == 2 && OdDgnImportContext::isLevelMask() ) { // Restore Level Mask OdDgnImportContext::popLevelMask(); } if( !idBlockDefinition.isNull() ) { try { if (pXRef->getViewportFlag()) { matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin()).asVector() * pModel->getMeasuresConversion(OdDgModel::kWuUnitOfResolution, pModel->getWorkingUnit())); } else { matTransform = OdGeMatrix3d::translation(-(pXRef->getReferenceOrigin() + pModel->getInsertionBase().asVector()).asVector() * pModel->getMeasuresConversion(OdDgModel::kWuUnitOfResolution, pModel->getWorkingUnit())); } matTransform = OdGeMatrix3d::scaling( pXRef->getEntireScale() ) * matTransform; matTransform = pXRef->getTransformation() * matTransform; matTransform = OdGeMatrix3d::translation( pXRef->getMasterOrigin().asVector() ) * matTransform; pBlockReference = OdDbBlockReference::createObject(); pBlockReference->setBlockTableRecord( idBlockDefinition ); owner->appendOdDbEntity( pBlockReference ); } catch(...) { if( bAllowToEraseBlockDef ) idBlockDefinition.openObject(OdDb::kForWrite)->erase(true); } } } //--------------------------------------------------------------------------------------------------- bool OdDgReferenceAttachmentImportPE::allowImportElement(OdDgElement* e) { OdDgReferenceAttachmentHeader* pXRef = (OdDgReferenceAttachmentHeader*)(e); bool bRet = true; if( !OdDgnImportContext::isImportInvisible() && OdDgnImportContext::isLevelMask() ) { OdUInt32 uLevelId = pXRef->getLevelEntryId(); if( (uLevelId != 0) && !pXRef->getViewportFlag() ) { OdDgElementId levelId = OdDgnImportContext::getLevelOverride(pXRef->getLevelId()); levelId.convertToRedirectedId(); OdDgLevelTableRecordPtr pLevel = levelId.openObject(OdDg::kForRead); if( !pLevel.isNull() ) { if( !pLevel->getIsDisplayedFlag() || pLevel->getIsFrozenFlag() ) { bRet = false; } else { bRet = OdDgnImportContext::checkLevelMask( pLevel->getEntryId() ); } } } } return bRet; } //--------------------------------------------------------------------------------------------------- bool isExtentsIntoClipBoundary(const OdGePoint2dArray& extentsPts, const OdGePoint2dArray& arrClipBoundary) { OdGeExtents2d extBase; OdGeExtents2d extClipBoundary; extBase.addPoints(extentsPts); extClipBoundary.addPoints(arrClipBoundary); if (!extClipBoundary.contains(extBase)) return false; bool bRet = true; OdGePoint2d ptIsect; for( OdUInt32 i = 0; i < extentsPts.size() - 1; i++ ) { OdGeLineSeg2d segExt(extentsPts[i], extentsPts[i + 1]); for( OdUInt32 j = 0; j < arrClipBoundary.size() - 1; j++ ) { OdGeLineSeg2d segBoundary(arrClipBoundary[j], arrClipBoundary[j + 1]); if( segExt.intersectWith(segBoundary, ptIsect) ) { bRet = false; break; } } if (!bRet) break; } if( bRet ) { bRet = false; OdGeLineSeg2d segCheck(extBase.center(), arrClipBoundary[0]); for (OdUInt32 j = 0; j < extentsPts.size() - 1; j++) { OdGeLineSeg2d segExt(extentsPts[j], extentsPts[j + 1]); if (segExt.intersectWith(segCheck, ptIsect)) { bRet = true; break; } } } return bRet; } //--------------------------------------------------------------------------------------------------- class OdDgnImportXRefBlockExtentsCalculator : public OdGiExtCalc { public: OdDgnImportXRefBlockExtentsCalculator(); virtual ~OdDgnImportXRefBlockExtentsCalculator() {}; OdGiRegenType regenType() const; void draw(const OdGiDrawable* pDrawable); private: OdGiRegenType m_uCurType; }; //--------------------------------------------------------------------------------------------------- OdDgnImportXRefBlockExtentsCalculator::OdDgnImportXRefBlockExtentsCalculator() { m_uCurType = kOdGiForExtents; } //--------------------------------------------------------------------------------------------------- OdGiRegenType OdDgnImportXRefBlockExtentsCalculator::regenType() const { return m_uCurType; } //--------------------------------------------------------------------------------------------------- void OdDgnImportXRefBlockExtentsCalculator::draw(const OdGiDrawable* pDrawable) { if (pDrawable && pDrawable->isKindOf(OdDbText::desc())) { OdDbTextPtr pDbText = pDrawable; OdString strText = pDbText->textString(); if((strText.find(L"%%o") != -1) || (strText.find(L"%%u") != -1) || (strText.find(L"%%O") != -1) || (strText.find(L"%%U") != -1)) m_uCurType = kOdGiStandardDisplay; } else if (pDrawable && pDrawable->isKindOf(OdDbMText::desc())) { OdDbMTextPtr pDbText = pDrawable; OdString strText = pDbText->contents(); if ((strText.find(L"\\O") != -1) || (strText.find(L"||L") != -1) || (strText.find(L"\\o") != -1) || (strText.find(L"||l") != -1)) m_uCurType = kOdGiStandardDisplay; } OdGiExtCalc::draw(pDrawable); m_uCurType = kOdGiForExtents; } //--------------------------------------------------------------------------------------------------- OdGeExtents3d getDwgBlockExtents(OdDbBlockReference* pBlockRef) { OdGeExtents3d extRet; OdStaticRxObject giContext; giContext.setDatabase(pBlockRef->database(), false); OdStaticRxObject drawObject; drawObject.setContext(&giContext); drawObject.draw(pBlockRef); drawObject.getExtents(extRet); if( extRet.isValidExtents() ) { OdGeVector3d vrOffset = extRet.diagonal() / 1000.0; extRet.addPoint(extRet.minPoint() - vrOffset); extRet.addPoint(extRet.maxPoint() + vrOffset); } return extRet; } //--------------------------------------------------------------------------------------------------- bool hideByReferenceOverride(const OdDgReferenceAttachmentHeader* pXRef, OdDgDatabase* pDgnDb) { bool bRet = false; OdDgElementId idBaseXRef = OdDgnImportContext::getXRefId(0); if (idBaseXRef.isNull()) return bRet; OdArray arrXRefPath; for (OdUInt32 k = 1; k < OdDgnImportContext::getXRefNestedDepth(); k++) { OdDgElementId idPathXRef = OdDgnImportContext::getXRefId(k); if (!idPathXRef.isNull()) { arrXRefPath.push_back((OdUInt64)(idPathXRef.getHandle())); } else { arrXRefPath.push_back((OdUInt64)(0)); } } arrXRefPath.push_back((OdUInt64)(pXRef->elementId().getHandle())); OdUInt32 uPathSize = arrXRefPath.size(); for (OdUInt32 i = 0; i < uPathSize; i++) { OdDgReferenceAttachmentHeaderPtr pBaseXRef = idBaseXRef.openObject(OdDg::kForRead); OdDgElementIteratorPtr pXRefIter = pBaseXRef->createIterator(); for (; !pXRefIter->done(); pXRefIter->step()) { OdDgElementPtr pChild = pXRefIter->item().openObject(OdDg::kForRead); if (!pChild.isNull() && pChild->isKindOf(OdDgReferenceOverride::desc())) { OdDgReferenceOverridePtr pXRefOverride = pChild; OdUInt64Array arrPath; pXRefOverride->getPathOfXRef(arrPath); if (arrPath.size() == arrXRefPath.size()) { bool bCorrectOverride = true; for (OdUInt32 n = 0; n < arrXRefPath.size(); n++) { if (arrPath[n] != arrXRefPath[n]) { bCorrectOverride = false; break; } } if (bCorrectOverride) { if( pXRefOverride->getDisplayOverrideFlag() ) bRet = !pXRefOverride->getDisplayFlag(); break; } } } } } return bRet; } //--------------------------------------------------------------------------------------------------- void OdDgReferenceAttachmentImportPE::subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner ) { OdDgReferenceAttachmentHeader* pXRef = (OdDgReferenceAttachmentHeader*)(e); OdUInt8 uXRefMode = 2; DgnImporter* pImport = OdDgnImportContext::getDgnImporter(); if( pImport ) { OdRxVariantValue tmpVar = (OdRxVariantValue)pImport->properties()->getAt("XRefImportMode"); uXRefMode = tmpVar->getUInt8(); } if( !pXRef || !owner ) { return; } if( pXRef->getDoNotDisplayAsNestedFlag() && (OdDgnImportContext::getXRefNestedDepth() > 0) ) { return; } if( pXRef->isSelfReference() && (OdDgnImportContext::getXRefNestedDepth() > 0) && OdDgnImportContext::getXRefId(OdDgnImportContext::getXRefNestedDepth()-1) == pXRef->elementId() ) { return; } bool bLoaded = pXRef->isLoadedNow(); OdDgModelPtr pModel = pXRef->getReferencedModel(); OdDbBlockReferencePtr pBlockReference; OdGeMatrix3d matTransform = OdGeMatrix3d::kIdentity; bool bVisible = pXRef->getDisplayFlag(); if( !pModel.isNull() ) // dgn model { if( !bLoaded ) bLoaded = pXRef->database() == pModel->database(); OdString strFilename = pModel->database()->getFilename(); // Check visibility of x-ref if( OdDgnImportContext::isXRefInStack(strFilename, pModel->elementId()) ) { return; } if( !OdDgnImportContext::checkNestedDepth() ) { if (!bLoaded && !OdDgnImportContext::addXRefDatabaseIdToUnload(pXRef->elementId(), strFilename) ) { pXRef->unload(false, false); } return; } if( (OdDgnImportContext::getXRefNestedDepth() > 0) && hideByReferenceOverride(pXRef, e->database()) ) { if (!bLoaded && !OdDgnImportContext::addXRefDatabaseIdToUnload(pXRef->elementId(), strFilename)) pXRef->unload(false, false); return; } if( pXRef->getUnloadFlag() ) pXRef->reload(false); bLoaded = OdDgnImportContext::addXRefDatabaseIdToUnload(pXRef->elementId(), strFilename); importDgnXRef( owner, pXRef, matTransform, pBlockReference, uXRefMode, pImport); if( !bLoaded ) pXRef->unload(false, false); } else // may be dwg model { importDwgXRef( owner, pXRef, matTransform, pBlockReference ); } if( !pBlockReference.isNull() ) { // layer if( pXRef->getLevelEntryId() == 0 ) { pBlockReference->setLayer(owner->database()->getLayerZeroId()); } else { OdDbObjectId layerId = OdDgnImportContext::getObjectId(OdDgnImportContext::getLevelOverride(pXRef->getLevelId())); if( layerId.isNull() || OdDbLayerTableRecord::cast(layerId.openObject()).isNull() ) // is used in audit checking also { layerId = owner->database()->getLayerZeroId(); } pBlockReference->setLayer(layerId); } // transform pBlockReference->setBlockTransform( matTransform ); // visibility pBlockReference->setVisibility( bVisible ? OdDb::kVisible : OdDb::kInvisible ); // transparency pBlockReference->setTransparency( pXRef->getTransparency() ); // clip OdGiClipBoundary clipBoundary; bool useClipBoundary = false; bool bInverceClip = false; OdDgReferenceAttachClipBoundaryPEPtr pBoundaryPE = OdDgReferenceAttachClipBoundaryPEPtr(OdRxObjectPtr(pXRef)); if( !pBoundaryPE.isNull() ) { useClipBoundary = pBoundaryPE->extractBoundary( pXRef, clipBoundary, 1e-6, false, NULL, bInverceClip, true, matTransform, true ); } if (useClipBoundary && (clipBoundary.m_Points.size() == 5)) { // Calculate block extents clipping points OdGeMatrix3d toClipSpace = matTransform * clipBoundary.m_xInverseBlockRefXForm * clipBoundary.m_xToClipSpace.inverse(); toClipSpace.invert(); OdGeExtents3d extBlock = getDwgBlockExtents(pBlockReference); if( extBlock.isValidExtents() ) { extBlock.transformBy(toClipSpace); OdGePoint2dArray arrBlockExtBoundary; OdGePoint2d pt0 = extBlock.minPoint().convert2d(); OdGePoint2d pt2 = extBlock.maxPoint().convert2d(); OdGePoint2d pt1 = pt0; pt1.x = pt2.x; OdGePoint2d pt3 = pt0; pt3.y = pt2.y; arrBlockExtBoundary.push_back(pt0); arrBlockExtBoundary.push_back(pt1); arrBlockExtBoundary.push_back(pt2); arrBlockExtBoundary.push_back(pt3); arrBlockExtBoundary.push_back(pt0); // Clip boundary more then extents if( OdDgnImportContext::getCropXRefExtraClipByExtentsFlag() && isExtentsIntoClipBoundary(arrBlockExtBoundary, clipBoundary.m_Points)) clipBoundary.m_Points = arrBlockExtBoundary; } } if( useClipBoundary ) { if( pBlockReference->extensionDictionary().isNull() ) { pBlockReference->createExtensionDictionary(); } OdDbDictionaryPtr pDict = OdDbDictionary::cast(pBlockReference->extensionDictionary().openObject(OdDb::kForWrite)); if( !pDict.isNull() ) { OdDbDictionaryPtr pFDict = OdDbDictionary::cast(pDict->getAt(OD_T("ACAD_FILTER"), OdDb::kForWrite)); if( pFDict.isNull() ) { pFDict = OdDbDictionary::createObject(); pDict->setAt( OD_T("ACAD_FILTER"), pFDict ); } if( !pFDict.isNull() ) { OdDbSpatialFilterPtr pSp = OdDbSpatialFilter::cast(pFDict->getAt(OD_T("SPATIAL"), OdDb::kForWrite)); if( pSp.isNull() ) { pSp = OdDbSpatialFilter::createObject(); pFDict->setAt( OD_T("SPATIAL"), pSp ); } if( !pSp.isNull() ) { double dFrontClip = ODDB_INFINITE_XCLIP_DEPTH; double dBackClip = ODDB_INFINITE_XCLIP_DEPTH; if( clipBoundary.m_bClippingFront ) { dFrontClip = clipBoundary.m_dFrontClipZ; } if( clipBoundary.m_bClippingBack ) { dBackClip = clipBoundary.m_dBackClipZ; } pSp->setDefinition( clipBoundary ); if( bInverceClip) pSp->setFilterInverted(bInverceClip); } } } } } } //--------------------------------------------------------------------------------------------------- }