# Ifc Syntax Geometry Tessellation

> Use when you need to author, read, or debug tessellated (faceted) geometry in an IFC4 or IFC4.3 model : triangle meshes and polygon meshes built from a shared indexed point pool, the lightweight geometry that the Reference View MVD relies on. Prevents the tessellation errors that break meshes : 0-based instead of 1-based indices, a triangle row with the wrong number of indices, a PnIndex indirection applied twice, a Closed flag that lies about whether the mesh is a solid, and using tessellation entities in an IFC2x3 file where they do not exist. Covers IfcCartesianPointList3D and IfcCartesianPointList2D, IfcTessellatedFaceSet, IfcTriangulatedFaceSet (Coordinates, Normals, Closed, CoordIndex, PnIndex), IfcPolygonalFaceSet, IfcIndexedPolygonalFace, IfcIndexedPolygonalFaceWithVoids, the PnIndex indirection layer, the RepresentationType Tessellation mapping, and the IFC4 / IFC4.3 version differences. Keywords: IFC tessellation, IfcTriangulatedFaceSet, IfcPolygonalFaceSet, IfcTessellatedFaceSet, IfcCartesianPointL

- Skill: `impertio-studio/ifc-syntax-geometry-tessellation` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/ifc-syntax-geometry-tessellation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/ifc-syntax-geometry-tessellation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/ifc-syntax-geometry-tessellation

---


# IFC Syntax : Geometry Tessellation

Tessellation is faceted geometry : a mesh of flat triangles or polygons. It was
**introduced in IFC4** and is the geometric backbone of the Reference View MVD,
because a consuming application can render a mesh with almost no implementation
effort. IFC2x3 has no tessellation entities : its faceted equivalent is
`IfcFacetedBrep`.

The design is index-based : one shared **point pool** holds every vertex once, and
every face is a short list of integer **indices** into that pool. This makes a
tessellated model far more compact than thousands of repeated point instances.

This skill covers IFC4 and IFC4.3. The differences between those two versions are
small and listed in the Version Differences section.

## Quick Reference

### The indexed model

```
IfcCartesianPointList3D      the point pool : every vertex, once
        ^
        | Coordinates
IfcTriangulatedFaceSet       faces as integer-index rows into the pool
   or IfcPolygonalFaceSet
        ^
        | Items
IfcShapeRepresentation       RepresentationType = 'Tessellation'
```

ALWAYS store every vertex once in the point pool and reference it by index. NEVER
repeat coordinate values per face : the index model exists to avoid that.

### IfcCartesianPointList3D : the point pool

Verified verbatim (IFC4.3) :

```
ENTITY IfcCartesianPointList3D
 SUBTYPE OF (IfcCartesianPointList);
	CoordList : LIST [1:?] OF LIST [3:3] OF IfcLengthMeasure;
	TagList : OPTIONAL LIST [1:?] OF IfcLabel;
END_ENTITY;
```

- `CoordList` is an ordered list of points ; each point is exactly three
  `IfcLengthMeasure` values. Point **N** is `CoordList[N]`, indexed from **1**.
- `TagList` (optional) carries one `IfcLabel` per point. It is an **IFC4.3
  addition** : in IFC4 the entity has only `CoordList`.
- `IfcCartesianPointList2D` is the 2D analogue (`LIST [2:2]` points). A tessellated
  face set always uses the **3D** list ; the 2D list serves 2D index geometry such
  as `IfcIndexedPolyCurve`.

### IfcTessellatedFaceSet : the abstract supertype

Verified verbatim (IFC4.3) :

```
ENTITY IfcTessellatedFaceSet
 ABSTRACT SUPERTYPE OF (ONEOF
	(IfcPolygonalFaceSet
	,IfcTriangulatedFaceSet))
 SUBTYPE OF (IfcTessellatedItem);
	Coordinates : IfcCartesianPointList3D;
 DERIVE
	Dim : IfcDimensionCount := 3;
 INVERSE
	HasColours : SET [0:1] OF IfcIndexedColourMap FOR MappedTo;
	HasTextures : SET [0:?] OF IfcIndexedTextureMap FOR MappedTo;
END_ENTITY;
```

- `Coordinates` is the shared `IfcCartesianPointList3D` point pool.
- `Dim` is DERIVED and always `3` : a tessellated face set is always 3D.
- `IfcTessellatedFaceSet` is **abstract** : NEVER instantiate it. Use
  `IfcTriangulatedFaceSet` or `IfcPolygonalFaceSet`.

### IfcTriangulatedFaceSet : a triangle mesh

Verified verbatim (IFC4.3) :

