## Primitive Elements

The primitives of the 3D data structure are VERT, VECT, EDGE, PGON and BODY.
The bodies are represented by their surfaces and the connections between them.
The information to execute a 3D cutaway comes from the connection information.

Indexing starts with 1, and a BASE statement or any new body (implicit BASE statement) resets indices to 1.
For each edge, the indices of the adjacent polygons (maximum 2) are stored.
Edges’ orientations are defined by the two vertices determined first and second.

Polygons are lists of edges with an orientation including the indices of the edges. These numbers can have a negative prefix.
This means that the given edge is used in the opposite direction. Polygons can include holes.
In the list of edges, a zero index indicates a new hole. Holes must not include other holes. One edge may belong to 0 to 2 polygons.
In the case of closed bodies, the polygon’s orientation is correct if the edge has different prefixes in the edge list of the two polygons.

The normal vectors of the polygons are stored separately.
In the case of closed bodies, they point from the inside to the outside of the body.
The orientation of the edge list is counterclockwise (mathematical positive), if you are looking at it from the outside.
The orientation of the holes is opposite to that of the parent polygon. Normal vectors of an open body must point to the same side of the body.

To determine the inside and outside of bodies they must be closed. A simple definition for a closed body is the following:
each edge has exactly two adjacent polygons.

The efficiency of the cutting, hidden line removal or rendering algorithms is lower for open bodies.
Each compound three-dimensional element with regular parameters is a closed body in the internal 3D data structure.

Contour line searching is based on the status bits of edges and on their adjacent polygons.
This is automatically set for compound curved elements but it is up to you to specify these bits correctly in the case of primitive elements.

In the case of a simplified definition (vect = 0 or status < 0 in a PGON) the primitives that are referred to by others must precede
their reference. In this case, the recommended order is:

```VERT (TEVE)
EDGE (VECT)
PGON (PIPG)
COOR
BODY```

Searching for adjacent polygons by the edges is done during the execution of the BODY command.

The numbering of VERTs, EDGEs, VECTs and PGONs is relative to the last (explicit or implicit) BASE statement.
Status values are used to store special information about primitives.
Each single bit usually has an independent meaning in the status, but there are some exceptions.

Given values can be added together. Other bit combinations than the ones given below are strictly reserved for internal use.
The default for each status is zero.

### VERT

`VERT x, y, z`

A node in the x-y-z space, defined by three coordinates.

### VERT{2}

`VERT x, y, z, hard`

Extension of the VERT command including a possibility to declare a node to be hard vertex.
A hard vertex defines a break when rendering smooth surfaces.

`x, y, z: `coordinates of the node.
`hard: `
`1: `if the vertex should define a break when rendering smooth surfaces
`0: `otherwise

### TEVE

`TEVE x, y, z, u, v`

Extension of the VERT command including a texture coordinate definition.
Can be used instead of the VERT command if user-defined texture coordinates are required
instead of the automatic texture wrapping ().

`x, y, z: `coordinates of a node.

`u, v: `texture coordinates of the node (u, v)
Coordinates for each vertex of the current body must be specified and each vertex should have only one texture coordinate.
If VERT and TEVE statements are mixed inside a body definition, (u, v) coordinates are ineffective.
Note: The (u, v) texture coordinates are only effective in photorenderings, and not for vectorial fill mapping.

### VECT

`VECT x, y, z`

Definition of the normal vector of a polygon by three coordinates.
In case of a simplified definition (vect=0 in a PGON), these statements can be omitted.

### EDGE

`EDGE vert1, vert2, pgon1, pgon2, status`

Definition of an edge.
`vert1, vert2: `index of the endpoints. The vert1 and vert2 indices must be different and referenced to previously defined VERTs.
`pgon1, pgon2: `indices of the neighboring polygons. Zero and negative values have special meanings:
`0: `terminal or standalone edge,
`< 0: `possible neighbors will be searched for,
`status: `Status bits:<
`status = j1 + 2*j2 + 4*j3 + 8*j4 + 16*j5 + 32*j6 + 64*j7 + 262144*j19`, where each j can be 0 or 1.
`j1: `invisible edge,
`j2: `edge of a curved surface.
Reserved status bits for future use:
`j3: `first edge of a curved surface (effective only when j2=1),
`j4: `last edge of a curved surface (effective only when j2=1),
`j5: `the edge is an arc segment,
`j6: `first segment of an arc (effective only when j4=1),
`j7: `last segment of an arc (effective only when j4=1),
`j19: `render sharp edge between 2 curved polygons (effective only when j2=1).

### PGON

`PGON n, vect, status, edge1, edge2, ..., edgen`

