插入带栅格数据的 OLE 对象

INSERTRASTER 跨平台命令(参见 _InsertRaster_func 函数)用于将不同栅格图像格式的文件插入到 .dwg 图纸中。它用于在 ODADrawingsExplorer 中伪打开栅格文件,结果可以保存为 .dwg 文件。

_InsertRaster_func 函数包含在 ExCommands.tx 模块中,其源代码可以在以下路径找到:Drawing/Examples/ExCommands/ExInserRaster.cpp。

首先,命令会提示输入源栅格图像文件的路径。

OdDbUserIOPtr pIO = pCmdCtx->userIO();
OdString path = pIO->getFilePath(L"Select file to insert", OdEd::kGfpForOpen,
                                 L"Select file to insert", L"bmp", L"",
                                 L"Bitmap files (*.bmp)|*.bmp|Jpeg files (*.jpg)|*.jpg|"
                                 L"PNG files (*.png)|*.png|All files (*.*)|*.*||");

然后,命令会加载指定的栅格图像。

OdRxRasterServicesPtr pRasSvcs = ::odrxDynamicLinker()->loadApp(RX_RASTER_SERVICES_APPNAME);
OdGiRasterImagePtr pImage = pRasSvcs->loadRasterImage(path);

然后,命令会根据需要转换加载的栅格图像,使其高度和宽度不超过2,048像素。这是为了确保包含该图像的.dwg图纸能够在Autodesk® AutoCAD®和ODA Software中成功渲染。

如果跳过此步骤,则高度或宽度超过2,048像素的栅格图像只能在ODA Software中并仅使用OdOleSsItemHandlerModule.tx模块成功渲染。

::odrxDynamicLinker()->loadModule(OdOleSsItemHandlerModuleName);

在创建Ole2Frame对象之前,必须加载ItemHandler模块。通常,执行该命令的应用程序会首先加载该模块。在这种情况下,可以跳过以下步骤。

::odrxDynamicLinker()->loadModule(OdOlePlatformItemHandlerModuleName);

然后,命令会创建一个Ole2Frame对象,并将加载的栅格图像插入其中。

OdDbDatabase* pDb = OdDbDatabase::cast(pCmdCtx->baseDatabase()).get();
OdDbOle2FramePtr pOleFrame = OdDbOle2Frame::createObject();
pOleFrame->setDatabaseDefaults(pDb);
OdOleItemHandler* pItem = pOleFrame->getItemHandler();
pItem->embedRaster(pImage, pDb);
pOleFrame->setOutputQuality(OdDbOle2Frame::kHighGraphics);
pOleFrame->unhandled_setHimetricSize(OdUInt16(pImage->pixelWidth()),
                                     OdUInt16(pImage->pixelHeight()));

使用特殊的跟踪器来设置框架的位置。

struct OleSsInsertTracker : OdEdRealTracker
{
  OdSmartPtr<OdDbOle2Frame> _pOleFrame;
  OdGePoint3d _orig;
  OdGeVector2d _size;
  double _dist;

  void setValue(double dist)
  {
    _dist = dist;
    OdRectangle3d r3d;
    OdGeVector2d size = _size.normal() * _dist;
    r3d.lowLeft .set(_orig.x,          _orig.y,          _orig.z);
    r3d.upLeft  .set(_orig.x,          _orig.y + size.y, _orig.z);
    r3d.upRight .set(_orig.x + size.x, _orig.y + size.y, _orig.z);
    r3d.lowRight.set(_orig.x + size.x, _orig.y,          _orig.z);
    _pOleFrame->setPosition(r3d);
  }
  int addDrawables(OdGsView* pView) { pView->add(_pOleFrame, 0); return 1; }
  void removeDrawables(OdGsView* pView) { pView->erase(_pOleFrame); }
};
OdStaticRxObject<OleSsInsertTracker> tracker;
tracker._pOleFrame = pOleFrame;
OdGeVector2d size(pImage->pixelWidth(), pImage->pixelHeight());
OdDbUserIOPtr pIO = pCmdCtx->userIO();
tracker._orig = pIO->getPoint(L"Specify insertion point <0,0>:",
                              OdEd::kGptDefault, &OdGePoint3d::kOrigin);

// Set initial OLE frame position to origin, and size in world units.
// Convert MM_HIMETRIC (0.01 millimeter) to space units.

double s = pDb->getMEASUREMENT()==OdDb::kEnglish ? 0.01 / 25.4 : 0.01;
tracker._size.set(double(size.x) * s, double(size.y) * s);
OdString sPmt;
sPmt.format(OD_T("Specify size <%g>:"), tracker._size.length());
double dist = pIO->getDist(sPmt, OdEd::kGdsFromLastPoint | OdEd::kGptRubberBand, 0.,
                           OdString::kEmpty, &tracker));
tracker.setValue(dist);

如果r3d矩形已知,则只需进行以下调用即可,而无需执行上述操作:

pOleFrame->setPosition(r3d);

最后,命令会将完成的框架添加到数据库的活动布局中。

OdDbBlockTableRecordPtr pSpace = pDb->getActiveLayoutBTRId().safeOpenObject(OdDb::kForWrite);
pSpace->appendOdDbEntity(pOleFrame);

今天就开始行动

免费试用 ODA 软件 60 天。
无风险,无需信用卡。

免费试用