.dwg 数据库支持 Autodesk® AutoCAD® 线型,但这些线型只能在线型图案中包含虚线、点和文本。DGN 线型功能强大得多,因为它们还支持:
- 在图案中嵌入块。
- 绘制具有偏移的多个图案(类似于 OdDbMLine 实体)。
- 许多额外的标志,以增强线型虚线行为。
ODA SDK 具有用于在 .dwg 数据库中嵌入 DGN 线型的类和函数。此外,由 ODA SDK 保存的 .dwg 文件可以在 AutoCAD 中类似地进行矢量化,AutoCAD 自 2012 版本以来一直支持矢量化 DGN 线型。一个例外是:DGN 线型只能以 .dwg 文件格式保存,如果以 .dxf 文件格式保存则会丢失。
设置 DGN 线型模块
所有 DGN 线型嵌入功能均由 AcDgnLS.tx 模块提供。此模块必须可用才能矢量化 DGN 线型。对于 DGN 线型创建,此模块必须加载并初始化。对于动态库配置,在使用 AcDgnLS.tx 模块功能之前,必须对其进行初始化:
::odrxDynamicLinker()->loadModule(OdDgnLSModuleName);
为了使用 DGN 线型创建功能,应用程序还必须链接 AcDgnLS.lib 静态库(对于非 Windows 平台,为 AcDgnLS.a)。
对于静态链接的应用程序,AcDgnLS.tx 模块必须在静态模块映射中注册:
/************************************************************************/
/* Define a module map for statically linked modules */
/************************************************************************/
#if !defined(_TOOLKIT_IN_DLL_) || defined(__MWERKS__)
ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdDgnLSModule);
ODRX_BEGIN_STATIC_MODULE_MAP()
ODRX_DEFINE_STATIC_APPMODULE(OdDgnLSModuleName, OdDgnLSModule)
ODRX_END_STATIC_MODULE_MAP()
#endif
创建笔划图案组件
笔划图案由一系列短划线(点)和间隙(空格)组成。这是创建 DGN 线型最简单的组件。每个短划线都可以有其自己的特定参数。为了简化我们的示例,我们将只调用部分参数。
为了创建组件,我们需要唯一的 GUID。AcDgnLS.tx 模块提供了一些函数来简化它们的使用。这些函数在一个单独的头文件中可用:
#include "DgnLS/DbLSMisc.h"
要初始化 GUID,请调用 oddbDgnLSInitializeImportUID 函数:
OdUInt8 dgnLS_UID[16];
::oddbDgnLSInitializeImportUID(dgnLS_UID);
包含包含 OdDbLSStrokePatternComponent 类声明的头文件:
#include "DgnLS/DbLSStrokePatternComponent.h"
现在我们可以创建笔划图案组件:
// Create Stroke LineStyle Component
OdDbLSStrokePatternComponentPtr pComponent = OdDbLSStrokePatternComponent::createObject();
pComponent->setComponentType(kLSStrokePatternComponent);
pComponent->setComponentUID(dgnLS_UID);
并在笔划图案组件中添加笔划和间隙:
// Append strokes
pComponent->insertStroke(0.008)->setDash();
pComponent->insertStroke(0.003)->setGap();
pComponent->insertStroke(0.002)->setDash();
pComponent->insertStroke(0.003)->setGap();
这些笔划和间隙的组合为我们提供了以下线型:
例如,我们可以修改第一个短划线并指定其他参数,例如宽度:
pComponent->insertStroke(0.008, 0.003, 0.002, OdDbLSStroke::kLSWidthFull)->setDash();
下图显示了此更改的结果:
最后,例如,我们可以修改短划线端点的行为:
pComponent->insertStroke(0.008, 0.003, 0.002, OdDbLSStroke::kLSWidthFull, OdDbLSStroke::kLSCapsArc)->setDash();
并获得以下线型:
当然,短划线还有更多参数可以修改,但描述它们超出了本文的范围。
创建并配置笔划图案组件后,我们可以将其添加到 .dwg 数据库中的 DGN 线型字典中:
// Add component into LineStyles dictionary
OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponent"), pComponent);
将线型附加到 .dwg 文件 (OdDbLinetypeTableRecord)
要将 DGN 线型应用于 .dwg 数据库实体,请将其附加到描述数据库中线型的原生 .dwg 数据库对象——即 OdDbLinetypeTableRecord。
首先,包含包含 OdDbLSDefinition 类声明的头文件:
#include "DgnLS/DbLSDefinition.h"
现在我们可以创建 OdDbLSDefinition,它将附加到线型表记录:
// Create LineStyle Definition
OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
pLSDef->setComponent(pComponent->objectId());
pLSDef->setComponentUID(pComponent->componentUID());
线型定义引用现有的线型组件。当然,它包含额外的参数,例如缩放等,但为了简单起见,我们在此处不会更改它们。现在我们可以创建一个 .dwg 数据库线型:
// Create Linetype Table Record
OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
pLtpRec->setName(OD_T("DemoDgnLineStyleStroke"));
pLtpRec->setComments(OD_T("Stroke 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);
现在,我们可以像使用标准线型一样,将创建的线型与任何 .dwg 数据库实体一起使用。为了完成我们的示例并显示结果,请使用此线型在数据库中填充一条新线:
// 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);
笔划模式创建(完整命令源代码)
#include "DbLinetypeTable.h"
#include "DbLinetypeTableRecord.h"
#include "DbLine.h"
#include "DgnLS/DbLSDefinition.h"
#include "DgnLS/DbLSStrokePatternComponent.h"
#include "DgnLS/DbLSMisc.h"
void _CreateDgnLineStyle_Stroke_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 pComponent = OdDbLSStrokePatternComponent::createObject();
pComponent->setComponentType(kLSStrokePatternComponent);
pComponent->setComponentUID(dgnLS_UID);
// Append strokes
pComponent->insertStroke(0.008, 0.003, 0.002, OdDbLSStroke::kLSWidthFull, OdDbLSStroke::kLSCapsArc)->setDash();
pComponent->insertStroke(0.003)->setGap();
pComponent->insertStroke(0.002)->setDash();
pComponent->insertStroke(0.003)->setGap();
// Add component into LineStyles dictionary
OdDbDictionaryPtr pDict = ::oddbDgnLSGetComponentsDictionary(pDb, OdDb::kForWrite, true);
pDict->setAt(OD_T("DemoDgnLineStyleStrokeComponent"), pComponent);
// Create LineStyle Definition
OdDbLSDefinitionPtr pLSDef = OdDbLSDefinition::createObject();
pLSDef->setComponent(pComponent->objectId());
pLSDef->setComponentUID(pComponent->componentUID());
// Create Linetype Table Record
OdDbLinetypeTableRecordPtr pLtpRec = OdDbLinetypeTableRecord::createObject();
pLtpRec->setName(OD_T("DemoDgnLineStyleStroke"));
pLtpRec->setComments(OD_T("Stroke 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);
}
本系列的下一篇文章将介绍如何使用内部线型组件。