为满足 ODA 成员的要求,现已提供在导出为 .pdf 文件时裁剪 .dgn 图纸的功能。
在将 .dgn 文件导出为 .pdf 文件之前,请设置一个裁剪区域,生成的 .pdf 文件将仅包含裁剪区域内的那些元素(如果修剪边界穿过元素,则包含元素的一部分)。裁剪区域可以具有自由形状,但应使用闭合的平面元素(例如形状、圆形、椭圆形或复杂形状)来指定裁剪区域的边界。
因此,让我们使用 OdaDgnApp 示例应用程序逐步检查如何执行“围栏”裁剪以导出为 .pdf 文件。
运行示例应用程序并打开要导出为 .pdf 文件的 .dgn 文件,并使用 Teigha 提供的渲染设备之一进行渲染。
在工具栏中选择两个“围栏”裁剪图标中的任意一个来设置裁剪形状。
第一种情况设置一个矩形裁剪区域(实际上它将是一个形状元素)。单击“围栏类型为矩形”:
接下来,指定围栏的矩形角:
接下来,选择“文件”->“导出为PDF”。并在“导出为PDF”设置中打开“Fence”选项:
运行导出并获取结果:
在设置圆形裁剪区域的第二种情况下,可以执行相同的操作。点击“Fence Type to Circle”:
导出为.pdf文件时,结果如下:
完成!
现在我们来看看OdaDgnApp中的更多实现细节。
声明了带有参数的“Fence”命令以实现此功能。它是一个继承自OdEdCommand类的特定类。请参阅OdaDgnAppDoc.h:
class Cmd_Fence : public OdEdCommand
{
public:
const OdString groupName() const;
const OdString globalName() const;
void execute(OdEdCommandContext* pCmdCtx);
};
该命令已添加到OdEdCommandStack列表中。
有关UI与命令执行的绑定,请参阅OdaDgnAppVectorizer.cpp:
ON_COMMAND(ID_CREATEFENCE_BTN, OnCreateFence)
ON_COMMAND(ID_CREATEFENCE_CIRCLE, OnCreateFenceCircle)
. . . . .
void COdaDgnAppVectorizer::OnCreateFence()
{
GetDocument()->ExecuteCommand( OD_T("Fence r") );
}
void COdaDgnAppVectorizer::OnCreateFenceCircle()
{
GetDocument()->ExecuteCommand( OD_T("Fence c") );
}
然后转到OdaDgnAppDoc.cpp,其中处理了该命令:
void COdaDgnAppDoc::ExecuteCommand(const OdString& sCmd, bool bEcho)
{
. . . . .
pCommands->executeCommand(s, pCmdCtx);
if( s == OD_T("FENCE") )
{
OdValuePtr pHandle = pCmdCtx->arbitraryData(OD_T("Fence"));
if( !m_idFence.isNull() && !pHandle.isNull() )
{
OdDgElementPtr pFence = m_idFence.openObject(OdDg::kForWrite);
if( !pFence.isNull() )
{
pFence->erase(true);
}
}
if( !pHandle.isNull() )
{
OdInt64 uHandle = 0;
pHandle->get(uHandle);
m_idFence = m_pDb->getElementId( OdDbHandle((OdUInt64)uHandle));
}
}
. . . . .
}
命令成功执行后,会分配一个用于裁剪的特定元素。其m_idFence被设置,然后.pdf导出将使用它进行裁剪。executeCommand()本身应该为fence命令调用适当的执行。因此,应该运行Cmd_Fence::execute()。在此调用内部,应该完成裁剪区域的规范:
void Cmd_Fence::execute(OdEdCommandContext* pCmdCtx)
{
. . . . .
try
{
pt1 = pIO->getPoint(L"Specify corner of window, enter a scale factor (nX or nXP), or\n"
L"[Rectangle/Circle] <real time>:",
OdEd::kInpThrowEmpty|OdEd::kInpThrowOther|OdEd::kGptNoOSnap, 0, szKeywords);
pt1 = pIO->getPoint(OD_T("Specify corner of Fence:"),OdEd::kInpThrowEmpty | OdEd::kGptNoOSnap);
pt2 = pIO->getPoint(OD_T("Specify opposite corner of Fence:"), OdEd::kGptNoUCS | OdEd::kGptRectFrame | OdEd::kGptNoOSnap);
create_Fence(pt1, pt2, pView, pDgView->getModelId(), pCmdCtx, false );
}
. . . . .
catch(const OdEdKeyword& kw)
{
switch(kw.keywordIndex())
{
case 0: // Rectangle clipping area
pt1 = pIO->getPoint(OD_T("Specify corner of Fence:"),OdEd::kInpThrowEmpty | OdEd::kGptNoOSnap);
pt2 = pIO->getPoint(OD_T("Specify opposite corner of Fence:"), OdEd::kGptNoUCS | OdEd::kGptRectFrame | OdEd::kGptNoOSnap);
create_Fence(pt1, pt2, pView, pDgView->getModelId(), pCmdCtx, false );
break;
case 1: // Circle clipping area
pt1 = pIO->getPoint(OD_T("Specify center of Fence:"),OdEd::kInpThrowEmpty | OdEd::kGptNoOSnap);
pt2 = pIO->getPoint(OD_T("Specify radius Fence:"), OdEd::kGptNoUCS | OdEd::kGptRectFrame | OdEd::kGptNoOSnap);
create_Fence(pt1, pt2, pView, pDgView->getModelId(), pCmdCtx, true );
break;
}
}
. . . . .
}
create_Fence()方法根据所选的fence命令模式创建适当的裁剪元素。在圆形裁剪边界的情况下,它将是OdDgEllipse3d;在矩形裁剪边界的情况下,它将是OdDgLineString3dPtr。
最后,要将此元素指定为导出到.pdf的体积裁剪元素,请参阅ExportToPDFDialog.cpp:
OdUInt32 CExport2PDFDialog::ExportToPdf(OdString pdfFileName)
{
OdPdfExportModulePtr pModule = ::odrxDynamicLinker()->loadApp(OdPdfExportModuleName);
{
OdPdfExportPtr exporter = pModule->create();
{
PDFExportParams params;
. . . . .
// Use fence for pdf exporting to clip the drawing
if( m_Views == 2 && !m_idFence.isNull() )
{
idView = getActiveViewId(m_pDb); // Get active view.
. . . . .
if( !idView.isNull() )
{
. . . . .
pView->setVolumeClipElementId( m_idFence ); // Set fence as volume clip element
. . . . .
}
}
}
}
}
这允许您设置和实现自己的裁剪边界,以修剪DGN图形并导出为.pdf文件。