Maps for Missing Texture Coordinates in Teigha Visualize

Alexander Fedorov

May 10, 2018

Teigha Visualize has a mapping mechanism to use correct texture settings even when mapping coordinates are not present. In this tutorial, we’ll create a sphere and the texture will be set using mappers.

Let’s see how to create a ball.

Suppose we have a model and a database ID. Let’s get a pointer to the database, add an entity to this model, and append a sphere to it.

// 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);

Then create a material and material map, and set it to the entity:

// 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);

The mapping projection type is set to the entity mapper. It shows how the texture is associated with the geometry. The entity has a default mapper with default projection kPlanar.

Texture without mappers:

image1

In this case, the mapper type is kSphere.

There are two kinds of mappers:

  • Set to the entity (OdTvMapperDef) and used for translation, rotation and scale texture.
  • Used for the diffusing map (OdTvMapper) and used for texture offsetting, scaling and rotating.

Each of them has a transform matrix, but these matrices have different functions. The OdTvMapperDef transform matrix is used for setting the texture position to a 3D object. The translate vector translates the texture UV zero position in the 3D system. For example, for a sphere it can be the center of the sphere. Also, the texture can be rotated by axis by setting data in another matrix position. The transform matrix of the entity mapper is usually the transformation matrix, so its elements are the same elements as a usual matrix used for 3D.

The transform matrix in OdTvMapper is used for offsetting, scaling and rotating the texture on the object. In the [0][0] position of this matrix, 1 / u_scale; and in the [1][1] position, 1 / v_scale. For fully setting the texture on the sphere, in the [0][0] and [1][1] positions should be 1. Texture offsetting is in [0][3] by X and in [1][3] by Y. For X, the offset is calculated as x * 1 / u_scale, and for y it is y * 1 / v_scale. And for rotating in [0][0] set cos([0][0]), in [0][1] set sin([0][1]) (clockwise), or –sin([0][0]) (counterclock-wise), in [1][0] set –sin([1][1]) (clockwise) or sin([1][1]) (counterclock-wise), and in [1][1] set cos([1][1]). Offsetting makes sense only if the texture scaling is greater than 1.

There are a number of methods to make using mappers easy:

  • OdTvMapperDef::translate() sets the texture position.
  • OdTvMapperDef::rotate() rotates the texture.
  • OdTvMapperDef::scale() scales the texture by axis.
  • OdTvTextureMapper::setSampleSize() sets the texture sample size.
  • OdTvTextureMapper::setOffset() offsets the texture.
  • OdTvTextureMapper::setRotation() rotates the texture.
// 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);

The result is the following texture with the kSphere mapper:

image2