# X3D shape and geometry

Draft

This article or section is currently under construction

In principle, someone is working on it and there should be a better version in a not so distant future.
If you want to modify this page, please discuss it with the person working on it (see the "history")

## Introduction

This short tutorial introduced some basic X3D geometry modeling concepts plus some other concepts that needed to build simple scenes.

Prerequisites: X3D, X3D graphics principles and X3D shape and geometry

In X3D, 3D "things" are defined with shape nodes. Shape nodes can appear under any grouping node (including the Scene node). Usually, a geometry is included under at least a Transform node for positioning, rotation, etc.

A Shape node includes:

• A mandatory geometry node, of which several exist
• An optional (quasi-mandatory) Appearance node which in turn usually includes a Material node for coloring.

Here is an example fragment that would define a red ball with a radius of 0.9 (metres):

``` <Shape>
<!-- A sphere -->
<Appearance>
<Material diffuseColor='0 1 1'/>
</Appearance>
</Shape>
```

X3D includes several kinds of geometry nodes:

1. Simple geometric primitives
2. Points, lines and polygone nodes
3. Geometric 2D nodes
4. Triangle nodes

## Advance topics: translations, color and reuse

In order to play with simple shapes, one ought to know how to position objects, how to color them and how to reuse them.

Finally, it often is useful to import nodes into a scene, either ones made by yourself in X3D or translated from another 3D format and/or found in a 3D repository.

### Inlining

To include another XML scene use the Inline element:

Some example code:

```  <!-- include nice coordinates arrows -->
<Inline url="coordinates.x3d"/>
```

### Translations and color

In order to position geometric shapes we need to use a so-called Transform node and in order to see a node in most clients we need to color it. Below we just introduce a minimal design pattern that you should use and understand before playing with geometry nodes. Otherwise, all your shapes will be in the same location and be rather invisible ...

The translation="2 0 0" attribute of the Transform node allows to position an object in the x,y and z axis. The code below will move the containing object two meters to the right along the x-axis.

The Appearence node allows to add various colors and textures to an objet. In our case we define a simple Material with a diffuseColor of red (RGB value = "1 0 0").

```  <Transform translation='2 0 0'>
<Shape>
<!-- A single geometry node here -->
<Box size="2 2 2"/>
<!-- A simple RGB color for appearence, e.g. a 100% red cube -->
<Appearance>
<Material diffuseColor="1.0 0 0"/>
</Appearance>
</Shape>
</Transform>
```

For more information about so-called grouping nodes (e.g. Transform) read the X3D grouping and transforms tutorial. You also can have a look at X3D appearence.

### DEF and USE

6 spikes made from a DEFed cylinder USEd two times

Often, a defined construct, e.g. a a geometry, a color or a full shape could be reused. In that case we can name it. Some folks argue that any created shape or even any node should have a named since this strategy improves documentation.

All names in X3D must start with letter, followed by letters, numbers and the underscore ("_"). Hyphens ("-") are forbidden like in most programming languages.

DEF names provide a label for any node including child nodes making up that subgraph. It can be seen as the equivalent of ID attributes in XML. In the same way, labels defined with DEF ought be unique.

USE labels reference a DEF node and can only be used after a DEF label was defined.

According to Don Bruzman, There are some conventions that should be used for naming:

• Use CamelCaseNaming
• Capitalize each individual word
• Avoid abbreviations, since none are consistent and they don't help international readers
• strive for clarity, be brief but complete

In addition, he points out, names are imporant since they do no just define a target for reuse, but also describe purpose and functionlity. They strongly influence how one thinks about a thing and provide explanatory documentation.

The following example builds six spikes of a wheel with three cylinders. We define a first cylinder like this:

```<Shape  DEF="Spike" >
<Appearance>
<Material diffuseColor="1.0 0.0 0.0"/>
</Appearance>
</Shape>
```

It then can be used like in the following way. We firstly define a rotation with the Transform node, then USE the spike node as child node inside.