Polygon definition.
`n: `number of edges in the edge list.
`vect: `index of the normal vector. It must refer to a previously defined VECT.
Note: If vect = 0, the program will calculate the normal vector during the analysis.
`edge1, edge2, ..., edgen: `
these indices must refer to previously defined EDGEs.
A zero value means the beginning or the end of a hole definition.
A negative index changes the direction of the stored normal vector or edge to the opposite in the polygon.
(The stored vector or edge does not change; other polygons can refer to it using the original orientation with a positive index.)
`status: `Status bits:
`status = j1 + 2*j2 + 16*j5 + 32*j6 + 64*j7 + 4*j3 + 8*j4`, where each j can be 0 or 1.
`j1: `invisible polygon,
`j2: `polygon of a curved surface,
`j5: `concave polygon,
`j6: `polygon with hole(s),
`j7: `hole(s) are convex (effective only when j6=1),
Reserved status bits for future use:
`j3: `first polygon of a curved surface (effective only when j2=1),
`j4: `last polygon of a curved surface (effective only when j2=1).

If the status value is negative, the engine will calculate the status of the polygon (like concave polygon or polygon with hole).
n = 0 is allowed for special purposes.

### PGON{2}

`PGON{2} n, vect, status, wrap, edge_or_wrap1, ..., edge_or_wrapn`

The first three parameters are similar to the ones at the PGON command.
`wrap: `wrapping mode + projection type.
`0: `the global wrapping mode is applied,
`> 0: `the meaning is the same as it is in the COOR command.
`edge_or_wrap1, ..., edge_or_wrapn: `The number and meaning of these parameters are based on the wrap definition:
`edge1, ..., edgen: `
if wrap is 0; in this case `edgen` means the same as at the PGON command,
and globally defined texture mapping will be applied;
`x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, edge1, ..., edgen: `
if wrapping mode isn’t 0 in wrap;
in this case `xi, yi, zi` coordinates defining the coordinate system of the texture mapping for the polygon;
`edge1, u1, v1, ..., edgen, un, vn: `
if wrapping mode is 0 but projection type isn’t 0 in wrap;
in this case `ui, vi` texture space coordinates are the same as at the TEVE command; the mapping will affect the currently defined polygon only.

### PGON{3}

`PGON{3} n, vect, status, wrap_method, wrap_flags, edge_or_wrap1, ..., edge_or_wrapn`

The parameters are similar to the the PGON{2} command, except `wrap`, which is split into two parameters `wrap_method` and `wrap_flags`. The meaning of these is the same as in the COOR{2} command.

### PIPG

```PIPG expression, a, b, mask, n, vect, status,
edge1, edge2, ..., edgen```

Picture polygon definition.
The first four parameters are the same as in the PICTURE command; the remaining ones are the same as in the PGON command.

### COOR

Compatibility: deprecated since ARCHICAD 20.

`COOR wrap, vert1, vert2, vert3, vert4`

Local coordinate system of a BODY for the fill and texture mapping.
`wrap: `wrapping mode + projection type
`Wrapping modes: `
`1: `planar box (deprecated),
`2: `box,
`3: `cylindrical,
`4: `spherical,
`5: `same as the cylindrical fill mapping, but in rendering the top and the bottom surface will get a circular mapping,
`6: `planar,
`7: `NURBS based, the vertices’ texture coordinates are from their surface parameters, only in case of NURBS bodies.
`Projection types: `
`256: `the fill always starts at the origin of the local coordinate system,
`1024: `quadratic texture projection (recommended),
`2048: `linear texture projection based on the average distance,
`4096: `linear texture projection based on normal triangulation.

Note: The last three values are only effective with custom texture coordinate definitions ().

`vert1: `index of a VERT, representing the origin of the local coordinate system.
`vert2, vert3, vert4: `indices of VERTs defining the three coordinate axes.

Use a minus sign (-) before VERT indices if they are used only for defining the local coordinate system.

Example:
For custom texture axes:

```CSLAB_ "Brick-White", "Brick-White", "Brick-White",
4, 0.5,
0, 0, 0, 15,
1, 0, 0, 15,
1, 1, 1, 15,
0, 1, 1, 15
BASE
VERT 1, 0, 0 !#1
VERT 1, 1, 1 !#2
VERT 0, 0, 0 !#3
VERT 1, 0, 1 !#4
COOR 2, -1, -2, -3, -4
BODY 1```

### COOR{2}

Compatibility: deprecated since ARCHICAD 20.

`COOR{2} wrap_method, wrap_flags, vert1, vert2, vert3, vert4`

Similar to the COOR command, changing `wrap` to two parameters `wrap_method` and `wrap_flags`, and also extending the possibilities of it.

