# Continuous UVs from CAD Models

> How to generate continuous UVs from CAD models in Asset Transformer Studio

Asset Transformer Studio gives the possibility to generate UVs based on the CAD data, which can then be made continuous for repeatable textures, or repacked for lightmaps.

Here is an example of a brushed aluminum material applied on a model for which continuous UVs were created using this method:

![Continuous UVs example](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_04.jpg)

## How To

UVs from CAD can be generated at the [tessellation phase](../about-tessellation), based on the BRep/NURBS surfaces contained in a CAD model. They are called "Conformal Scaled UVs".

Here is how to setup the `UV Mode` parameter in the [Tessellate](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#tessellate) function:

![Conformal Scaled UVs parameter](/api/media?file=/asset-transformer-studio/2026.5.0/media/ALGO_Tessellate_ConformalScaledUVs.jpg)

> **Important:**
>
> These CAD UVs are generated at the tessellation phase, so they can only be obtained with [CAD models](../about-3d-models-types) containing NURBS/BRep geometries.

The algorithm creates one UV island per CAD patch, unstretched, with a correct 2D scale relative to its 3D size. A small patch will have a smaller 2D size (in the UV space) than a big patch of the same part, resulting in a homogeneously scaled set of UVs.

Here is an example with the CAD model of a soldering gun:

![CAD UV islands](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_05.jpg)

As is, these **CAD UVs are not really suitable for repeatable textures, nor for lightmaps** — they are disconnected, too large, etc. — but they are a usable starting point.

See the paragraphs below to see how the UVs can be used both for repeatable textures and lightmaps.

### UVs for repeatable textures

UVs obtained at tessellation with the **Conformal Scaled UV** method are not directly usable for repeatable textures, **as they are not connected to each other, nor continuous**, as we can see with a Wood texture applied to the model:

![Disconnected UV islands](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_06.jpg)

To make the patches continuous, use the function [algo.mergeUVIslands()](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#mergeuvislandsaffine), which minimizes the number of seams in the UV mapping.

After running this function, **UV islands are now continuous**, allowing the texture to repeat properly:

![Merged UV islands](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_07.jpg)

The **remaining issue is the seam position** (green arrows): it is quite visible on the arm of the soldering gun, because it's placed at the exterior.

If we were to manually unwrap this model, we would place the seam in the interior of the arm, **where it is less visible**.

There is a method to do that automatically as well.

Using the function [algo.createVisibilityInformation()](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#createvisibilityinformation) before merging UV islands together, Asset Transformer Studio can find which polygons are less visible in the model, in order to find a better place to cut seams.

The polygons that are less visible from cameras placed around the model are automatically marked as candidates for seams (their edges/boundaries), using **visibility attributes**.

These visibility attributes are transferred as weights to the function [algo.mergeUVIslands()](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#mergeuvislandsaffine) using another function: [algo.transferVisibilityToPolygonalWeight()](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#transfervisibilitytopolygonalweight).

Using these visibility attributes as a helper to find the best seam possible, the UV islands merging gives a much better result, with **a seam placed in the interior of the arm, where it is the least visible**:

![Optimized seam placement](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_08.jpg)

Comparing the result of the UV obtained by merging the **Conformal Scaled UVs** against UVs obtained by a simple projection, we can see the benefits of the first method: **textures are continuous with no visible seams, and unstretched!**

![Comparison with projection](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_09.jpg)

Asset Transformer Studio is shipped with a [Sample Script](../../working-with-asset-transformer-studio/scripting-with-the-python-api/sample-scripts) called *GenerateUVsFromCADModel.py*, allowing to obtain the result above.

You can also use the following code:

```python
root = scene.getRoot()
algo.repairCAD([root], 0.1)
algo.tessellate([root], 0.2, -1, -1, True, algo.UVGenerationMode.ConformalScaledUV, 0)
algo.createVisibilityInformation([root], 2, 1024, 16, 90, True)
algo.transferVisibilityToPolygonalWeight([root], 2)
algo.mergeUVIslandsAffine([root], 0, 0, 1.2, -1, 1, -1, 0, False, 90)
algo.resizeUVsToTextureSize([1], 100, 0)
```

> **Note:**
>
> Check the [API Reference](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md) for more information about each function used in that script, and adapt it to your need.

### UVs for lightmaps

UVs obtained at tessellation with the **Conformal Scaled UV** method **are not directly suitable for lightmaps**, as they are overlapping and not repacked in the \[0,1] UV space, making lightmap baking impossible.

But UV islands generated are great as they are properly scaled and unstretched. So, they only need a basic repacking to be ready for baking.

The example below shows perfectly repacked UVs:

![Repacked UV islands](/api/media?file=/asset-transformer-studio/2026.5.0/media/Pixyz_UVs_10.jpg)

Here is the code used to obtain the result above: it copies the UVs generated at tessellation for the first channel (0) into the secondary channel, which gets repacked (all parts are repacked in the same UV space in this example):

```python
root = scene.getRoot()
algo.repairCAD([root], 0.1)
algo.tessellate([root], 0.2, -1, -1, True, 2, 0)
algo.copyUV([root], 0, 1)
algo.repackUV([root], 1, True, 1024, 2, False, 3, True)
```

> **Note:**
>
> Check the [API Reference](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md) for more information about [copyUV](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#copyuv) and [repackUV](/asset-transformer-studio/2026.5.0/api/python/algo_functions.md#repackuv).