```<Transform  rotation="0.0 0.0 1.0  1.0472">
<Shape  USE="Spike"/>
</Transform>
```

Below is the full source of the inter-rotation-2.x3d example that you can view in a X3D client.

```<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "http://www.web3d.org/specifications/x3d-3.2.dtd">
<X3D profile='Immersive' version='3.2' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.2.xsd'>
<meta name="filename" content="inter-rotation-2.x3d"/>
<meta content='primitives-list.x3d' name='title'/>
<meta content='Simple DEF/USE/Transform Demo' name='description'/>
<meta content='Daniel K. Schneider, TECFA, University of Geneva' name='creator'/>
<meta content='october 4 2010' name='created'/>
<meta content='1.0' name='version'/>
<meta content='http://edutechwiki.unige.ch/en/X3D_shape_and_geometry' name='reference'/>
<meta content='Any X3D client' name='requires'/>
<meta content='http://tecfa.unige.ch/guides/x3d/ex/basics/laurence-name.x3d' name='identifier'/>
<meta content='X3D-Edit, https://savage.nps.edu/X3D-Edit' name='generator'/>

<Scene>
<Shape  DEF="Spike" >
<Appearance>
<Material diffuseColor="1.0 0.0 0.0"/>
</Appearance>
</Shape>
<Transform  rotation="0.0 0.0 1.0  1.0472">
<Shape  USE="Spike"/>
</Transform>
<Transform  rotation="0.0 0.0 1.0  2.0944">
<Shape  USE="Spike"/>
</Transform>

<!-- include nice coordinates arrows -->
<Inline  bboxCenter="0.0 0.0 0.0" bboxSize="10.0 10.0 10.0" url="../common/coordinates.x3d"/>
</Scene>
</X3D>
```

## Geometric primitives

The five geometric primitives are most often used for hand coding, and implementation details (i.e. tessellation/polygon count) is left to the client.

Below is some example code that you can play with.

A HTML5/X3Dom version is here

```<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "http://www.web3d.org/specifications/x3d-3.2.dtd">
<X3D profile='Immersive' version='3.2' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.2.xsd'>
<meta content='primitives-list.x3d' name='title'/>
<meta content='Exhibit of X3D primitive geometry nodes. Each one is positioned and colored differently' name='description'/>
<meta content='Daniel K. Schneider, TECFA, University of Geneva' name='creator'/>
<meta content='october 4 2010' name='created'/>
<meta name='modified'/>
<meta content='1.0' name='version'/>
<meta content='http://edutechwiki.unige.ch/en/X3D_shape_and_geometry' name='reference'/>
<meta content='Any X3D client' name='requires'/>
<meta content='http://tecfa.unige.ch/guides/x3d/ex/basics/primitives-list.x3d' name='identifier'/>
<meta content='X3D-Edit, https://savage.nps.edu/X3D-Edit' name='generator'/>
<Scene>
<!-- Positioning in the x, y, z axis -->
<Transform translation='-4 0 0'>
<Shape>
<!-- A box -->
<Box size='1.8 1.8 1.8'/>
<Appearance>
<Material diffuseColor='1.0 0 0'/>
</Appearance>
</Shape>
</Transform>
<!-- Positioning in the x, y, z axis -->
<Transform translation='-2 0 0'>
<Shape>
<!-- A cone -->
<Appearance>
<Material diffuseColor='1.0 1.0 0'/>
</Appearance>
</Shape>
</Transform>
<!-- Positioning in the x, y, z axis -->
<Transform translation='0 0 0'>
<Shape>
<!-- A solid cylinder -->
<Appearance>
<Material diffuseColor='0 0 1.0'/>
</Appearance>
</Shape>
</Transform>
<!-- Positioning in the x, y, z axis -->
<Transform translation='2 0 0'>
<Shape>
<!-- A sphere -->
<Appearance>
<Material diffuseColor='0 1 1'/>
</Appearance>
</Shape>
</Transform>
<!-- Positioning in the x, y, z axis -->
<Transform translation='3 0 0'>
<Shape>
<!-- Text -->
<Text length='0' maxExtent='5' string='"hello"'/>
<Appearance>
<Material diffuseColor='1.0 0 1.0'/>
</Appearance>
</Shape>
</Transform>
</Scene>
</X3D>
```

