/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #ifndef _DGN_IMPORT_SHAPE_INCLUDED_ #define _DGN_IMPORT_SHAPE_INCLUDED_ #include "DgnImportPE.h" #include "DgnImportCommon.h" #include "DgnImportPatterns.h" #include #include "DbRegion.h" #include "DgShape.h" #include #include #include #include #include #include #include "Gi/GiUtils.h" namespace TD_DGN_IMPORT { //--------------------------------------------------------------------------------------------------- template OdGePoint3d getShapeVertex(T*, OdUInt32 uIndex){return OdGePoint3d::kOrigin;} //--------------------------------------------------------------------------------------------------- template <> OdGePoint3d getShapeVertex(OdDgShape2d* shape2d, OdUInt32 uIndex) { OdGePoint2d ptVertex = shape2d->getVertexAt(uIndex); return OdGePoint3d( ptVertex.x, ptVertex.y, 0 ); } //--------------------------------------------------------------------------------------------------- template <> OdGePoint3d getShapeVertex(OdDgShape3d* shape3d, OdUInt32 uIndex) { return shape3d->getVertexAt(uIndex); } //--------------------------------------------------------------------------------------------------- template struct OdDgShapeImportPE : OdDgnImportPE { void subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner) ODRX_OVERRIDE { T* pShape = static_cast(e); OdUInt8 uShapeImportMode = OdDgnImportContext::getShape2dImportMode(); if( pShape->get3dFormatFlag() ) { uShapeImportMode = OdDgnImportContext::getShape3dImportMode(); } bool bImportAsPolylineMode = OdDgnImportContext::getImportCurvesOnlyFlag(); if( (uShapeImportMode == 2) && !bImportAsPolylineMode ) { OdDgnImportPE::subImportElement( e, owner ); return; } OdGePoint3dArray arrVertices; for( OdUInt32 j = 0; j < pShape->getVerticesCount(); j++ ) { arrVertices.push_back( getShapeVertex(pShape,j) ); } if( arrVertices[0].isEqualTo(arrVertices[arrVertices.size()-1]) ) { arrVertices.removeLast(); } if( arrVertices.size() < 3 ) { return; } bool bUseFillColor = pShape->getFillType() == OdDg::kFillColor; OdUInt32 uFillColorIndex = 0; OdDgViewPtr pActiveView = OdDgnImportContext::getActiveView(); if (bUseFillColor) uFillColorIndex = getDgnElementColorIndex(pShape->getFillColorIndex(),pShape->getLevelId()); if( !OdDgnImportContext::getActualViewFlags().getShowFillsFlag() ) { bUseFillColor = false; } OdDbObjectId idCreatedObject; bool bImportAsPolyline = OdDgnImportContext::getImportCurvesOnlyFlag(); bool bErasePolyline = false; if( (uShapeImportMode == 0) || bImportAsPolylineMode ) // create polyline { bImportAsPolyline = true; } if( bUseFillColor || bImportAsPolyline ) // Create polyline and solid hatch { OdDbPolylinePtr pPolyline; OdDb3dPolylinePtr p3dPolyline; OdDbHatchPtr pHatch; OdDbWipeoutPtr pWipeout; if( bUseFillColor && (uFillColorIndex == 255) ) { arrVertices.push_back(arrVertices.first()); pWipeout = OdDbWipeout::createObject(); owner->appendOdDbEntity(pWipeout); pWipeout->setBoundary(arrVertices); idCreatedObject = pWipeout->objectId(); } else if( createVertexPolyline( arrVertices, pPolyline, pShape->getThickness() ) ) { if (!pPolyline.isNull()) pPolyline->setDatabaseDefaults(owner->database()); if( bUseFillColor ) { pHatch = OdDbHatch::createObject(); owner->appendOdDbEntity(pHatch); owner->appendOdDbEntity(pPolyline); OdDbObjectIdArray arrHatchItems; arrHatchItems.push_back(pPolyline->id()); pHatch->appendLoop(OdDbHatch::kExternal, arrHatchItems); pHatch->setPattern(OdDbHatch::kPreDefined, L"SOLID"); pHatch->setAssociative(true); OdDbObjectIdArray arrIds; arrIds.push_back(pPolyline->objectId()); pHatch->setAssocObjIdsAt(0, arrIds); idCreatedObject = pPolyline->objectId(); } else { owner->appendOdDbEntity( pPolyline ); idCreatedObject = pPolyline->objectId(); } } else if (bImportAsPolyline) { p3dPolyline = OdDb3dPolyline::createObject(); p3dPolyline->setDatabaseDefaults(owner->database()); owner->appendOdDbEntity(p3dPolyline); if (arrVertices.first().isEqualTo(arrVertices.last())) arrVertices.removeLast(); for (OdUInt32 k = 0; k < arrVertices.size(); k++) { OdDb3dPolylineVertexPtr pNewVertex = OdDb3dPolylineVertex::createObject(); pNewVertex->setVertexType(OdDb::k3dSimpleVertex); pNewVertex->setPosition(arrVertices[k]); p3dPolyline->appendVertex(pNewVertex); } p3dPolyline->makeClosed(); } if( !pPolyline.isNull() ) { OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back( pPolyline->objectId() ); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath( pShape->elementId(), dwgPath ); copyEntityProperties( pShape, pPolyline); } else if ( !p3dPolyline.isNull() ) { OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back(p3dPolyline->objectId()); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath(pShape->elementId(), dwgPath); copyEntityProperties(pShape, p3dPolyline); } if( !pHatch.isNull() ) { copyEntityProperties( pShape, pHatch); setDwgColorByDgnIndex( pShape->database(), pHatch, uFillColorIndex ); } else if (!pWipeout.isNull()) { copyEntityProperties(pShape, pWipeout); } if( pPolyline.isNull() && p3dPolyline.isNull() && pHatch.isNull() && pWipeout.isNull() ) { OdDgnImportPE::subImportElement( pShape, owner ); return; } } else // Create Face or Region { if( arrVertices.size() < 5 && ( isContinuousLineStyle(getLineStyleEntryId(pShape), pShape) ) ) // create face { bool bCreateFace = true; if( arrVertices[1].isEqualTo(arrVertices[2]) ) { if( (arrVertices.size() == 3) || arrVertices[0].isEqualTo(arrVertices[3]) ) { OdDbLinePtr pLine = OdDbLine::createObject(); pLine->setStartPoint(arrVertices[0]); pLine->setEndPoint(arrVertices[1]); owner->appendOdDbEntity(pLine); copyEntityProperties(pShape, pLine); idCreatedObject = pLine->objectId(); OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back(idCreatedObject); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath(pShape->elementId(), dwgPath); bCreateFace = false; } } if( bCreateFace ) { OdDbFacePtr pFace = OdDbFace::createObject(); pFace->setVertexAt(0, arrVertices[0]); pFace->setVertexAt(1, arrVertices[1]); pFace->setVertexAt(2, arrVertices[2]); if (arrVertices.size() > 3) { pFace->setVertexAt(3, arrVertices[3]); } else { pFace->setVertexAt(3, arrVertices[2]); } owner->appendOdDbEntity(pFace); copyEntityProperties(pShape, pFace); idCreatedObject = pFace->objectId(); OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back(idCreatedObject); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath(pShape->elementId(), dwgPath); } } else { OdGeVector3d vrShapeNormal = OdGeVector3d::kIdentity; getHatchPatternNormal(pShape, vrShapeNormal); OdDbPolylinePtr pPolyline; if( createVertexPolyline( arrVertices, pPolyline, pShape->getThickness(), vrShapeNormal) ) { if (!pPolyline.isNull()) { OdDbPolyline* pLine = NULL; if (pPolyline->isKindOf(OdDbPolyline::desc())) pLine = (OdDbPolyline*)(pPolyline.get()); if( pLine && !pLine->hasBulges() && (pLine->numVerts() >= MAX_REGION_EDGES) ) { OdGePoint3dArray arrPts; OdInt32Array arrFaces; OdGeMatrix3d matrix; matrix.setToPlaneToWorld(pLine->normal()); arrPts.resize(pLine->numVerts()); arrFaces.resize(pLine->numVerts() + 2); arrFaces[0] = pLine->numVerts() + 1; double dElevation = pLine->elevation(); for (OdUInt32 i = 0; i < pLine->numVerts(); i++) { OdGePoint2d ptVertex2d; pLine->getPointAt(i, ptVertex2d); OdGePoint3d ptVertex3d(ptVertex2d.x, ptVertex2d.y, dElevation); ptVertex3d.transformBy(matrix); arrPts[i] = ptVertex3d; arrFaces[i + 1] = i; } arrFaces[pLine->numVerts() + 1] = 0; OdDbSubDMeshPtr pSubDMesh = OdDbSubDMesh::createObject(); pSubDMesh->setDatabaseDefaults(owner->database()); pSubDMesh->setSubDMesh(arrPts, arrFaces, 0); owner->appendOdDbEntity(pSubDMesh); copyEntityProperties(pShape, pSubDMesh); pPolyline->erase(true); } else { OdRxObjectPtrArray arrPolylines; arrPolylines.push_back((OdRxObjectPtr)(pPolyline)); OdRxObjectPtrArray arrRegions; if (OdDbRegion::createFromCurves(arrPolylines, arrRegions) == eOk) { OdDbRegionPtr pRegion = arrRegions[0]; owner->appendOdDbEntity(pRegion); copyEntityProperties(pShape, pRegion); idCreatedObject = pRegion->objectId(); OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back(idCreatedObject); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath(pShape->elementId(), dwgPath); } else { OdGeVector3d positiveAreaDir, negativeAreaDir; arrVertices.push_back(arrVertices.first()); odgiSquareValues(arrVertices.size(), arrVertices.asArrayPtr(), positiveAreaDir, negativeAreaDir); positiveAreaDir += negativeAreaDir; if( positiveAreaDir.isZeroLength() || !vrShapeNormal.isZeroLength() ) { owner->appendOdDbEntity(pPolyline); copyEntityProperties(pShape, pPolyline); idCreatedObject = pPolyline->objectId(); OdDgnImportPathToDwgObject dwgPath; dwgPath.m_idPath.objectIds().push_back(idCreatedObject); dwgPath.m_bExists = true; OdDgnImportContext::addObjectPath(pShape->elementId(), dwgPath); } else { OdDgnImportPE::subImportElement(pShape, owner); } return; } } } } else { OdDgnImportPE::subImportElement( pShape, owner ); return; } } } OdDbObjectIdArray arrIds; if( !idCreatedObject.isNull() ) { arrIds.push_back( idCreatedObject ); } if( !bImportAsPolylineMode ) { importPatterns( pShape, arrVertices, arrIds, true, owner, true, idCreatedObject ); } } }; //--------------------------------------------------------------------------------------------------- } #endif // _DGN_IMPORT_SHAPE_INCLUDED_