Keywords

1 Introduction

Lately, new web technologies in the field of 3D graphics have been developed, such as WebGL [1], “Three.js” [10] and Babylon [4], which are enabling a pervasive cross-browser form of processing and displaying graphical data without most of the portability concerns traditional technologies have, leaving only typical cross-browser API differences as a possible problem. These new technologies have already enabled powerful new tools to be developed [23], and their performance can be fine-tuned to work well both on desktop and mobile platforms [24].

Currently, those visualization technologies are being explored widely and a myriad of examples are available. Many of them are now related to a field that has been gaining attention in the last years: 3D printing.

3D printing, or additive manufacturing, is the process of transforming information contained in a digital three-dimensional object into a physical object. It achieves such feat by extracting horizontal cross-sections of the virtual objects, which are then printed and laid down until the whole object is created [12].

Throughout the last couple of years, 3D printing technology has risen in popularity, even further than what was expected according to experts [2]. This gave spawn to a series of very differentiated applications ranging from manufacturing composite elements [17] to printing biomaterials [15].

However, the file format considered as the de facto standard, STL (Standard Triangulation Language) [19, 21, 22], is falling behind since it is limited in its representational capabilities in regard to the constantly evolving technological scenario. Therefore, new initiatives were founded in order to find a suitable format that can be extended as needed, providing support to emerging technologies, such as AMF (Additive Manufacturing Format) [20] and 3MF (3D Manufacturing Format) [13].

2 ThreeMF Loader

The loader proposed in this work was implemented through the use of the “Three.js” library to parse 3MF files in accordance with the specifications [3]. This section discusses the “Three.js” library and the loader’s architecture.

According to its specification [3], a 3MF file is in fact a zip file that obeys the Open Packaging Conventions [18]. For this work, the main files observed inside the zip are the 3Dmodel.model, which stores 3D models as triangular meshes, and the image textures files, because both contain the core of what is necessary to fully display the 3D model that the 3MF file represents. It is noteworthy that the 3Dmodel.model file is, in fact, an XML file.

2.1 Three.Js

“Three.js” is a lightweight 3D library that simplifies 3D graphics usage inside a browser [10]. It features a simple API and has different options of rendering engines, with the default engines being: HTML5 canvas and SVG elements, CSS3D and WebGL. For the purposes of this work, the WebGL renderer was used together with the HTML5 canvas element, so the models could be rendered to the screen. The following classes were utilized in this work to fully represent a 3MF model:

  • Scene: Manages the rendering of several models on the screen. Each model must be constructed and added to the scene separately by using one of the provided classes in “Three.js”.

  • Geometry: Contains all the information about the objects vertices, faces, colors and texture UVs, and also includes positional information.

  • Face3: Represents a triangle shaped face in space by referencing vertices previously added to a Geometry. As an added bonus, this class also stores which color or texture used.

  • Mesh: Related to Geometry and the Material which will be used to display it.

  • MeshPhongMaterial: The material utilized for this work, defining that the Phong shader will be used to represent the objects after they are loaded.

By utilizing such classes, one can fully describe a triangular mesh, regardless of size, even if such mesh contains more complex information such as color and textures. For a concrete example about the library’s initialization and object construction, please refer to the source code of this project [11], and also to the examples at the “Three.js” website.

2.2 Architecture

For the definition of the loader’s architecture, current loaders at the “Three.js” base code were studied, and a general structure was identified. As a result, a new class called ThreeMFLoader was created as per the needs of the structure.

The primary function of “Three.js” loaders is the load function, which receives a url and returns a model. But, despite having a similar signature, some loaders differed about the function return type, which was defined either as Mesh or Geometry objects depending on the loader. Considering that the function of a loader should not affect how the loaded model is displayed, it was decided that the ThreeMFLoader should just return a Geometry and a list of the accompanying textures, leaving the materials choice to the final user.