```
ENTITY IfcTriangulatedFaceSet
 SUPERTYPE OF (ONEOF
	(IfcTriangulatedIrregularNetwork))
 SUBTYPE OF (IfcTessellatedFaceSet);
	Normals : OPTIONAL LIST [1:?] OF LIST [3:3] OF IfcParameterValue;
	Closed : OPTIONAL IfcBoolean;
	CoordIndex : LIST [1:?] OF LIST [3:3] OF IfcPositiveInteger;
	PnIndex : OPTIONAL LIST [1:?] OF IfcPositiveInteger;
 DERIVE
	NumberOfTriangles : IfcInteger := SIZEOF(CoordIndex);
END_ENTITY;
```

- `CoordIndex` is the triangle list : every row is **exactly three**
  `IfcPositiveInteger` indices. Each index resolves a vertex (directly into
  `Coordinates`, or through `PnIndex` when that is present).
- `Normals` (optional) carries per-vertex normals for smooth shading.
- `Closed` : `TRUE` means the mesh forms a closed solid shell ; `FALSE` or omitted
  means an open surface.
- `PnIndex` (optional) is the indirection layer : see below.
- `IfcTriangulatedIrregularNetwork` (a terrain TIN subtype) is an **IFC4.3
  addition** : IFC4 `IfcTriangulatedFaceSet` has no subtype.

### IfcPolygonalFaceSet : a polygon mesh

Verified verbatim (IFC4.3) :

```
ENTITY IfcPolygonalFaceSet
 SUBTYPE OF (IfcTessellatedFaceSet);
	Closed : OPTIONAL IfcBoolean;
	Faces : LIST [1:?] OF UNIQUE IfcIndexedPolygonalFace;
	PnIndex : OPTIONAL LIST [1:?] OF IfcPositiveInteger;
END_ENTITY;
```

Each entry in `Faces` is an `IfcIndexedPolygonalFace`, which may have any number of
vertices (3 or more), not just three.

```
ENTITY IfcIndexedPolygonalFace
 SUPERTYPE OF (ONEOF
	(IfcIndexedPolygonalFaceWithVoids))
 SUBTYPE OF (IfcTessellatedItem);
	CoordIndex : LIST [3:?] OF IfcPositiveInteger;
END_ENTITY;
```

```
ENTITY IfcIndexedPolygonalFaceWithVoids
 SUBTYPE OF (IfcIndexedPolygonalFace);
	InnerCoordIndices : LIST [1:?] OF LIST [3:?] OF UNIQUE IfcPositiveInteger;
END_ENTITY;
```

- `IfcIndexedPolygonalFace.CoordIndex` is the outer loop : 3 or more indices.
- `IfcIndexedPolygonalFaceWithVoids` adds `InnerCoordIndices` : one index loop per
  hole. ALWAYS use it for a face with a hole ; NEVER cut a hole by reusing the plain
  `IfcIndexedPolygonalFace`.

### PnIndex : the indirection layer

When `PnIndex` is **absent**, a `CoordIndex` value is a direct 1-based index into
`Coordinates.CoordList`.

When `PnIndex` is **present**, a `CoordIndex` value indexes into `PnIndex`, and the
`PnIndex` value then indexes into `Coordinates.CoordList` :

```
without PnIndex :  CoordIndex value  ----------------------> CoordList[value]
with    PnIndex :  CoordIndex value -> PnIndex[value] ------> CoordList[ PnIndex[value] ]
```

`PnIndex` lets several face sets share one coordinate pool, or compresses a model
where many faces reuse a small set of points. ALWAYS apply the indirection exactly
once when `PnIndex` is present. NEVER apply it when `PnIndex` is absent.

### Mapping to a representation

A tessellated face set is a `IfcRepresentationItem` placed in an
`IfcShapeRepresentation` whose `RepresentationType` is `'Tessellation'` and whose
`RepresentationIdentifier` is normally `'Body'`. See
`ifc-syntax-geometry-representations`.

### Version differences (compact)

| Item | IFC2x3 | IFC4 | IFC4.3 |
|------|--------|------|--------|
| Tessellation entities | absent | present | present |
| `IfcCartesianPointList3D.TagList` | n/a | absent | present |
| `IfcCartesianPointList2D.TagList` | n/a | absent | present |
| `IfcTriangulatedIrregularNetwork` | n/a | absent | present |
| `CoordIndex` / `PnIndex` / `Normals` / `Closed` semantics | n/a | identical | identical |

In IFC2x3 the faceted equivalent is `IfcFacetedBrep` with `IfcPolyLoop` faces : see
`ifc-syntax-geometry-representations` and the Brep skill.

## Decision Trees

### Triangulated or polygonal face set?

```
Is every face a triangle?
|
+-- YES --> IfcTriangulatedFaceSet. CoordIndex rows are LIST [3:3] : always 3.
|           Cheapest to render ; the Reference View default mesh form.
|
+-- NO, faces have varying vertex counts, or some faces have holes
    --> IfcPolygonalFaceSet with IfcIndexedPolygonalFace entries.
        A face with a hole --> IfcIndexedPolygonalFaceWithVoids.
```

