|
先封装一个函数
.h
//xform 插入点;dScale 比例;pBlockId 图块ID
//nBasePos 插入的基点,0:以DWG图形最左下点为基点,1:右下,2:右上,3:左上,4:原图(0,0)点
bool InsertDwg(const AcGePoint3d & xform, AcDbDatabase* pSrc, LPCTSTR lpLayer/*=NULL*/, double dScale=1.0/*比例*/, int nBasePos=0, bool bIsDWGMoveToOrignFirst=true, AcDbObjectId* pBlockId=NULL, double dAngle = 0.0);
.cpp
bool InsertDwg(const AcGePoint3d & xform, AcDbDatabase* pSrc, LPCTSTR lpLayer/*=NULL*/, double dScale/*=1.0比例*/, int nBasePos/*=0*/, bool bIsDWGMoveToOrignFirst/*=true*/, AcDbObjectId* pBlockId/*=NULL*/, double dAngle/* = 0.0*/)
{
AcAxDocLock docLock(m_pDb);
pSrc->updateExt();
// 得到图形左下和右上角点
AcGePoint3d p1(pSrc->extmin());
AcGePoint3d p2(pSrc->extmax());
// 取得DWG中所有元素
AcDbObjectId blockId;
HHVerifyErr2(m_pDb->insert(blockId, GenGUID(), pSrc),return false;);
AcDbBlockReference* pBlockReference = new AcDbBlockReference ( AcGePoint3d(0.0,0.0,0.0), blockId);
AddEntity(pBlockReference, pBlockId)
{
delete pBlockReference;
return false;
}
// 设图层
if ( lpLayer != NULL )
{
AcDbObjectId mLayerId;
if ( !GetLayerId(lpLayer, mLayerId) )
{
AddLayer(lpLayer, &mLayerId);
}
pBlockReference->setLayer(mLayerId);
}
// 设比例
if ( fabs(dScale-1.0) > 1e-6 )
{
AcGeScale3d scale(dScale);
HHVerifyErr(pBlockReference->setScaleFactors(scale));
p1.scaleBy(dScale);
p2.scaleBy(dScale);
}
if ( !bIsDWGMoveToOrignFirst )
p1 = AcGePoint3d(0.0,0.0,0.0);
// 计算坐标
switch (nBasePos)
{
default:
case 0:// 左下
break;
case 1:// 右下
p1.x = p2.x;
break;
case 2:// 右上
p1 = p2;
break;
case 3:// 左上
p1.y = p2.y;
break;
case 4:// 元坐标
p1.x = 0.0;
p1.y = 0.0;
break;
case 5:
p1.x += (p2.x - p1.x) / 2.0;
p1.y += (p2.y - p1.y) / 2.0;
}
pBlockReference->transformBy(xform-p1);
AcGeMatrix3d matrix = matrix.rotation(dAngle,zAxis,xform);
pBlockReference->transformBy(matrix);
pBlockReference->close();
return true;
}
1.dxf格式的
CString strFilePath;//dxf文件路径
AcDbDatabase mDb(false, true);
Acad::ErrorStatus es = mDb.dxfIn(strFilePath);
if (es != Acad::eOk)
{
HHTalkBox(_T("读入dxf文件失败!"));
return;
}
LPCTSTR lpLayer;//插入图层
AcAxDocLock lock;
InsertDwg(ptReference, &mDb, lpLayer, 1, 0, false, &mId);
2.dwg格式的
AcAxDocLock lock;
// 分配
AcDbDatabase* pDb = new AcDbDatabase(Adesk::kFalse, true);
if(pDb==NULL)
return false;
if(!pDb->readDwgFile(lpDWG, _SH_DENYNO))
{
delete pDb;
return false;
}
LPCTSTR lpLayer;//插入图层
InsertDwg(xform, pDb, lpLayer, dScale, nBasePos, bIsDWGMoveToOrignFirst, pBlockId, dAngle);
delete pDb;
3.图片格式的(*.jpg;*.gif;*.bmp;*.png)
// 计算图片大小
Gdiplus::Bitmap img(strPrjPath);
double dWidth = img.GetWidth()/img.GetHorizontalResolution()*25.4;
double dHeight = img.GetHeight()/img.GetVerticalResolution()*25.4;
// 插入图片
AcAxDocLock lock;
CImageSupportModule ISM(m_pDb);
AcDbObjectId tempId;
if (pId == NULL)
pId = &tempId;
// attach image
Acad::ErrorStatus es = ISM.NewImageAttach(lpJpgPath,*pId); // returns Entity Id.
if (es != Acad::eOk)
{
assert(false);
acutPrintf(_T("Error: Attach example image failed.\n"));
return false;
}
AcDbObjectId oid = *pId;
AcDbObjectPointer<AcDbRasterImage> imgPtr(oid,kForWrite);
AcGeMatrix3d mtx;
mtx.setToTranslation(mPtLB.asVector());
AcDbExtents ext ;
imgPtr->getGeomExtents(ext);
AcGeVector3d origsize = ext.maxPoint() - ext.minPoint();
AcGeVector3d newSize = mPtRT - mPtLB;
double ratioX = newSize.x / origsize.x;
double ratioY = newSize.y / origsize.y;
double ratioResult = min(ratioX,ratioY);
AcGeMatrix3d scaleMtx = AcGeMatrix3d::scaling(ratioResult,mPtLB);
mtx.preMultBy(scaleMtx);
imgPtr->transformBy(mtx);
AcGePoint3dArray ptArr;
imgPtr->getStretchPoints(ptArr);
if (4==ptArr.length())
{
AcDbExtents extsPost;
imgPtr->getGeomExtents(extsPost);
AcGeVector3d vecOffset = mPtRT -extsPost.maxPoint();
AcDbIntArray ptIndex;
if (ratioX-ratioY>1e-6)
{
ptIndex.append(2);
ptIndex.append(3);
}
else
{
ptIndex.append(1);
ptIndex.append(2);
}
imgPtr->moveStretchPointsAt(ptIndex,vecOffset);
}
if ( vmRoat!=NULL )
imgPtr->transformBy(*vmRoat);
// 设置图层
AcDbObjectId acdIdLayer;
if ( !GetLayerId(lpLayer, acdIdLayer) )
{
HHVerify(AddLayer(lpLayer, &acdIdLayer));
}
imgPtr->setLayer(acdIdLayer);
class CImageSupportModule
{
public:
CImageSupportModule(AcDbDatabase* pDb);
virtual ~CImageSupportModule(void);
public:
// Attaches an new Image
virtual Acad::ErrorStatus NewImageAttach (const CString& strImgPath, AcDbObjectId & parEntityId);
// Manipulate Image
virtual Acad::ErrorStatus Manipulate (AcDbObjectId parEntityId);
virtual Acad::ErrorStatus SetPos (const AcDbObjectId& id, const AcGePoint3d& ptLB, const AcGePoint3d& ptRT);
// Create Objects
virtual Acad::ErrorStatus CreateAcDbRasterImage (AcDbObjectId & parEntityId, AcDbObjectId parObjectId);
// creates the entity
virtual Acad::ErrorStatus CreateAcDbRasterImageDef (AcDbObjectId & parObjectId, CString parImageName, CString parImagePath);
// creates the definition
virtual Acad::ErrorStatus CreateAcDbRasterImageDefReactor (AcDbObjectId & parReactorId, AcDbObjectId parObjectId, AcDbObjectId parEntityId);
// creates the reactor
// Utilities Method
virtual Acad::ErrorStatus AppendToPaperOrModelSpace (AcDbEntity* parEntity, Adesk::Boolean parbToPaperSpace);
// delete image attach
virtual Acad::ErrorStatus DeleteImageDef(const ACHAR* pImageName);
private:
CString m_strImagePath;
AcDbDatabase* m_pDb;
};
#include "StdAfx.h"
#include "ImageSupportModule.h"
#include "FilteredEntityCollector.h"
using namespace EntityFilter;
CImageSupportModule::CImageSupportModule(AcDbDatabase* pDb)
: m_pDb(pDb)
{
if (m_pDb == NULL)
{
m_pDb = acdbHostApplicationServices()->workingDatabase();
}
}
CImageSupportModule::~CImageSupportModule(void)
{
}
//
// description: Create image definition object.
// Create image entity.
// Create image reactor.
//
// parameter: parEntityId Returns the object Id of the RasterImage.
//
//
// problems: The image path has to be updated in the newImageAttach method.
// Or the image path has to be set in the preference project directory
// of Acad and set it to the current project.
//
Acad::ErrorStatus CImageSupportModule::NewImageAttach (const CString& strImgPath, AcDbObjectId& parEntityId)
{
CString ImageName;
int iIndex = strImgPath.ReverseFind('\\');
if (iIndex != -1)
{
ImageName = strImgPath.Right(strImgPath.GetLength()-iIndex-1);
ImageName = ImageName.Left(ImageName.GetLength()-4);
}
// Create image definition object.
AcDbObjectId ObjectId;
Acad::ErrorStatus es = CreateAcDbRasterImageDef(ObjectId, ImageName, strImgPath);
if (es != Acad::eOk) return es;
// Create image entity.
es = CreateAcDbRasterImage(parEntityId, ObjectId);
if (es != Acad::eOk) return es;
// Create image reactor.
AcDbObjectId ReactorId; // AcDbRasterImageDefReactor Id
es = CreateAcDbRasterImageDefReactor (ReactorId, ObjectId, parEntityId);
if (es != Acad::eOk) return es;
return es;
}
// description: Create a new image entity.
// Set Defintion id in Entity. ( link it to the specified image definition object)
// Appends the entity to model space.
// Set Entity ID to Attribute.
//
// parameter: parEntityId Returns object Id of the created RasterImage.
// parObjectId Object Id of the RasterImageDef.
//
//
Acad::ErrorStatus CImageSupportModule::CreateAcDbRasterImage (AcDbObjectId & parEntityId, AcDbObjectId parObjectId)
{
AcDbRasterImage* pAcDbRasterImage = new AcDbRasterImage;
if ( pAcDbRasterImage == NULL)
return Acad::eNullEntityPointer;
// Set Defintion id in Entity. ( link it to the specified image definition object)
Acad::ErrorStatus es = pAcDbRasterImage->setImageDefId(parObjectId);
if (es != Acad::eOk)
{
delete pAcDbRasterImage;
return es;
}
// Appends the entity to model space.
es = AppendToPaperOrModelSpace ((AcDbEntity*) pAcDbRasterImage, Adesk::kFalse);
if (es != Acad::eOk)
{
delete pAcDbRasterImage;
return es;
}
// Set Entity ID to Attribute.
parEntityId = pAcDbRasterImage->objectId();
pAcDbRasterImage->close();
return es;
}
// description: Create reactor.
// Set the entity to be its owner.
// Link it to the definition object.
// Set Reactor Id.
// Adds the database resident object to the reactor list of the object.
//
// parameter: parReactorId Returns object Id of the created RasterImageDefReactor.
// parObjectId Object Id of the RasterImageDef.
// parEntityId Object Id of the RasterImage.
//
Acad::ErrorStatus CImageSupportModule::CreateAcDbRasterImageDefReactor (AcDbObjectId & parReactorId,
AcDbObjectId parObjectId,
AcDbObjectId parEntityId)
{
// Disable image definition notification while changing the defintion reactor list.
AcDbRasterImageDefReactor::setEnable(Adesk::kFalse);
// open Definition
AcDbRasterImageDef* pAcDbRasterImageDef = NULL;
Acad::ErrorStatus es = acdbOpenObject((AcDbObject*&) pAcDbRasterImageDef, parObjectId, AcDb::kForWrite);
if (es != Acad::eOk) return es;
AcDbRasterImage* pAcDbRasterImage = NULL;
es = acdbOpenObject((AcDbObject*&) pAcDbRasterImage, parEntityId, AcDb::kForWrite);
if (es != Acad::eOk)
{
pAcDbRasterImageDef->close();
return es;
}
// Create reactor.
AcDbRasterImageDefReactor* pAcDbRasterImageDefReactor = new AcDbRasterImageDefReactor;
if (pAcDbRasterImageDefReactor == NULL)
{
pAcDbRasterImage->close();
pAcDbRasterImageDef->close();
return Acad::eNullObjectPointer;
}
// Set the entity to be its owner.
es = pAcDbRasterImageDefReactor->setOwnerId( parEntityId);
if (es != Acad::eOk)
{
pAcDbRasterImage->close();
pAcDbRasterImageDef->close();
delete pAcDbRasterImageDefReactor;
return es;
}
// Link it to the definition object.
es = m_pDb->addAcDbObject( parReactorId, pAcDbRasterImageDefReactor);
if (es != Acad::eOk)
{
pAcDbRasterImage->close();
pAcDbRasterImageDef->close();
delete pAcDbRasterImageDefReactor;
return es;
}
// Set Reactor Id.
pAcDbRasterImage->setReactorId( parReactorId);
// Adds the database resident object to the reactor list of the object.
pAcDbRasterImageDef->addPersistentReactor(parReactorId);
pAcDbRasterImageDefReactor->close();
pAcDbRasterImageDef->close();
pAcDbRasterImage->close();
// Re-enable image def notification.
AcDbRasterImageDefReactor::setEnable(Adesk::kTrue);
return es;
}
// ___ createAcDbRasterImageDef ________________________________________________________________________
//
// description: Create new image def object
// set source file name
// load image
// Get Dictionary Id.
// Check if image name already in use.
//
// parameter: parObjectId Returns object Id of the created RasterImageDef.
// parImageName Name of the image.
// parImagePath Path of the image.
//
// return value: ErrorStatus
// Returns Acad::eOk if successfull.
// Acad::eNullObjectPointer failed to initialize entity.
// Acad::eHandleInUse image name in use.
// And error states of this classes: AcDbDictionary, AcDbRasterImageDef,
// and the function acdbOpenObject.
//
// problems: .
Acad::ErrorStatus CImageSupportModule::CreateAcDbRasterImageDef (AcDbObjectId & parObjectId,
CString parImageName,
CString parImagePath)
{
Acad::ErrorStatus es = eOk;
// Get Dictionary Id.
AcDbObjectId DictionaryId = AcDbRasterImageDef::imageDictionary(m_pDb);
if (DictionaryId.isNull())
{
// Create dictionary
es = AcDbRasterImageDef::createImageDictionary(m_pDb, DictionaryId);
if (es!= Acad::eOk)
{
return es;
}
}
//es = acdbOpenObject((AcDbObject*&)pDictionary, DictionaryId, AcDb::kForRead);
AcDbObjectPointer<AcDbDictionary> dictionaryPtr(DictionaryId,kForRead);
if (dictionaryPtr.openStatus() != Acad::eOk)
{
return es;
}
if (dictionaryPtr->has(parImageName))
{
es = dictionaryPtr->getAt(parImageName,parObjectId);
return es;
}
//acutDelString(pTempNewName);
// Create new image def object
AcDbRasterImageDef* pAcDbRasterImageDef = new AcDbRasterImageDef();
if (pAcDbRasterImageDef == NULL)
return Acad::eNullObjectPointer;
// set source file name
es = pAcDbRasterImageDef->setSourceFileName(parImagePath);
if (es != Acad::eOk)
{
acutPrintf(_T("Error: Could not find the image file.\n"));
delete pAcDbRasterImageDef;
return es;
}
// load image
es = pAcDbRasterImageDef->load();
pAcDbRasterImageDef->setActiveFileName(parImagePath);
if (es != Acad::eOk)
{
acutPrintf(_T("Error: Could not open the image file.\n"));
delete pAcDbRasterImageDef;
return es;
}
dictionaryPtr->upgradeOpen();
// adds a new entry specified by newValue into the dictionary and returns Object Id.
es = dictionaryPtr->setAt(parImageName, pAcDbRasterImageDef, parObjectId);
pAcDbRasterImageDef->close();
return es;
}
Acad::ErrorStatus CImageSupportModule::AppendToPaperOrModelSpace (AcDbEntity* parEntity, Adesk::Boolean parbToPaperSpace)
{
// declaration
Acad::ErrorStatus ErrorStatus;
AcDbDatabase* pDataBase;
AcDbBlockTable* pBlockTable;
AcDbBlockTableRecord* pBlockTableRecord;
// get database
pDataBase = acdbHostApplicationServices()->workingDatabase();
// check
if (pDataBase == NULL)
// No database
return Acad::eNoDatabase;
// get block table
ErrorStatus = pDataBase->getSymbolTable(pBlockTable, AcDb::kForRead);
// check
if (ErrorStatus != Acad::eOk)
// Failed to get block table
return ErrorStatus;
// appends to ...
if (parbToPaperSpace)
// ... paper space
ErrorStatus = pBlockTable->getAt(ACDB_PAPER_SPACE, pBlockTableRecord, AcDb::kForWrite);
else
// ... model space by default
ErrorStatus = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
// check
if (ErrorStatus != Acad::eOk)
// Failed to get block table record
{
pBlockTable->close();
return ErrorStatus;
}
// append entity to block table record
ErrorStatus = pBlockTableRecord->appendAcDbEntity (parEntity);
pBlockTableRecord->close();
pBlockTable->close();
return ErrorStatus;
}
// ___ manipulate ______________________________________________________
//
// description: Set orientation.
// Set clip boundary to whole image.
// Set polygonal clip boundary.
//
// parameter: parEntityId Object Id of the RasterImage.
//
// return value: ErrorStatus
// Returns Acad::eOk if successfull.
// problems: .
Acad::ErrorStatus CImageSupportModule::Manipulate (AcDbObjectId parEntityId)
{
AcDbRasterImage* pAcDbRasterImage;
Acad::ErrorStatus es = acdbOpenObject((AcDbObject*&) pAcDbRasterImage, parEntityId, AcDb::kForWrite);
if (es == Acad::eOk)
{
// Get current clip boundary.
AcGePoint2dArray ClipBoundary = pAcDbRasterImage->clipBoundary ();
// type of clip boundary
AcDbRasterImage::ClipBoundaryType ClipBoundaryType = AcDbRasterImage::kPoly; // polygonal clip boundary
// Define single clip points to set and append it to the clip boundary.
// Be aware that the first and last clip point has to be the same
// and that the clip points are pixel space.
AcGePoint2d ClipPoint; // single clip point
ClipPoint.set (100, 100);
ClipBoundary.setAt (0, ClipPoint);
ClipPoint.set (300, 0);
ClipBoundary.setAt (1, ClipPoint);
ClipPoint.set (600, 200);
ClipBoundary.setAt (2, ClipPoint);
ClipPoint.set (100, 400);
ClipBoundary.setAt (3, ClipPoint);
ClipPoint.set (100, 100);
ClipBoundary.setAt (4, ClipPoint);
// Last point has to be same as first point.
ClipPoint.set (100, 100);
ClipBoundary.append (ClipPoint);
// Set orientation.
AcGePoint3d origin(4, 3, 0);
AcGeVector3d u(6, 0, 0),v(0, 1, 0);
Adesk::Boolean ReturnValue = pAcDbRasterImage->setOrientation( origin, u, v );
if (ReturnValue != Adesk::kTrue)
acutPrintf(_T("Error: Set orientation failed.\n"));
// Set clip boundary.
es = pAcDbRasterImage->setClipBoundary(ClipBoundaryType, ClipBoundary);
if (es != Acad::eOk)
acutPrintf(_T("Error: Set orientation failed.\n"));
pAcDbRasterImage->close();
}
return es;
}
//
//! @brief
//! @param const AcGePoint3d& ptLB
//! @param const AcGePoint3d& ptRT
//! @exception
//! @return Acad::ErrorStatus
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-3-19 1.0
// 2011-7-25 1.0
//
Acad::ErrorStatus CImageSupportModule::SetPos( const AcDbObjectId& id, const AcGePoint3d& ptLB, const AcGePoint3d& ptRT )
{
AcDbRasterImage* pRasterImage = NULL;
Acad::ErrorStatus es = acdbOpenObject((AcDbObject*&) pRasterImage, id, AcDb::kForWrite);
if (es != Acad::eOk) return es;
AcGePoint3dArray verts;
pRasterImage->getVertices(verts);
AcGeMatrix3d mtx = ptLB - verts[0];
pRasterImage->transformBy(mtx);
if (es != eOk) return es;
return Acad::eOk;
}
/**
* @brief 删除本图中所有名字为 \c pImageName 的图像引用,然后删除图像定义
*
* @param pImageName
*
* @returns (Acad::ErrorStatus)
*
* detailed description here.
*
*/
Acad::ErrorStatus CImageSupportModule::DeleteImageDef( const ACHAR* pImageName )
{
Acad::ErrorStatus es = eOk;
// Get Dictionary Id.
AcDbObjectId DictionaryId = AcDbRasterImageDef::imageDictionary(m_pDb);
if (DictionaryId.isNull())
{
return eOk; // 没有图像字典,说明无需删除,返回eOK是合理的
}
AcDbObjectPointer<AcDbDictionary> dictionaryPtr(DictionaryId,kForRead);
if (dictionaryPtr.openStatus() != Acad::eOk)
{
return es;
}
if (!dictionaryPtr->has(pImageName))
{
return eOk; // 没有此图形记录,返回eOk
}
AcDbObjectId parObjectId;
es = dictionaryPtr->getAt(pImageName,parObjectId);
struct ImagePred
{
ImagePred(AcDbObjectId id) : m_imageDefId(id)
{
}
bool operator()(const AcDbEntity * pEnt)
{
if (!pEnt->isKindOf(AcDbRasterImage::desc())) return false;
const AcDbRasterImage * pImage = (const AcDbRasterImage*) pEnt;
return pImage->imageDefId() == m_imageDefId;
}
private:
AcDbObjectId m_imageDefId;
};
FilteredEntityCollector entityColl (m_pDb);
ImagePred imagePred(parObjectId);
entityColl.OfPredicate(imagePred);
AcDbObjectIdArray resultImageIds = entityColl.ToObjectIdArray();
for(int i = 0; i < resultImageIds.length(); ++i)
{
const AcDbObjectId& oid = resultImageIds.at(i);
AcDbObjectPointer<AcDbEntity> entPtr(oid,kForWrite);
if ((es = entPtr.openStatus()) != eOk)
return es;
entPtr->erase();
}
AcDbObjectPointer<AcDbObject> imageDefPtr(parObjectId,kForWrite);
if ((es = imageDefPtr.openStatus()) != eOk) return es;
es = imageDefPtr->erase();
if (es != eOk) return es;
imageDefPtr->close();
dictionaryPtr->upgradeOpen();
es = dictionaryPtr->remove(pImageName);
return es;
} |
|