[返回博客](/cn/blog) # 如何在 Teigha Visualize 中使用标记（批注）

Vlad Malka 五月 24, 2018 [\#Visualize](/cn/blog/tag/visualize) [\#getting started](/cn/blog/tag/getting-started) [\#Example](/cn/blog/tag/example)

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

Teigha Visualize 支持有助于审阅和编辑文件的功能，特别是创建和保存标记（批注）。以下是一些包含标记的图纸示例：

![image1](/files/inline-images/image002_13.jpg)![image2](/files/inline-images/image004_6.jpg)![image3](/files/inline-images/image006_3.jpg)在 Teigha Visualize Viewer 示例中，您可以亲自尝试。使用主窗口中的“标记”工具栏创建不同类型的标记：

- 矩形标记 — 绘制矩形标记；
- 圆形标记 — 绘制圆形标记；
- 手柄标记 — 绘制自由手柄标记；
- 云线标记 — 绘制云线标记；
- 文本标记 — 绘制文本标记。

![image4](/files/inline-images/image007_4.png)然后使用这两个工具保存和加载标记视图：

- 保存视图 — 保存当前带有您绘制的标记的视图；
- 加载视图 — 加载包含标记的视图。

要保存您绘制的标记：

1. 单击“保存”； ![image5](/files/inline-images/image009_3.png)
2. 输入保存的标记视图的名称。

其工作原理如下：

保存的标记使用包含视图参数的结构：位置、目标、upVector、fieldWidth、fieldHeight、投影类型和渲染模式。当按下“保存”按钮时，这些参数从视图中接收。之后，该结构将二进制数据写入具有输入名称的新实体。

```
// create and append the binary data to the entity
OdTvByteUserData *data = new OdTvByteUserData(params, sizeof(struct SaveViewParams), OdTvByteUserData::kOwn, true);
      pEn->appendUserData(data, m_appTvId);

```

要加载包含标记的已保存视图：

1. 单击“加载”； ![image6](/files/inline-images/image010_0.png)
2. 选择要加载的视图，然后单击“加载”。 （您也可以单击“删除”以移除选定的标记视图。）

其工作原理如下：

当按下“加载”按钮时，首先从具有选定名称的实体中读取二进制数据，然后将数据应用于当前视图，最后为该实体打开可见性。

#### 实施细节

以下是标记实现结构的图表：

![image7](/files/inline-images/image012.jpg)在数据库中，存储了不同的模型，其中一个模型存储标记实体。此模型的名称为“$ODA\_TVVIEWER\_MARKUPS”。该模型仅在绘制标记时创建。在对象树中，此模型位于“服务模型”中。请务必检查此模型是否存在。

```
if (m_TvMarkupsModelId.isNull())
{
  m_TvMarkupsModelId = m_TvDatabaseId.openObject(OdTv::kForWrite)
    ->createModel(OD_TV_MARKUP_MODEL, OdTvModel::kDirect);

  m_TvMarkupsModelId.openObject()->setNeedSaveInFile(true);
}

```

当标记创建开始时，创建一个临时实体“$MarkupTempEntity”，其中所有名称都在具有适当名称的宏中声明；下一个标记创建将写入此实体。此实体在几乎任何操作（平移、轨道、缩放等）中都会被销毁。此外，模型还包含其他已保存的实体，而标记未保存，并且工作继续使用临时实体。下图显示了标记实体的结构。

![image8](/files/inline-images/image014_0.jpg)任何标记实体都只有五个子实体。每个子实体都是特殊类型标记的文件夹：

- 矩形标记 — 子实体“矩形”；
- 圆形标记 — 子实体“圆形”；
- 自由手柄标记 — 子实体“自由手柄”；
- 云标记 — 子实体“云”；
- 文本标记 — 子实体“文本”。

每个标记的构造函数都会搜索一个临时实体，如果未找到，则根据标记类型的文件夹创建一个新的临时实体。

```
// create main entity if not exist
OdTvModelPtr modelPtr = m_tvDraggersModelId.openObject(OdTv::kForWrite);
m_entityId = findEntityByName(modelPtr->getEntitiesIterator(), OD_TV_MARKUP_TEMP_ENTITY, false);
if (m_entityId.isNull())
{
  m_entityId = modelPtr->appendEntity(OD_TV_MARKUP_TEMP_ENTITY);
  m_entityId.openObject(OdTv::kForWrite)->setColor(OdTvColorDef(255, 0, 0));
}

// crate rectangles subEntity if not exist
m_rectFoldEntityId = findSubEntityByName(m_entityId.openObject()->getGeometryDataIterator(), OD_TV_MARKUP_RECTANGLES);
if (m_rectFoldEntityId.isNull())
  m_rectFoldEntityId = m_entityId.openObject(OdTv::kForWrite)->appendSubEntity(OD_TV_MARKUP_RECTANGLES);

```

标记文件夹包含具有相应几何数据的子实体。当创建对象标志为真时，使用 updateFrame() 方法创建具有几何数据的子实体。

```
//update or create entity
if (bCreate)
{
  m_rectEntityId = m_rectFoldEntityId.openAsSubEntity(OdTv::kForWrite)->appendSubEntity();
  {
    OdTvEntityPtr entityNewPtr = m_rectEntityId.openAsSubEntity(OdTv::kForWrite);
    //create frame
    m_frameId = entityNewPtr->appendPolygon(m_pts);
  }
}

```

## 今天就开始行动

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

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