### Do you need PnIndex?

```
Does CoordIndex index straight into the point pool?
|
+-- YES, one face set, no shared pool, no compression
|   --> omit PnIndex. CoordIndex values index Coordinates.CoordList directly.
|
+-- NO, several face sets share one pool, or you compress repeated points
    --> include PnIndex. CoordIndex -> PnIndex -> CoordList. Apply once.
```

### Tessellation or Brep?

```
Which schema is the file?
|
+-- IFC4 or IFC4.3 --> tessellation (IfcTriangulatedFaceSet / IfcPolygonalFaceSet).
|
+-- IFC2x3 --> tessellation does NOT exist. Use IfcFacetedBrep with IfcPolyLoop.
```

## Patterns

### Pattern : Build a triangulated face set

ALWAYS store every vertex once in an `IfcCartesianPointList3D` and list each triangle
as a three-index row in `CoordIndex`.
ALWAYS use **1-based** indices : index `1` is the first point in `CoordList`. IFC
index lists are `IfcPositiveInteger` and start at 1.
NEVER write a `CoordIndex` row with two or four indices : the type is `LIST [3:3]`,
exactly three per triangle.

### Pattern : Build a polygonal face set with a hole

ALWAYS model a multi-sided face as an `IfcIndexedPolygonalFace` whose `CoordIndex`
lists the outer loop (3 or more indices).
ALWAYS model a face that has a hole as an `IfcIndexedPolygonalFaceWithVoids` : the
outer loop in `CoordIndex`, each hole as one loop in `InnerCoordIndices`.
NEVER represent a hole by connecting the outer and inner loops with a bridge edge in
a plain `IfcIndexedPolygonalFace` : that is a Brep workaround, not the tessellation
model.

### Pattern : Apply PnIndex correctly

ALWAYS check whether `PnIndex` is present before resolving a `CoordIndex` value.
ALWAYS resolve through one indirection when `PnIndex` is present :
`CoordList[ PnIndex[ CoordIndex_value ] ]`.
NEVER apply `PnIndex` when it is absent, and NEVER apply it twice : a double
indirection scrambles the mesh.

### Pattern : Set Closed honestly

ALWAYS set `Closed = .T.` only when the mesh is a watertight, closed solid shell.
ALWAYS set `Closed = .F.` or omit it for an open surface (a single panel, a terrain
patch).
NEVER set `Closed = .T.` on an open surface : a consumer that trusts the flag will
compute a wrong volume or attempt invalid solid operations.

### Pattern : Place tessellation in a representation

ALWAYS put a tessellated face set into an `IfcShapeRepresentation` with
`RepresentationType = 'Tessellation'` and, for a solid body,
`RepresentationIdentifier = 'Body'`.
NEVER label a tessellated representation `'SweptSolid'` or `'Brep'` : the
`RepresentationType` MUST match the geometry kind so consumers dispatch correctly.

### Pattern : Honour the version differences

ALWAYS target IFC4 or IFC4.3 for tessellation : NEVER write `IfcTriangulatedFaceSet`
or `IfcPolygonalFaceSet` in an IFC2x3 file, where the entities do not exist.
ALWAYS write `IfcCartesianPointList3D` with only `CoordList` for an IFC4 file ; add
`TagList` only when the target is IFC4.3.
NEVER write `IfcTriangulatedIrregularNetwork` in an IFC4 file : that subtype is an
IFC4.3 addition.

## Reference Links

- `references/methods.md` : the complete verified entity definitions for the point
  lists and every tessellated face set entity, the `PnIndex` resolution algorithm,
  index-base and winding rules, and the per-version difference matrix.
- `references/examples.md` : worked STEP scenarios : a triangulated cube, a polygonal
  face set, a face with a void, a `PnIndex` shared pool, and the enclosing
  `IfcShapeRepresentation`.
- `references/anti-patterns.md` : the tessellation failure modes this skill prevents,
  each with the reason it fails.

### Official sources

- IfcTessellatedFaceSet : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcTessellatedFaceSet.htm
- IfcTriangulatedFaceSet : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcTriangulatedFaceSet.htm
- IfcPolygonalFaceSet : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcPolygonalFaceSet.htm
- IfcIndexedPolygonalFace : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcIndexedPolygonalFace.htm
- IfcIndexedPolygonalFaceWithVoids : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcIndexedPolygonalFaceWithVoids.htm
- IfcCartesianPointList : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcCartesianPointList.htm
- IfcCartesianPointList3D : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcCartesianPointList3D.htm
- IfcCartesianPointList2D : https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcCartesianPointList2D.htm

### Related skills

- `ifc-syntax-geometry-representations` : `IfcShapeRepresentation`,
  `RepresentationType` values, and the representation context.
- `ifc-core-mvd` : the Reference View, whose mesh geometry is tessellation-based.

