Jump to: navigation, search

STEPTools Inc (Troy, NY) has developed a WebGL demonstration of standards-based display of CAD/CAM content over the web. The starting point is a STEP-NC file, conforming to Application Protocol 238 of the STEP standard for manufacturing data. A STEP-NC file contains information for computer aided manufacturing and may contain geometry for the workpiece at stages of the manufacture as well as geometry of the cutting tools, toolpaths, fixtures and machine centers, as well as process data.

The files on this wiki page are taken or derived from the boxy demonstration.

The geometry displayed in the webgl demo is delivered in an XML file ― it is not a standard schema but is a readily understood encoded collection of triangles. This file is downloaded and interpreted by Javascript functions embedded or included in the underlying HTML 5 source. The single boxy.xml file is large and contains all the geometry for the workpieces, cutting tools and fixtures, as well as toolpaths for animated movements of the cutting tools.

The STEP-NC WebGL demonstration does not rely on plug-ins beyond the WebGL capability of the browser. An initial HTML page includes embedded Javascript functions which run when the web document is initialized. The Javascript includes application specific code developed by STEP Tools Inc. as well as WebGL utilities copyrighted by Google. These Javascript functions make an HTTP request back to the server to retrieve the boxy.xml file containing 3D geometry as triangle meshes. The Javascript parses the geometry file and invokes the browser's WebGL functions to render the geometry in an HTML canvas element.

Conventional HTML form controls and Javascript are used to provide user interactivity; allowing selection of which geometry to show, as well as running animation which simulates the machining process.


This is a screenshot of the WebGL demonstration (running on Safari v5.1.2 under MacOS); the red highlight box shows the 'selected' workingstep. The geometry for the workpiece at this stage of machining was identified as being in XML node id="id55130" of the boxy.xml file. The triangle data in the boxy.xml was reformatted into a X3D format file by an XSLT script (see below).

The geometry in the boxy.xml file includes specification of the normal vectors; however it appears that the normals do not consistently point out of the solid body of the workpiece, which causes unsatisfactory rendering on some X3D browsers. For this reason, the conversion to X3D can be done optionally without including the normal geometry data.

It is also possible to use the original STEP-NC file:

  • STEP-NC file This is a Zip archive of a STEP Part 28 (XML encoding) file.

to generate an X3D rendering of the same shape which uses NURBS surfaces to render the shape. This was performed with a unreleased version of the STEP-Prolog software demonstrated at SPRI server.

  • shell55130_nurbs_transpose.x3d Workpiece rendered through NurbsTrimmedSurface, with nurbs parameters transposed for rendering on InstantReality X3d browser.


The automated conversion processes used here do not create X3D Viewpoint nodes in the generated X3D files. For a better user experience these Viewpoints have been manually generated using the X3D-Edit tool and added to these files:

Conversion to X3DOM

The X3D files can be converted to xhtml files which include the X3D content using the X3DOM standard, with the XSLT script X3dToX3dom.xslt. Presently the Javascript implementation of the X3DOM standard does not implement the X3D Nurbs Component, but does support the IndexedTriangleSet node. The result of transforming the shell55130_tri_nonormal_vw.x3d file with this script is

Information flow.002.png

An XSLT script can generate an X3D file from the triangle data in WebGL data. The script used takes two parameters. Using the xsltproc XSLT command line tool, the invocation looks like:

xsltproc  -param "shape" "//shell[@id='id55130']" -param "include-normal" "false()"   convert_to_x3d.xsl boxy.xml > boxy_shell.x3d

XSLT script: convert_to_x3d.xsl

<?xml version="1.0" encoding="utf-8"?>

XSL transformation to generate an X3D file from the xml data used for 
the STEPTools WebGL demo (

This transformation takes two parameters
shape : an XPath expression identifying the nodes in the source XML file which contains
geometry to be converted to X3D

include-normal : enter as true() or false()  whether normal geometry data taken from
source file should be included in X3D geometry

Copyright 2012 Vincent Marchetti

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

<xsl:stylesheet version="1.0" 

<xsl:output method="xml" encoding="utf-8"/>

<xsl:param name="shape"/>
<xsl:param name="include-normal" select="0"/>

<xsl:template match="/">
<X3D xmlns:xsd="" 
    <Background skyColor="0.2 0.5 0.2"/>
    <xsl:apply-templates select="$shape"/>
        <Material containerField="material" diffuseColor="1.000000 1.000000 1.000000"/>

<xsl:template match="shell">
<IndexedTriangleSet containerField="geometry" solid="FALSE">
    <xsl:attribute name="index">
    <xsl:for-each select="facets/f/@v">
        <xsl:for-each select="str:split(normalize-space(.))">
            <xsl:value-of select="number(./text())+0"/><xsl:text> </xsl:text>
    <Coordinate containerField="coord">
    <xsl:attribute name="point">
    <xsl:for-each select="./verts/v/@p">
        <xsl:for-each select="str:split(normalize-space(.))">
            <xsl:value-of select="format-number(number(./text()),'###.####')"/><xsl:text> </xsl:text>

        <xsl:if test="position() < last()">
            <xsl:text>, </xsl:text>
    <xsl:if test="$include-normal"> 
        <Normal containerField="normal">
        <xsl:attribute name="vector">
        <xsl:for-each select="facets/f/@fn">
            <xsl:for-each select="str:split(normalize-space(.))">
                <xsl:value-of select="format-number(number(./text()),'###.####')"/><xsl:text> </xsl:text>
            <xsl:if test="position() < last()">
                <xsl:text>, </xsl:text>