Since the 3MF is a zip file, libraries regarding the use of zip files in Javascript had to be found, because no other “Three.js” loader had to deal with a zipped file at the time this work was done. So, the “zip.js” library [14] was chosen as a means to do so, and functions were defined to load the “3Dmodel.model” file and the related texture image files from the 3MF zip file.

However, the “zip.js” library uses Web Workers, which are essentially an implementation of threads in the Javascript environment, implying in the files being extracted from the zip file in an asynchronous manner. A simple synchronization control was then devised through counting all the files that needed to be extracted, and then subtracting such counter by one each time a file was fully extracted.

With all the files available for parsing after extracting, new functions were defined to parse the “3Dmodel.model” file. Given that such file is an XML file, the default Javascript’s DOM parser was utilized to navigate through it, with several new functions being created to modularize each of the XML file nodes concerns.

The root function for XML processing, called processXML, is responsible for separating and storing the information of tags that can later be referenced by other elements, such as the texture2d, colorgroup and texture2dgroup tags.

Besides the processXML function, the parseObjects function can be defined as being fundamental in the parsing process. It extracts all the vertex and triangle tags from an object node and inserts them onto a Geometry as Face3 objects. Each triangle node can also hold a reference to either a colorgroup or a texture2dgroup, and thanks to the pre-processing done by the processXML function, such information is available to be used and inserted in the Face3 object, or inside the Geometry object, as it happens in the UV mappings case.

Most of the functions besides the processXML and parseObjects can be classified as helper functions, since they only take care of simpler details, like extracting the coordinates of a vertex. In such way, they are not discussed here, but are available for consultation at the source code of the project [11].

3 Printing Simulator

In order to validate the loader usefulness in a real web application, a basic 3D printing simulator was implemented. This section will present the basic implementation details of the Simulator, describing the libraries.

3.1 Implementation

After the model is in the appropriate structure, to simulate the additive manufacturing process one has to divide it into layers, effectively slicing it. To achieve slicing, a CSG (Constructive Solid Geometry) library was utilized, namely the “CSG.js” library [6].

The “CSG.js” library implements CSG Boolean operations by using BSP (Binary Space Partitioning) trees, but at the time of implementation of this work it was severely outdated [6]. A suitable updated version was found inside the source code of the OpenJSCad project [8], which enabled the implementation of the slicing feature through the use of CSG’s intersection operation.

Despite being an updated version, the “CSG.js” basic data structures differ from the ones found in “Three.js”, and as such a third component was needed in order to enable interoperability between the libraries; the “ThreeCSG.js” [5] was used to do so. However, the new component was also outdated. Thus, the “ThreeCSG.js” library had to be updated, which presented a need to better understand the “CSG.js” data structures.

Similarly to “Three.js”, “CSG.js” has a set of classes designed to represent 3D models, from which some were selected based on their likeness to “Three.js” data structures. Those are the CSG, Polygon, Vertex and Vector3D classes, described as follows:

  • CSG: Represents a 3D model and contains a list of Polygons. Its chosen counterpart in the “Three.js” library is the Geometry class.

  • Polygon: A 3D polygon represented by a list of vertices. Since it describes a face in the high level CSG object, this class was used to be the equivalent of a Face3 object, despite being more general.

  • Vertex: Represents a single 3D point and can be directly correlated to a “Three.js” vertex.

  • Vector3D: Require for the construction of a CSG Vertex. It represents a vector or a point in 3D space.

After updating the “ThreeCSG.js” library, the objects could be easily con- verted between CSG and Geometry objects, giving “Three.js” full access to the “CSG.js” capabilities. The intersection operation was available to “Three.js” Geometry objects, and a parallelepiped could be defined in a way that slices varying heights by intersecting it with an arbitrary Geometry, given that the parallelepiped has depth and width equal to the geometry (Fig. 1).

Fig. 1.
figure 1

The defined parallelepiped intersecting a tetrahedron.

