3d models with x3dom

I was looking for a way to bring existing 3d models that I’d created in other programs into webpages so that they could be rotated and manipulated without the need for the original software. There are solutions out there but they are not always very helpfully documented, so I thought I’d summarise what I’ve learned so far!

There are two main approaches to 3d graphics for the web, declarative and imperative. Essentially, as far as I understand it, the declarative approach (SVG for 2d, X3Dom for 3d) simply declares the object and lo! it appears, whereas in the imperative approach (canvas for 2d, WebGL for 3d) objects are created via JavaScript functions. Of course the reality and the pros and cons of each approach are clearly more complicated than this, but for a relatively simple model, and where functions are not going to be re-used, the declarative approach is certainly appealing. The crystallographic programs VESTA and KrystalShaper, in which I had created many models, export in the VRML format, which has been superseded by X3D, the language that is used by X3Dom. The 3D modelling program Art of Illusion, in which I had created a small number of models, exports in VRML as well as two other formats, while Blender has a wide variety of import and export formats. The workflow for making the models ready for use in webpages therefore consisted of importing the VRML files in Blender and re-exporting in X3D format, which could be inserted into HTML code with minor modifications. The X3Dom approach involves the use of a JavaScript file and a CSS file. These can either be downloaded and stored in local folders or called directly from the x3dom.org server. There is some sample code on the x3dom.org tutorial page. Documentation for X3Dom exists but there appears to be a pretty steep learning curve between including simple primitives and importing and manipulating complex models built in other programs. Perhaps the expectation is that most of the modelling work will have been done elsewhere. However, from my own experience, the models cannot be used exactly as-imported; instead, they do need some manipulation, and hence some understanding of x3d syntax is necessary. One of the main difficulties I had was finding out which primitives can be used, hence this post! The picture below shows the five primitives: cylinder (yellow), box (red), sphere (blue), plane (green) and cone (magenta). More complex shapes can be specified as “indexed face sets”. The code required to generate the image above is as follows:

<x3d width=”1200px” height=”700px”>
<scene>
<shape>
<appearance>
<material diffusecolor=”1 0 0″></material>
</appearance>
<box></box>
</shape>
<transform translation=”-3 0 0″>
<shape>
<appearance>
<material diffusecolor=”0 1 0″></material>
</appearance>
<plane solid=”false”></plane>
</shape>
</transform>
<transform translation=”3 0 0″>
<shape>
<appearance>
<material diffusecolor=”0 0 1″></material>
</appearance>
<sphere></sphere>
</shape>
</transform>
<transform translation=”0 -3 0″>
<shape>
<appearance>
<material diffusecolor=”1 1 0″></material>
</appearance>
<cylinder></cylinder>
</shape>
</transform>
<transform translation=”0 3 0″>
<shape>
<appearance>
<material diffusecolor=”1 0 1″></material>
</appearance>
<cone></cone>
</shape>
</transform>
</scene>
</x3d>

Note the similarity to HTML and that the ordering of items (“nodes”) is somewhat counterintuitive – we first have to open a tag declaring where an item will be translated to, then open a second tag declaring that a shape is present, then describe its appearance and only then declare what sort of shape it is!

Many aspects, for example the size of the elements and the position of the viewport, are set by default, allowing us to set up an initial scene with very few lines of code and then subsequently to refine it.

Another aspect of note is that, by default, the plane element, as obtained by simply using <plane></plane>, has the property ‘solid=”true”‘. This means that is we rotate to look at the reverse side of the plane, it will no longer be visible. To make the plane visible from both sides, set its property to <plane solid=”false”></plane>.

A  screenshot of one of the crystallographic models exported from VESTA can be seen below:


CSS: Stop menu text breaking across a line

Yesterday I was racking my brains to work out how to deal with this: There are eleven items on this menu and if the window is made too small, English text breaks between words and Japanese text between characters in a single menu item. Although this behaviour is normal in paragraphs, it’s not suitable for menu items so, how to stop it? I eventually found the answer after much searching: white-space: nowrap; (W3schools documentation, Tizag.com tutorial) (I had expected it to have the name word-wrap or text-wrap or something like that…) With this attribute applied to the <li> tag, the menu appears as shown below. Now the word appears on the lower line rather than being broken across two. Hoorah! NB: If applied to large chunks of text, white-space: nowrap; will make the text stick out beyond its containing box unless an overflow: scroll; or overflow: hide; attribute is also used, so white-space: nowrap; is best reserved for small menu items.