[返回博客](/cn/blog) # 使用“围栏”或平面元素裁剪 .dgn 图纸以导出为 PDF

Sergey Sorvenkov 二月 06, 2018 [\#dgn](/cn/blog/tag/dgn) [\#export](/cn/blog/tag/export) [\#pdf](/cn/blog/tag/pdf)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

为满足 ODA 成员的要求，现已提供在导出为 .pdf 文件时裁剪 .dgn 图纸的功能。

在将 .dgn 文件导出为 .pdf 文件之前，请设置一个裁剪区域，生成的 .pdf 文件将仅包含裁剪区域内的那些元素（如果修剪边界穿过元素，则包含元素的一部分）。裁剪区域可以具有自由形状，但应使用闭合的平面元素（例如形状、圆形、椭圆形或复杂形状）来指定裁剪区域的边界。

因此，让我们使用 OdaDgnApp 示例应用程序逐步检查如何执行“围栏”裁剪以导出为 .pdf 文件。

运行示例应用程序并打开要导出为 .pdf 文件的 .dgn 文件，并使用 Teigha 提供的渲染设备之一进行渲染。

在工具栏中选择两个“围栏”裁剪图标中的任意一个来设置裁剪形状。

第一种情况设置一个矩形裁剪区域（实际上它将是一个形状元素）。单击“围栏类型为矩形”：

![image1](/files/inline-images/image001_23.png)接下来，指定围栏的矩形角：

![image2](/files/inline-images/image003_13.png)接下来，选择“文件”-&gt;“导出为PDF”。并在“导出为PDF”设置中打开“Fence”选项：

![image3](/files/inline-images/image005_8.png)运行导出并获取结果：

![image4](/files/inline-images/image007_3.png)在设置圆形裁剪区域的第二种情况下，可以执行相同的操作。点击“Fence Type to Circle”：

![image5](/files/inline-images/image009_2.png)导出为.pdf文件时，结果如下：

![image6](/files/inline-images/image011_2.png)完成！

现在我们来看看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文件。

## 今天就开始行动

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

[免费试用](https://www.opendesign.com/cn/free-trial)