As result, two functions were defined in a separate file called “3DPrinterSimulator.js”:

  • generateSlices: Receives a mesh and a slice height, and then produces the sliced mesh as Geometry objects.

  • displaySlices: Receives the “Three.js” scene, a list of mesh slices, a delay time and feedback function. It renders each slice in the scene according to the delay set by the user, then executes the feedback function so the user may know that the simulation has ended.

By using such functions, one can effectively simulate the 3D printing process on a “Three.js” geometry by first generating the slices with the desired height, and then displaying them (Fig. 2).

Fig. 2.
figure 2

Intermediary simulation results of the 3D printing process.

4 Results

To confirm the pervasiveness and effectiveness of the technologies utilized, the loading process was tested both on mobile and desktop platforms. This section describes the tests performed in this work, which were executed in four models: Tetrahedron, Rhombicuboctahedron, Dodecahedron chain and Heartgears (Fig. 3).

Fig. 3.
figure 3

Loaded 3MF models.

4.1 File Format Comparison

Although the STL format has been the de facto standard for printing over the past two decades, it is severely limited and fail to address the evolving needs for 3D printing [19, 21, 22]. Some extensions have been proposed, but they were not widely accepted [16, 25]. As a side-effect of the lack of extensions, nowadays the STL file format is only able to save and load simple 3D meshes based on triangles, and has no support for texture, color, and materials. It is important to notice that an STL file can be represented in either ASCII or Binary, with the only difference between them being their file size in bytes, since the Binary format is considerably smaller than the plain ASCII file.

As for the 3MF file format, it proposes to fix some of the STL problems, offering a specification with flexible rules for extensions. In such way, although it still only supports triangular models, it can be easily extended in order to support more complex representations. Additionally, texture, color, and materials are already supported out of the box [3]. It also comes with only one representation, (i.e., a zip file).

An in-depth comparison between file sizes is shown as follows (Table 1), where files containing exactly the same information were compared in order to ascertain which is better suited for web visualization given the file size taken to represent the same object.

Table 1. File format sizes (in KB).

Thus, it can be observed that the size of a 3MF file grows slower than STL files, even the binary one. Also, since the smaller file size makes downloading faster, the 3MF file is better suited for web visualization in regard to file size.

4.2 Loading Time

The file size only affects the download speed of the model; its effect can be nullified if parsing takes too long. Hence, tests gauging was conducted to learn whether the unzipping and parsing of the 3MF file will negate the file size benefits. The tables in sequence (Tables 2, 3, 4 and 5) describe the loading times of the STL and 3MF formats. In the tests, three types of devices were used: PC, smart phone, and tablet. Each model was loaded 100 times on each device, and the average times and their standard deviations were recorded.

Table 2. STL file parsing time (average time in ms).
Table 3. Binary STL file parsing time (average time in ms).
Table 4. 3MF unzipping times (average time in ms).
Table 5. 3MF parsing times (average time in ms).

The devices specifications are listed as follows:

The binary STL file format seems more advantageous in loading times, especially when the 3MF unzipping time is factored in. Nonetheless, it is important to notice that the unzipping time can still be compensated by the smaller file size on larger models, since unzipping files has a relatively short time and is not prone to variations given the users access to a fast Internet connection.

4.3 Loaders Comparison

During the development of this work, one of the objectives was to contribute to the “Three.js” source code by the addition of a 3MF loader. However, a third party loader was submitted before, and a comparison between the one previously submitted (current Three.js’ 3MF loader) [10] and the one developed here was drawn in regards to capabilities and loading times.

As far as capabilities go, the loader present at the “Three.js” code parses some minor tags from 3MF that the loader proposed here does not, such as the metadata tag, which contains information such as the file author, creation date, among others. As for the loader here proposed, it provides support to textures and colors as extra features.

Architecture-wise, it is important to notice that the libraries utilized to unzip files were different. While the proposed loader uses the “zip.js” library, the “Three.js” loader uses the “jszip.js” library [7]. When tested in regards to unzipping time, “jszip.js” proved to be much faster than “zip.js” (Table 6). However, it did not work on the tested phone and tablet, even when changing browsers. The browsers tested were Safari, Chrome, Opera, Firefox and the Native Android Browser.