The rendered scene may look like this (depending on your viewing position). Try to understand:

• how we defined the dimensions of each object
• (optionally) how we aligned the five objects and how we defined color for each.
An exhibit of primitive geometry nodes

Most of these nodes have additional attributes, e.g. a cylinder can be open. However, all positioning and rotation has to made through a Transform node.

(to be written)

## Point, Line and FaceSets

If you use a modeling tool, it rarely will use X3D primitives, but produce descriptions of shape in terms of either points, lines or faces.

As explained in X3D graphics principles and the OpenScad beginners tutorial, and according to Don Brutzman, graphics software and hardware uses triangle geometry constructs. More complex shapes can always be reduced to triangles by the rendering software (known as tesselation)

Triangles used to defined a polygone are usually arranged in a way that only one side is visible, since that way only one side needs to be computed. By default objects created are only rendered on the outside. Geometry nodes can be parametrized to show the inside by setting solid='false,

• solid='true' means do not render (draw) the inside
• solid='false' means render both inside and outside

Let's have a look at an example that we made with Google sketchup using 2D letters and the extrusion tool. The scene is very simple, i.e. a list of 3D letters.

Example of IndexedTriangleSet (one for each letter)

Below is the wireframe, showing the triangles that compose the letters. As you can see rounded objects need many more triangles

IndexedTriangleSets are very difficult to read as you can see in the following source code. However it is easy to position and scale such imported objects made with 3D modeling tools.

