Reducing the filesize of complex 3D .OBJ models


Loading large 3D Models in the browser is extremely resource intensive. 2D images are trivial to resize and resample with negligible loss of perceived quality. 3D resizing is complex.

As part of my "Pirate Museum" I wanted to display 3D scans of statues using WebVR. The only problem is, these files are huge.

Take The Dancing Faun - at full resolution, that's around 230MB. Even on fast broadband that's a pain to download - and even on a fast computer it is slow to render. Once you add several models like that to a scene, everything grinds to a halt.

I wanted a simple way to turn a complex model into something simple - but still recognisable.

On the left you can see the face of the full sized model - on the right is it after being shrunk.

Reducing model complexity.

A surprising level of detail remains - and the filesize is a miniscule 1MB. Small enough for a floppy disk!

To do this, I used MeshLab - the Open Source 3D modelling software. Meshlab has a great GUI - but it can be slow to work with, especially if you're trying to change lots of models at once.

The first step is to create a filter script in the Meshlab GUI. This is what I settled on, a script to reduce any model to 32,000 faces.

<!DOCTYPE FilterScript>
<FilterScript>
 <filter name="Quadric Edge Collapse Decimation">
  <Param type="RichInt" value="32000" name="TargetFaceNum"/>
  <Param type="RichFloat" value="0" name="TargetPerc"/>
  <Param type="RichFloat" value="1" name="QualityThr"/>
  <Param type="RichBool" value="true" name="PreserveBoundary"/>
  <Param type="RichFloat" value="1" name="BoundaryWeight"/>
  <Param type="RichBool" value="true" name="PreserveNormal"/>
  <Param type="RichBool" value="false" name="PreserveTopology"/>
  <Param type="RichBool" value="true" name="OptimalPlacement"/>
  <Param type="RichBool" value="true" name="PlanarQuadric"/>
  <Param type="RichBool" value="false" name="QualityWeight"/>
  <Param type="RichBool" value="true" name="AutoClean"/>
  <Param type="RichBool" value="false" name="Selected"/>
 </filter>
</FilterScript>

The files is then saved as 32k.mlx.

I followed Andrew Hazelden's blog post to run the script using Meshlab server.

meshlabserver -i original.obj -o small.obj -s 32k.mlx

After a few moments - depending on the speed of your kit and size of model - a reduced size version will be spat out.

It is important to note that the MeshLab work only changes the quality of the model - not its apparent size in 3D space.

Models can be permanently scaled using Obj-Magic. For example, to scale a model to be half its physical size, run:
./obj-magic -s 0.5 -o half.obj original.obj

Finally, we have the issue of rotating models in 3D space. Some models are oriented in surprising ways. This can be done with obj-magic if you already know how you want the model to be rotated. I found it easier to use Blender on some of the models to rotate them and re-centre them.

Blender is notoriously complicated - all you need to do is import the .obj. Select it in the right hand panel. Then select the Cube / Object menu. In there you'll find the controls to shrink and rotate the object.

A screen from Blender showing a rotated 3D model

Once done, select "Export" then "Wavefront (.obj)".

So, with that you can easily shrink 3D models to a more compact file size.

You can visit my Pirate Museum to experience the models.

What do you reckon?