Table 6. Time taken by each loader to unzip files in PC (average time in ms).

When compared regarding parsing times, the “Three.js” loader also outperformed the one presented in this work (Table 7). By analyzing the parsing functions of each work, it was discovered that the bottleneck of this work’s loader was the need for computing the normals when each face of the geometry was created. In “Three.js” loader, this apparently is already done automatically by the data structures utilized.

Table 7. Time taken by each loader to parse models in PC (average time in ms).

It is important to notice that, during tests, it was discovered that the “Three.js” loader uses a Javascript API called TextDecoder, does not working on all Desktop browsers [9], and by the tests performed, it does not work on mobile devices as well. However, it is a problem that can be fixed, since there are libraries which implement API and give support to such browsers. While there is a loader already in the “Three.js” source code which is more efficient, some opportunities to improve such loader were identified while it was analyzed. It can be further optimized if a different function is used to separate the XML nodes, and support to textures and colors can also be added.

4.4 Printing Simulator Analysis

Since the objective of the final product of the simulation was to run both on mobile and PC, tests were conducted to assert that it could effectively run on those platforms. That is, besides loading and displaying the models, the device where the simulator runs must be able to simulate slicing in a timely fashion, so the user can use it without waiting for results.

In such a way, tests were conducted to determine the speed in which the devices could calculate each slice. Table 8 shows the time it takes for each slice to be computed; each average and standard deviation were taken from 100 samples, except for the Heartgears model which were tested on the mobile devices. For this model, in both phone and tablet, only 10 samples were run due to the long time it took to compute each slice, and the fact that, sometimes, the browser froze while computations were being made.

Table 8. Slicing times (average time in ms).

Given that the most complex models take too long for the slices to be computed, a strategy was devised to minimize such effects. Each slice is only computed once when the application is used, and a cache is established, so if the user so desires, the simulation can be viewed smoothly after its first execution. Nevertheless, the caching strategy did not solve one problem: complex models cannot be easily simulated through the use of the CSG intersection operation, especially on mobile devices which sometimes froze when the simulation was running. This leaves two options for the simulations to be effective on mobile devices: either optimize the used functions, or precompute the simulation and leave it available as a source file that the final user will use without noticing.

From these two options, the latter is considered to be a better option for incrementing this work on the future, given that it would also make the voxelization of the models possible regardless of the time that would take for the simulation to run, and the results would be available in a fast manner both on PC and mobile.

5 Conclusion

The 3MF model file loader and visualizer were successfully developed and validated through the implemented printing simulator. Meanwhile, the tests conducted were important for properly comparing the STL format and the new 3MF format, not only for their capabilities, but also regarding their possible use in a web application.

When considering file sizes and capabilities, the 3MF is better suited because it has improved scalability, extensibility, and support for textures and colors. For instance, the Heartgears binary STL model is 4.6 times bigger than its 3MF counterpart, and it only contains a triangulated model.

Nonetheless, one can argue that, due to greater loading times, the binary STL file is preferable when considering mobile devices, since in worst case it can take approximately 38.6 times more to load a complex 3MF model than it takes to load the same model in binary STL (as the Heartgears model in the tablet). However, the analysis made when comparing our loader versus the “Three.js” loader showed some points where our loader can be substantially optimized, and as such the loading times for the 3MF format can be greatly reduced, effectively nullifying this argument in the future.

As for the mobile uses for the simulator, it is clear that more optimized approaches will be needed in the future, since the gap between mobile and desktop is still enough to make some applications instances, as in the simulator when working with large models, impractical. The tests showed that a model can take up to almost 20 s for just one slice to be produced in mobile, and in some cases the tab simply crashed without the simulation running.

Regarding the open source contributions of this work, the fact that a more efficient loader already exists at the “Three.js” source code does not mean that there will not be any contribution. Support to texture and color can be added to it, and opportunities for improving it were also identified while its code was being analyzed. Therefore, a contribution to the open source community is still possible.