```<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "http://www.web3d.org/specifications/x3d-3.2.dtd">
<X3D profile='Interchange' version='3.2'>
<meta content='primitives-list.x3d' name='title'/>
<meta content='3D letters imported from .dae. Made with Google Sketchup. Illustration of IndexedTraingleSet.
I changed the color to yellow and had to multiply scales by 100 since I was using small units' name='description'/>
<meta content='Daniel K. Schneider, TECFA, University of Geneva' name='creator'/>
<meta content='october 4 2010' name='created'/>
<meta name='modified'/>
<meta content='1.0' name='version'/>
<meta content='http://edutechwiki.unige.ch/en/X3D_shape_and_geometry' name='reference'/>
<meta content='Any X3D client' name='requires'/>
<meta content='http://tecfa.unige.ch/guides/x3d/ex/basics/laurence-name.x3d' name='identifier'/>
<meta content='X3D-Edit, https://savage.nps.edu/X3D-Edit' name='generator'/>
<Scene>
<Transform DEF='COLLADA_UNITS' rotation='-1.0 0.0 0.0 1.570796' scale='2 2 2'>
<Transform>

<Shape>
<Appearance>
<Material DEF='ID3' diffuseColor='1.0 1.0 0.0'></Material>
</Appearance>
<IndexedTriangleSet index='0 1 2 1 0 3 1 3 4 5 2 1 6 7 8 7 6 9 10
11 12 11 10 13 14 15 16 15 14 17 18 19 20 19 18 21 22 23 24 23 22 25
26 27 28 27 26 29 30 31 32 31 30 33 31 33 34 32 31 35'>
<Coordinate DEF='ID5' point='-2.0556674 0.32395512
0.04520603, -1.916368 0.3130246 0.16083883,
-1.7492087 0.32395512 0.04520603, -2.0556674
0.27354917 0.57844514, -1.916368 0.27354917
0.57844514, -1.7492087 0.3130246 0.16083883,
-1.7492087 0.32395512 0.04520603, -2.0556674
-0.6990436 -0.05149582, -2.0556674 0.32395512
0.04520603, -1.7492087 -0.6990436 -0.05149582,
-2.0556674 0.27354917 0.57844514, -2.0556674
-0.6990436 -0.05149582, -2.0556674 -0.74944955
0.48174328, -2.0556674 0.32395512 0.04520603,
-1.916368 -0.74944955 0.48174328, -2.0556674
0.27354917 0.57844514, -2.0556674 -0.74944955
0.48174328, -1.916368 0.27354917 0.57844514,
-1.916368 -0.7099741 0.06413698, -1.916368 0.27354917
0.57844514, -1.916368 -0.74944955 0.48174328,
-1.916368 0.3130246 0.16083883, -1.7492087 -0.7099741
0.06413698, -1.916368 0.3130246 0.16083883, -1.916368
-0.7099741 0.06413698, -1.7492087 0.3130246
0.16083883, -1.7492087 -0.6990436 -0.05149582,
-1.7492087 0.3130246 0.16083883, -1.7492087
-0.7099741 0.06413698, -1.7492087 0.32395512
0.04520603, -2.0556674 -0.6990436 -0.05149582,
-1.916368 -0.7099741 0.06413698, -2.0556674
-0.74944955 0.48174328, -1.7492087 -0.6990436
-0.05149582, -1.7492087 -0.7099741 0.06413698,
-1.916368 -0.74944955 0.48174328'>
</Coordinate>

<Normal DEF='ID6' vector='2.7755576E-17 0.99556196
0.09410831, 2.7755576E-17 0.99556196 0.09410831,
2.7755576E-17 0.99556196 0.09410831, 2.7755576E-17
0.99556196 0.09410831, 2.7755576E-17 0.99556196
0.09410831, 2.7755576E-17 0.99556196 0.09410831,
1.7270247E-17 0.09410831 -0.99556196, 1.7270247E-17
0.09410831 -0.99556196, 1.7270247E-17 0.09410831
-0.99556196, 1.7270247E-17 0.09410831 -0.99556196,
-1.0 2.925767E-17 -1.4581571E-17, -1.0 2.925767E-17
-1.4581571E-17, -1.0 2.925767E-17 -1.4581571E-17,
-1.0 2.925767E-17 -1.4581571E-17, -1.7270247E-17
-0.09410831 0.99556196, -1.7270247E-17 -0.09410831
0.99556196, -1.7270247E-17 -0.09410831 0.99556196,
-1.7270247E-17 -0.09410831 0.99556196, 1.0
-2.925767E-17 1.4581571E-17, 1.0 -2.925767E-17
1.4581571E-17, 1.0 -2.925767E-17 1.4581571E-17, 1.0
-2.925767E-17 1.4581571E-17, -1.7270247E-17
-0.09410831 0.99556196, -1.7270247E-17 -0.09410831
0.99556196, -1.7270247E-17 -0.09410831 0.99556196,
-1.7270247E-17 -0.09410831 0.99556196, 1.0
-2.925767E-17 1.4581571E-17, 1.0 -2.925767E-17
1.4581571E-17, 1.0 -2.925767E-17 1.4581571E-17, 1.0
-2.925767E-17 1.4581571E-17, -2.7755576E-17
-0.99556196 -0.09410831, -2.7755576E-17 -0.99556196
-0.09410831, -2.7755576E-17 -0.99556196 -0.09410831,
-2.7755576E-17 -0.99556196 -0.09410831,
-2.7755576E-17 -0.99556196 -0.09410831,
-2.7755576E-17 -0.99556196 -0.09410831'>
</Normal>
</IndexedTriangleSet>
</Shape>

<Shape>
<Appearance>
<Material USE='ID3'></Material>
</Appearance>
<IndexedTriangleSet index='... deleted ....'>
<Coordinate DEF='ID11' point='.... deleted .....'></Coordinate>
<Normal DEF='ID12' vector=' .... deleted'></Normal>
</IndexedTriangleSet>
</Shape>

<Shape>
<!-- deleted -->
</Shape>
<!-- other shapes deleted -->
</Transform>
</Transform>
</Scene>
</X3D>
```