`wrap_method: `Wrapping modes are the same as described in the the COOR command. Projection types don’t apply, use `wrap_flags` instead.

`wrap_flags: `Wrapping flags
`wrap_flags = 4*j3 + 8*j4 + 16*j5 + 32*j6 + 64*j7 + 128*j8`, where each j can be 0 or 1.
`j3: `quadratic texture projection (recommended),
`j4: `linear texture projection based on the average distance,
`j5: `linear texture projection based on normal triangulation,
`j8: `translate the origin of the texture coordinate system closest to the global origin in the direction of the X, Y or Z axis respectively. For example, `j6` makes the origin translating in the direction of the X axis (along `v2 - v1` vector) so that it will be the orthogonal projection of the global origin to the line of the X axis. That is, if all `j6`, `j7` and `j8` are `1`, the origin is translated into the global origin (same as if projection type is `256` in the the COOR command).

Note: The `j3`, `j4` and `j5` flags are only effective if `wrap_method` is `0` and only one of them can be `1`. The `j6`, `j7` and `j8` flags are only effective if `wrap_method` is not `0`. These can be `1` at the same time in any combination.

`vert1, vert2, vert3, vert4: `like in the COOR command.

### COOR{3}

Compatibility: introduced in ARCHICAD 20.

```COOR{3} wrapping_method, wrap_flags,
origin_X, origin_Y, origin_Z,
endOfX_X, endOfX_Y, endOfX_Z,
endOfY_X, endOfY_Y, endOfY_Z,
endOfZ_X, endOfZ_Y, endOfZ_Z```

Similar to the COOR{2} command. Can be used with array parameter input (see WALL_TEXTURE_WRAP for more).
The coordinate system of the projection body is included in the COOR{3} command itself, no need to define additional vertexes in the current BODY.
Compatible with NURBS bodies (no non-NURBS primitives are needed to set up the texture coordinate system).

`wrap_method: `Wrapping modes are the same as described in the the COOR command, supplemented by NURBS based wrapping mode. Projection types don’t apply, use `wrap_flags` instead.
`1: `planar box (deprecated),
`2: `box,
`3: `cylindrical,
`4: `spherical,
`5: `same as the cylindrical fill mapping, but in rendering the top and the bottom surface will get a circular mapping,
`6: `planar,
`7: `NURBS based, the vertices’ texture coordinates are from their surface parameters, only in case of NURBS bodies.

`wrap_flags: `Wrapping flags

`wrap_flags = 4*j3 + 8*j4 + 16*j5 + 32*j6 + 64*j7 + 128*j8`, where each j can be 0 or 1.
`j3: `quadratic texture projection (recommended),
`j4: `linear texture projection based on the average distance,
`j5: `linear texture projection based on normal triangulation,
`j8: `translate the origin of the texture coordinate system closest to the global origin in the direction of the X, Y or Z axis respectively. For example, `j6` makes the origin translating in the direction of the X axis so that it will be the orthogonal projection of the global origin to the line of the X axis. That is, if all `j6`, `j7` and `j8` are `1`, the origin is translated into the global origin (opposite effect of projection type `256` in the COOR command).
Note: the `j3`, `j4` and `j5` flags are only effective if `wrap_method` is `0` and only one of them can be `1`. The `j6`, `j7` and `j8` flags are only effective if `wrap_method` is not `0`. These can be `1` at the same time in any combination.

`origin_X, origin_Y, origin_Z: `node in the x-y-z space, defined by three coordinates, texture origin.
`endOfX_X, endOfX_Y, endOfX_Z: `node in the x-y-z space, defined by three coordinates, texture mapping X direction.
`endOfY_X, endOfY_Y, endOfY_Z: `node in the x-y-z space, defined by three coordinates, texture mapping Y direction.
`endOfZ_X, endOfZ_Y, endOfZ_Z: `node in the x-y-z space, defined by three coordinates, texture mapping Z direction.

Example: COOR{3} and equivalent COOR{2} parametrisation:

```COOR{3} wrapping_method, wrap_flags,
origin_X, origin_Y, origin_Z,
endOfX_X, endOfX_Y, endOfX_Z,
endOfY_X, endOfY_Y, endOfY_Z,
endOfZ_X, endOfZ_Y, endOfZ_Z

! COOR{2} equivalent
BASE
VERT    origin_X, origin_Y, origin_Z,
VERT    endOfX_X, endOfX_Y, endOfX_Z
VERT    endOfY_X, endOfY_Y, endOfY_Z
VERT    endOfZ_X, endOfZ_Y, endOfZ_Z
COOR{2} wrapping_method, wrap_flags, -1, -2, -3, -4
```

