[返回博客](/cn/blog) # 在 .dwg 文件中使用 .dgn 线型（第 4 部分，共 4 部分）

Andrew Markovich 二月 28, 2019 [\#Example](/cn/blog/tag/example) [\#.dwg](/cn/blog/tag/dwg)

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

本文是关于在 .dwg 文件中使用 DGN 线型系列文章的一部分。有关上一篇文章，请参阅[第 3 部分](https://www.opendesign.com/blog/2019/january/using-dgn-line-styles-dwg-file-part-3-4)。

#### 创建点线型组件

点线型组件能够为每个笔划图案虚线（或间隙）或曲线起点/终点设置要矢量化的符号组件。它还能够为每个多段线顶点设置要矢量化的符号组件。要为笔划图案虚线（和间隙）设置符号，首先创建笔划图案组件。在此示例中，我们使用[上一篇文章](https://www.opendesign.com/blog/2019/january/using-dgn-line-styles-dwg-file-part-3-4)中的简单笔划图案组件：

```
// Create Stroke LineStyle Component
OdDbLSStrokePatternComponentPtr pLsComponent = OdDbLSStrokePatternComponent::createObject();
pLsComponent->setComponentType(kLSStrokePatternComponent);
pLsComponent->setComponentUID(dgnLS_UID);

// Append strokes
pLsComponent->insertStroke(0.008)->setDash();
pLsComponent->insertStroke(0.003)->setGap();
pLsComponent->insertStroke(0.002)->setDash();
pLsComponent->insertStroke(0.003)->setGap();

// Add component into LineStyles dictionary
OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponentForPointComponent"), pLsComponent);

```

这组笔画和间隙生成以下线型：

![image0](/files/inline-images/0.jpg)现在我们可以创建一个新的点组件（此代码是创建所有 DGN 线型组件的典型代码），并将现有的笔画模式组件附加到它：

```
// Create Point Component
OdDbLSPointComponentPtr pPtComponent = OdDbLSPointComponent::createObject();
pPtComponent->setComponentType(kLSPointComponent);
::oddbDgnLSIncrementUID(dgnLS_UID);
pPtComponent->setComponentUID(dgnLS_UID);

// Set up stroke component for point component
pPtComponent->setStrokeComponent(pLsComponent->objectId());

```

注意：当附加到点组件时，底层笔画模式组件的虚线不会被矢量化。要将笔画模式组件与点组件符号一起矢量化，需要创建复合组件。复合组件将在未来的博客文章中讨论。

要使用点组件，请在程序源代码中添加一个额外的包含文件：

```
#include "DgnLS/DbLSPointComponent.h"
```

现在，例如，将现有符号组件连接到描边图案组件中的第二个段（这是描边图案中的第一个间隙）：

```
// Set symbol for stroke component gaps
OdDbLSSymbolReference lsRef;
lsRef.setSymbolComponent(pSymComponent->objectId());
lsRef.setJustify(OdDbLSSymbolReference::kLSJustifyCenter);
pPtComponent->insertSymbolForStroke(&lsRef, 1);

```

此代码中的 OdDbLSSymbolReference 结构表示一组符号参数，例如旋转、偏移、对齐方式和一些附加标志。在此示例中，使用 OdDbLSSymbolReference::setSymbolComponent 方法将符号组件 ID 附加到 OdDbLSSymbolReference 结构。此外，设置对齐方式以在描边图案间隙的中心显示符号。必须设置对齐参数才能为描边附加符号。最后，调用 OdDbLSPointComponent::insertSymbolForStroke 方法将符号附加到点组件。

并将第二个符号组件附加到曲线末端进行矢量化：

```
// Set symbol for line end
lsRef.setSymbolComponent(pSymComponent->objectId());
lsRef.setJustify(OdDbLSSymbolReference::kLSNoJustify);
pPtComponent->insertSymbolForVertex(&lsRef, OdDbLSSymbolReference::kLSAtEnd);

```

最后，将我们的点组件附加到 DGN 线型组件字典：

```
// Add component into LineStyles dictionary
pDict->setAt(OD_T("DemoDgnPointComponent"), pPtComponent);
```

所有以下代码都在上一篇文章中详细介绍过，用于创建线型定义组件，将其附加到 OdDbLinetypeTableRecord 并创建线实体以测试线型可视化。这里我们再次使用它，但有一个小区别：将新的点线型组件附加到线型定义，而不是描边图案组件。

```
// Create LineStyle Definition
OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
pLSDef->setComponent(pPtComponent->objectId());
pLSDef->setComponentUID(pPtComponent->componentUID());

// Create Linetype Table Record
OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
pLtpRec->setName(OD_T("DemoDgnLineStylePoint"));
pLtpRec->setComments(OD_T("Point component"));
OdDbObjectId lsId = OdDbLinetypeTable::cast(pDb->getLinetypeTableId().safeOpenObject(OdDb::kForWrite))->add(pLtpRec);
// Attach LineStyle Definition to Linetype Table Record
pLtpRec->createExtensionDictionary();
OdDbDictionaryPtr pLtpDict = OdDbDictionary::cast(pLtpRec->extensionDictionary().openObject(OdDb::kForWrite));
pLtpDict->setAt(::oddbDgnLSGetDefinitionKeyName(), pLSDef);

// Create line for LineStyle testing
OdDbLinePtr pLine = OdDbLine::createObject();
pLine->setDatabaseDefaults(pDb);
pLine->setLinetype(lsId);
pLine->setEndPoint(OdGePoint3d(1.0, 0.0, 0.0));
OdDbBlockTableRecord::cast(pDb->getActiveLayoutBTRId().safeOpenObject(OdDb::kForWrite))->appendOdDbEntity(pLine);

```

执行代码后生成的线型如下图所示（在不同的缩放级别下）：

![image1](/files/inline-images/1.jpg)![image2](/files/inline-images/2.jpg)![image3](/files/inline-images/3.jpg)![image4](/files/inline-images/4.jpg)包含四个螺旋的块显示在每个线型（描边）图案重复处，包含折线箭头的块显示在 OdDbLine 实体的终点处。

#### 点组件创建（完整命令源代码）

```
#include "DbLinetypeTable.h"
#include "DbLinetypeTableRecord.h"
#include "DbLine.h"
#include "DbHelix.h"
#include "DbPolyline.h"
#include "DbBlockTable.h"
#include "DgnLS/DbLSDefinition.h"
#include "DgnLS/DbLSStrokePatternComponent.h"
#include "DgnLS/DbLSPointComponent.h"
#include "DgnLS/DbLSSymbolComponent.h"
#include "DgnLS/DbLSMisc.h"

static OdDbHelixPtr createHelix(OdGePoint3d location, double radius)
{
  OdDbHelixPtr helPtr = OdDbHelix::createObject();
  helPtr->setStartPoint(location - OdGeVector3d::kZAxis);
  helPtr->setConstrain(OdDbHelix::kTurns);
  helPtr->setBaseRadius(radius);
  helPtr->setTopRadius(radius / 5);
  helPtr->setTurns(4.0);
  helPtr->setAxisVector(OdGeVector3d::kZAxis);
  helPtr->createHelix();
  return helPtr;
}

static OdDbBlockTableRecordPtr createSegmentBlock()
{ const double fBlockScale = 1.0 / 1000.0;
  OdDbBlockTableRecordPtr btrPtr = OdDbBlockTableRecord::createObject();
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d(-fBlockScale, -fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d( fBlockScale, -fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d(-fBlockScale,  fBlockScale, 0.0), fBlockScale));
  btrPtr->appendOdDbEntity(createHelix(OdGePoint3d( fBlockScale,  fBlockScale, 0.0), fBlockScale));
  btrPtr->setName(OD_T("4helix"));
  return btrPtr;
}

static OdDbBlockTableRecordPtr createArrowBlock()
{
  const double fBlockScale = 1.0 / 1000.0;
  OdDbPolylinePtr pPl = OdDbPolyline::createObject();
  pPl->addVertexAt(0, OdGePoint2d(-fBlockScale, -fBlockScale));
  pPl->addVertexAt(1, OdGePoint2d(-fBlockScale,  fBlockScale));
  pPl->addVertexAt(2, OdGePoint2d( fBlockScale,  0.0));
  pPl->setClosed(true);
  OdDbBlockTableRecordPtr btrPtr = OdDbBlockTableRecord::createObject();
  btrPtr->appendOdDbEntity(pPl);
  btrPtr->setName(OD_T("arrow"));
  return btrPtr;
}

static OdDbObjectId appendBlock(OdDbDatabase *pDb, OdDbBlockTableRecordPtr btrPtr)
{
  return OdDbBlockTable::cast(pDb->getBlockTableId().openObject(OdDb::kForWrite))->add(btrPtr);
}

void _CreateDgnLineStyle_Point_func(OdEdCommandContext* pCmdCtx)
{
  OdDbDatabasePtr pDb = pCmdCtx->baseDatabase();
  OdDbUserIOPtr pIO = pCmdCtx->userIO();

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

  // We need GUID for DgnLS objects
  OdUInt8 dgnLS_UID[16];
  ::oddbDgnLSInitializeImportUID(dgnLS_UID);

  // Create Stroke LineStyle Component
  OdDbLSStrokePatternComponentPtr pLsComponent = OdDbLSStrokePatternComponent::createObject();
  pLsComponent->setComponentType(kLSStrokePatternComponent);
  pLsComponent->setComponentUID(dgnLS_UID);

  // Append strokes
  pLsComponent->insertStroke(0.008)->setDash();
  pLsComponent->insertStroke(0.003)->setGap();
  pLsComponent->insertStroke(0.002)->setDash();
  pLsComponent->insertStroke(0.003)->setGap();

  // Add component into LineStyles dictionary
  OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
  pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponentForPointComponent"), pLsComponent);

  // Create symbol component for first block
  OdDbLSSymbolComponentPtr pSymComponent = OdDbLSSymbolComponent::createObject();
  pSymComponent->setComponentType(kLSSymbolComponent);
  pSymComponent->setDescription(OD_T("DemoDgnSymbol1"));
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pSymComponent->setComponentUID(dgnLS_UID);

  // Attach block to symbol component
  pSymComponent->setBlockTableRecord(::appendBlock(pDb, ::createSegmentBlock()));

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnSymbolForSegment"), pSymComponent);

  // Create Point Component
  OdDbLSPointComponentPtr pPtComponent = OdDbLSPointComponent::createObject();
  pPtComponent->setComponentType(kLSPointComponent);
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pPtComponent->setComponentUID(dgnLS_UID);

  // Set up stroke component for point component
  pPtComponent->setStrokeComponent(pLsComponent->objectId());

  // Set symbol for stroke component gaps
  OdDbLSSymbolReference lsRef;
  lsRef.setSymbolComponent(pSymComponent->objectId());
  lsRef.setJustify(OdDbLSSymbolReference::kLSJustifyCenter);
  pPtComponent->insertSymbolForStroke(&lsRef, 1);

  // Create symbol component for second block
  pSymComponent = OdDbLSSymbolComponent::createObject();
  pSymComponent->setComponentType(kLSSymbolComponent);
  pSymComponent->setDescription(OD_T("DemoDgnSymbol2"));
  ::oddbDgnLSIncrementUID(dgnLS_UID);
  pSymComponent->setComponentUID(dgnLS_UID);

  // Attach block to symbol component
  pSymComponent->setBlockTableRecord(::appendBlock(pDb, ::createArrowBlock()));

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnSymbolForLineEnd"), pSymComponent);

  // Set symbol for line end
  lsRef.setSymbolComponent(pSymComponent->objectId());
  lsRef.setJustify(OdDbLSSymbolReference::kLSNoJustify);
  pPtComponent->insertSymbolForVertex(&lsRef, OdDbLSSymbolReference::kLSAtEnd);

  // Add component into LineStyles dictionary
  pDict->setAt(OD_T("DemoDgnPointComponent"), pPtComponent);

  // Create LineStyle Definition
  OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
  pLSDef->setComponent(pPtComponent->objectId());
  pLSDef->setComponentUID(pPtComponent->componentUID());

  // Create Linetype Table Record
  OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
  pLtpRec->setName(OD_T("DemoDgnLineStylePoint"));
  pLtpRec->setComments(OD_T("Point component"));
  OdDbObjectId lsId = OdDbLinetypeTable::cast(pDb->getLinetypeTableId().safeOpenObject(OdDb::kForWrite))->add(pLtpRec);
  // Attach LineStyle Definition to Linetype Table Record
  pLtpRec->createExtensionDictionary();
  OdDbDictionaryPtr pLtpDict = OdDbDictionary::cast(pLtpRec->extensionDictionary().openObject(OdDb::kForWrite));
  pLtpDict->setAt(::oddbDgnLSGetDefinitionKeyName(), pLSDef);

  // Create line for LineStyle testing
  OdDbLinePtr pLine = OdDbLine::createObject();
  pLine->setDatabaseDefaults(pDb);
  pLine->setLinetype(lsId);
  pLine->setEndPoint(OdGePoint3d(1.0, 0.0, 0.0));
  OdDbBlockTableRecord::cast(pDb->getActiveLayoutBTRId().safeOpenObject(OdDb::kForWrite))->appendOdDbEntity(pLine);
}

```

## 今天就开始行动

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

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