[返回博客](/cn/blog) # Teigha Visualize 中缺失纹理坐标的映射

Alexander Fedorov 五月 10, 2018 [\#Visualize](/cn/blog/tag/visualize) [\#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 具有一种映射机制，即使在没有映射坐标的情况下也能使用正确的纹理设置。在本教程中，我们将创建一个球体，并使用映射器设置纹理。

让我们看看如何创建一个球体。

假设我们有一个模型和一个数据库 ID。让我们获取数据库的指针，向此模型添加一个实体，并向其附加一个球体。

```
// Open database
OdTvDatabasePtr pTvDb = databaseId.openObject();

// Create entity
OdTvModelPtr modelPtr = modelId.openObject(OdTv::kForWrite);
OdTvEntityId entityId = modelPtr->appendEntity(OD_T("Ball"));
OdTvEntityPtr pEntity = entityId.openObject(OdTv::kForWrite);

// Append sphere to entity
pEntity->appendShellFromSphere(OdTvPoint(3., 3., 3.), 0.9, OdTvVector::kYAxis, OdTvVector::kXAxis, 50);

```

然后创建材质和材质贴图，并将其设置为实体：

```
// Create material with unique name
OdTvMaterialId materialId = pTvDb->createMaterial("Material");
OdTvMaterialPtr pMaterial = materialId.openObject(OdTv::kForWrite);

// Create material map
OdTvMaterialMap materialMap;

// Set texture path to map
materialMap.setSourceFileName(“../resources/Ball.png”);

// Set material map to material
pMaterial->setDiffuse(OdTvMaterialColor(OdTvColorDef(255, 0, 0)), materialMap);

// Set material to mapper
pEntity->setMaterial(materialId);

```

映射投影类型设置为实体映射器。它显示了纹理如何与几何体关联。实体具有默认映射器和默认投影 kPlanar。

没有映射器的纹理：

![image1](/files/inline-images/image002_11.jpg)在这种情况下，映射器类型为 kSphere。

映射器有两种：

- 设置为实体（OdTvMapperDef），用于纹理的平移、旋转和缩放。
- 用于漫反射贴图（OdTvMapper），用于纹理的偏移、缩放和旋转。

它们每个都有一个变换矩阵，但这些矩阵具有不同的功能。OdTvMapperDef 变换矩阵用于设置纹理在 3D 对象上的位置。平移向量在 3D 系统中平移纹理 UV 零点位置。例如，对于球体，它可以是球体的中心。此外，通过在另一个矩阵位置设置数据，纹理可以绕轴旋转。实体映射器的变换矩阵通常是变换矩阵，因此其元素与用于 3D 的普通矩阵的元素相同。

OdTvMapper 中的变换矩阵用于在对象上偏移、缩放和旋转纹理。在该矩阵的 \[0\]\[0\] 位置，为 1 / u\_scale；在 \[1\]\[1\] 位置，为 1 / v\_scale。为了将纹理完全设置在球体上，\[0\]\[0\] 和 \[1\]\[1\] 位置应为 1。纹理偏移在 \[0\]\[3\] 处按 X 偏移，在 \[1\]\[3\] 处按 Y 偏移。对于 X，偏移计算为 x \* 1 / u\_scale；对于 Y，偏移计算为 y \* 1 / v\_scale。对于旋转，在 \[0\]\[0\] 处设置 cos(\[0\]\[0\])，在 \[0\]\[1\] 处设置 sin(\[0\]\[1\])（顺时针）或 –sin(\[0\]\[0\])（逆时针），在 \[1\]\[0\] 处设置 –sin(\[1\]\[1\])（顺时针）或 sin(\[1\]\[1\])（逆时针），在 \[1\]\[1\] 处设置 cos(\[1\]\[1\])。只有当纹理缩放大于 1 时，偏移才有意义。

有许多方法可以简化映射器的使用：

- OdTvMapperDef::translate() 设置纹理位置。
- OdTvMapperDef::rotate() 旋转纹理。
- OdTvMapperDef::scale() 按轴缩放纹理。
- OdTvTextureMapper::setSampleSize() 设置纹理采样大小。
- OdTvTextureMapper::setOffset() 偏移纹理。
- OdTvTextureMapper::setRotation() 旋转纹理。

```
// Create material with unique name
OdTvMaterialId materialId = pTvDb->createMaterial("Material");
OdTvMaterialPtr pMaterial = materialId.openObject(OdTv::kForWrite);

// Create material map
OdTvMaterialMap materialMap;

// Create path to texture image file and set it to map
materialMap.setSourceFileName(“../resources/Ball.png”);
  
// Create entity mapper
OdTvMapperDef entityMapper;
entityMapper.setProjection(OdTvMapperDef::kSphere);
// Translate and rotate texture
entityMapper.translate(3., 3., 3.);
entityMapper.rotate(0., OdaPI / 2., OdaPI / 2.);
  
// Create material mapper, set texture sample size and set it to map
OdTvTextureMapper materialMapper;
materialMapper.setSampleSize(1., 1.);
materialMap.setMapper(materialMapper);

// Set mapper to entity
pEntity->setEntityMaterialMapper(entityMapper);

// Set material map to material
pMaterial->setDiffuse(OdTvMaterialColor(OdTvColorDef(255, 0, 0)), materialMap);

// Set material to mapper
pEntity->setMaterial(materialId);

```

结果是带有 kSphere 映射器的以下纹理：

![image2](/files/inline-images/image004_4.jpg)

## 今天就开始行动

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

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