### BODY

`BODY status`

Composes a body defined with the above primitives.

`status: `Status bits:`status = j1 + 2*j2 + 4*j3 + 32*j6 + 64*j7`, where each j can be 0 or 1.

`j1: `closed body (deprecated),
`j2: `body including curved surface(s) (deprecated),
`j3: `surface model: when the body is cut, no surface originates on the cutting plane,
`j6: `body always casts shadow independently from automatic preselection algorithm,
`j7: `body never casts shadow.

If neither j6 nor j7 are set, the automatic shadow preselection is performed.

If the status value is negative, the engine will calculate the status of the body.

Example:

1: Complete description

```VERT 0.0, 0.0, 0.0    !#1
VERT 1.0, 0.0, 0.0    !#2
VERT 1.0, 1.0, 0.0    !#3
VERT 0.0, 1.0, 0.0    !#4
VERT 0.0, 0.0, 1.0    !#5
VERT 1.0, 0.0, 1.0    !#6
VERT 1.0, 1.0, 1.0    !#7
VERT 0.0, 1.0, 1.0    !#8
EDGE 1, 2, 1, 3, 0    !#1
EDGE 2, 3, 1, 4, 0    !#2
EDGE 3, 4, 1, 5, 0    !#3
EDGE 4, 1, 1, 6, 0    !#4
EDGE 5, 6, 2, 3, 0    !#5
EDGE 6, 7, 2, 4, 0    !#6
EDGE 7, 8, 2, 5, 0    !#7
EDGE 8, 5, 2, 6, 0    !#8
EDGE 1, 5, 6, 3, 0    !#9
EDGE 2, 6, 3, 4, 0    !#10
EDGE 3, 7, 4, 5, 0    !#11
EDGE 4, 8, 5, 6, 0    !#12
VECT 1.0, 0.0, 0.0    !#1
VECT 0.0, 1.0, 0.0    !#2
VECT 0.0, 0.0, 1.0    !#3
PGON 4, -3, 0, -1, -4, -3, -2    !#1    !VERT1,2,3,4
PGON 4, 3, 0, 5, 6, 7, 8         !#2    !VERT5,6,7,8
PGON 4, -2, 0, 1, 10, -5, -9     !#3    !VERT1,2,5,6
PGON 4, 1, 0, 2, 11, -6, -10     !#4    !VERT2,3,6,7
PGON 4, 2, 0, 3, 12, -7, -11     !#5    !VERT3,4,7,8
PGON 4, -1, 0, 4, 9, -8, -12     !#6    !VERT1,4,5,8
BODY 1                                  !CUBE```

2: (no direct reference to the polygons or the vectors, they will be calculated)

```VERT 0.0, 0.0, 0.0     !#1
VERT 1.0, 0.0, 0.0     !#2
VERT 1.0, 1.0, 0.0     !#3
VERT 0.0, 1.0, 0.0     !#4
VERT 0.0, 0.0, 1.0     !#5
VERT 1.0, 0.0, 1.0     !#6
VERT 1.0, 1.0, 1.0     !#7
VERT 0.0, 1.0, 1.0     !#8
EDGE 1, 2, -1, -1, 0   !#1
EDGE 2, 3, -1, -1, 0   !#2
EDGE 3, 4, -1, -1, 0   !#3
EDGE 4, 1, -1, -1, 0   !#4
EDGE 5, 6, -1, -1, 0   !#5
EDGE 6, 7, -1, -1, 0   !#6
EDGE 7, 8, -1, -1, 0   !#7
EDGE 8, 5, -1, -1, 0   !#8
EDGE 1, 5, -1, -1, 0   !#9
EDGE 2, 6, -1, -1, 0   !#10
EDGE 3, 7, -1, -1, 0   !#11
EDGE 4, 8, -1, -1, 0   !#12
PGON 4, 0, -1, -1, -4, -3, -2   !#1
!VERT1,2,3,4
PGON 4, 0, -1, 5, 6, 7, 8       !#2
!VERT5,6,7,8
PGON 4, 0, -1, 1, 10, -5, -9    !#3
!VERT1,2,5,6
PGON 4, 0, -1, 2, 11, -6, -10   !#4
!VERT2,3,6,7
PGON 4, 0, -1, 3, 12, -7, -11   !#5
!VERT3,4,7,8
PGON 4, 0, -1, 4, 9, -8, -12    !#6
!VERT1,4,5,8
BODY -1                               !CUBE```

### BASE

`BASE`

Resets counters for low-level geometric elements (VERT, TEVE, VECT, EDGE, PGON and PIPG) statements.
Implicitly issued after every compound element definition.