Wednesday, 13 May 2020

Cleaning up your act - how a round trip through blender can improve your mesh

Those familiar with my blog may recall that our journey together through the art/accident of mesh making began with, and often returns to prim2mesh tools such as Mesh Studio (MS). During a period of particularly poor reliability from the Mesh Studio servers, in 2016, I made a blog post and video explaining how some of the optimisations achieved by Mesh Studio, could, with a little knowledge, be replicated in Blender.

That was a long time ago now, Blender has moved on and while MS remains perfectly adequate for many users, the loyal Mesh Studio user base has been challenged once again by instability and uncertainty. There is no suggestion that the product is anything other than the victim of circumstances ( and a pernicious bug) but it seems appropriate to update the "fallback plan" tutorial(s)

What are we going to learn today?

For this first "tutorial" we will look at the basics. After a quick reminder of what MS and similar tools do for us, we'll look at exporting to Blender, an initial cleanup, and then re-exporting.

What is a Prim2Mesh tool and why do I need it?

Let's have a quick recap on what it is that Mesh Studio and similar products do for us. Prim to mesh tools are typically used by builders/creators who wish to work inside Second Life, and/or who lack the skills required to create mesh in an external tool. They provide a convenient interim solution bridging the gap between the simple (but powerful) prim building in Second Life and the complex and frequently daunting Mesh creation tools such as Blender, Maya and 3DS Max. I will focus here on Mesh Studio but for the most part the same applies to similar products.

With Mesh Studio, the user is free to create their object using any prims that they like, this includes pretty-much any slices, twists and other tortures. Once the user has their model built (and ideally) textured, they simply drop in a script and use a menu-driven interface to analyse the prims and produce a mesh. The product is composed of two parts, an in-world scripted system that sends a detailed description of the linksets to an off-world server via a web  API. The Mesh itself is constructed on this external server and provided as a zip file containing the Collada (DAE) model ready to be uploaded into Second Life. Herein lies the Achilles heel of these solutions; any tool that depends on an external service is beholden to the operator of that service.

The menus and other scripts allow some pretty sophisticated constructions. In fact, the entire crystal palace exhibition glasshouse, a recreation of the original Hyde Park crystal palace from the late 19th Century, was created entirely using Mesh Studio by Vic Mornington, a long-term New Babbage resident and Mesh Studio connoisseur.

Full size :

The key features that Mesh to prim tools include are:-
1) some control over the mesh complexity (how many edges make up a curve or straight-edge
2) the elimination of unused mesh faces (transparent faces are not "meshed")
3) Simple mesh validation, checking that the number of materials used does not exceed the SL limit of 8
4) The merging of prims into one or more mesh units and elimination of some of the duplicate vertices.
5) The correct UV mapping to ensure that the resulting mesh can be textured the same way as the prim model.

The 2016 blog post linked above explains why this workflow is useful, it can be especially helpful when working on a project that needs to fit into a specific inworld scale and many creators use Secondlife tools to "prim-out" a rough model to use as a scale template.

So what do you do if the tools are not working?

You have your model, the deadline is approaching, you finish tweaking the textures and click on the menu....nothing...the server is down.

Blender and Firestorm to the rescue.

Blender is a free, open-source 3D creation tool. It stands squarely against many of the leading commercial packages that dominate the professional world and is increasingly making inroads into the commercial world of games and VFX. Blender has a reputation for being rather unfriendly to use,  personally, I think that this is overstated. All the big 3D desktop creation packages have complex user interfaces and no shortage of peculiarities, I tried learning any number of them in the past and found myself bemoaning the complexity and yearning for the solid ease of plugging prims together. The fact is that with power comes complexity. Someone used to Maya will swear it is the best, A 3DS Max aficionado will be equally convinced that their tool of choose is the best one. There is no single answer, pick one and stick with it. If you have no specific reason to pick one tool over another then Blender has two very significant points to consider. 1) It is free 2) It has a vast and ever growing ocean of tutorials and youtube channels. But don't choose blindly, if you have a friend or mentor who swears by another tool and you can afford that tool, then perhaps that is the better choice. The discussion that follows will not apply directly to those of you choosing a path other than Blender, but for the most part, the principles will remain the same.

What you should not listen to is all the moaning and whinging from people who used it in the past and failed.
1) They may not have failed because of Blender, in many cases it is simply the learning curve of moving away from the SL interface to something more complex.
2) They may not have tried a recent version of Blender (if they bemoan the mouse button selection, for example, nod politely and walk away - that has been configurable for many years and since last years revolutionary version 2.8 left-click select is the default).

Any tool is going to take practice and commitment. Pick one and commit. There are many excellent tutorials for Blender, prefer 2.8 ones over 2.7 at least until you know enough to work around the UI changes. Andrew Price's "Donut" tutorial series is as good a place as any to start. Look around SL for support groups for your chosen tool too.

And so onto the viewer... I will be using Firestorm because I am, of course, biased, but a number of other Third Party Viewers (TPVs) support the export of prims as Collada and the workflow should be very simple to translate to your chosen TPV if required. I will be using the Firestorm dialogues in my examples, but they will most likely have direct equivalents in other TPVs.

Please note: The Second Life viewer from Linden Lab does not have any export capability at present. Feel free to lobby your local Linden if this is important to you, Jiras are more effective than pitchforks.

SL-Blender roundtrip summary

The rest of this post is going to go into detail and the blogger platform is not ideal for formatting this so bear with me. I'll try to create a supporting video as I did before but I know many people prefer to read than watch, so I'm going to try to capture as much as I can in text as well.

It is probably worth re-stating our objective here. We are not looking to do anything advanced in terms of mesh creation, we are not going to bake textures, for example. Moreover, our objective is to retain (as far as possible) the UV layout (the texturing) that we established inworld. This simplified workflow is to enable people to export a prim model, "clean it up a little" and re-import it into Second Life/OpenSim with (hopefully) a lower Land Impact (LI), a workflow analogous to that of the Prim2Mesh tools.

Here is the high-level summary for the TL;DR crowd:-

I should note here that this is not the only workflow the steps can often be mixed up as best suits the purpose and things are often best taken iteratively. These techniques, however, should be sufficient to get you through most clean-up jobs.

Step by step overview

1) Grab Blender, I will be using 2.82. Download it here
2) Export the mesh from SL. I will be using Firestorm (of course), many other TPVs should work too.
3) Import the mesh into Blender.
4) Prepare the mesh for cleaning.
   a) Restore quads - establish some nice edge flow that will pay dividends later.
   b) Join the mesh - make sure our UVs are safe first though.
5) Cleaning.
   a) Remove doubles.
   b) Simplify the geometry -we'll look at a non-definitive selection of strategies.
6) Export again.

What won't we cover?

  • We will not cover, creating LOD models in this article, though I may hint at options. I will look at this in a future blog.
  • We will not examine UV editing, our objective is to leave those untouched
  • We will not look at physics objects. I have older blogs for that and future ones planned.

Step 1, download and install Blender.

Get the latest stable version from Blender.Org, at the time of writing this is version 2.82, though I am eagerly awaiting 2.83.

Step 2, grab your TPV of choice and export your prim model.

I am going to be using this old seahorse sub prim model, it comprises a number of useful features for our purposes, some transparent mesh, that we do not want to export, a few different textures and a couple of sculpted prims. It will pose a number of problems and has some rather awkward geometry to deal with.

Triaging the patient

Before we export it is worth taking some time to make sure things are as clean as possible.

I've deliberately picked a rather poor example, in the movie that accompanies this post you will get to see me trying to clean this up, applying the tricks I list here.

The model I am using is a steampunk seahorse submersible that I first built in around 2008. IT was never intended to be meshed, it has never been prepared for use with a prim2 mesh tool. For this exercise though we are simply going to export it clean it up. I

I have taken a few steps to clean up beforehand and I would strongly recommend the same to you. 

If there are prims that should "join" try to align them as close as you can. I will demonstrate how to fix cases where this has not happened, but as you will see it is easier if you do some work up front.

The model consists mostly of prims, the distinctive curved tail is a sculpty as is the exhaust array fin on the rear. The tail has some leftover vertices that we will also clean up in Blender. The top opens up using alpha-switching, which for a physical vehicle in 2008 was the only realistic means to get an opening submersible. With this test we are not going to open it up at all, so I have even set the interior to transparent where I can. this is no different to optimising your prim builds for Mesh Studio by removing the hidden faces.

We would quite like to export the textures, and we need the sculpts (the tail and brass fins on the back). Exporting the textures will be useful throughout the process, they will allow us to see when we take a wrong turn (the UV layouts get messed up); even if you are only using a "UV checkerboard" it will help you see when you need to take a step back and try a different option.)

Finally, before exporting I ensured that the rotation of the model was aligned to the axes.


To export it we use the "save as..." menu, accessible by right-clicking on the object, if you have pie menus you will need to click more and more again to find the option. From "save as..." click "Collada".

You should be presented with a dialogue that looks a little like this.

In this case, we see that the object consists of 29 prims and that all of them are exportable. This is great news, in order to be exportable you have to be the creator of the prims and for sculpts you have to be the creator of the sculpt image that underlies the sculpty too. For the submersible, it is all mine.

The textures, however, we fail on 2 of them. They happen to be full perm, both taken from the Linden provided library I believe (the glass and the brass) but as I am not creator I cannot export them and those prim faces will be exported blank. If I wanted I could actually save these separately because the permissions allow it but they are not essential to our purpose here.

The options we pick are important.

  • Save textures - We would like to save textures where we can, this will allow us to see the textures when we import it into Blender later.
  • Consolidate textures - shown here "unchecked" but actually we want it checked. This will combine all the uses of the same texture into a single material in the export. Without this, every prim that has the rusty metal texture will get its own copy. This would be a real pain later.
  • Skip transparent - very important here, we do not want all the extra mesh that results from the hidden faces, by enabling this option we can avoid that. 
  • Apply texture params - this ensures that the texture repeats and rotations are preserved in the export, it ensures that the UV mapping is the same as you see inworld.

Finally, we can select our preferred format to save the texture images in, if you expect to work with the textures I would suggest sticking with Targa, it is a lossless format and while the source image has already undergone lossy compression, we do not need to add further artefacts at this stage.

Please note: that the export code pre-dates materials and as such all normal maps, spec maps and other materials settings are ignored completely.

Once we are happy we click "save as", give it a name, and save it to our local disk.

Something to remember, it is well worth taking a moment to ensure that your object is rotated to 0 degrees (or at least some whole number) I failed to remember that in my tests and I had to fiddle about cleaning that up in Blender.

And on to Blender....

Step 3 is to import it into Blender.

You will need only a few skills to follow this tutorial, but I am not going to try to include a beginners guide to Blender in this post. Please watch the first episode or so of the aforementioned Blender Guru Donut project. It will do a far better job of equipping you with basic Blender skills than I can.

With that out of the way, I'll assume that you can navigate in the 3d viewport, and find a few of the main menus, I will try my best not to assume much more than this.
Start with a new scene, delete the default cube if it is there.

Importing Collada is very easy, File->Import->Collada, locate the file on disk where you saved it. click "Import Collada" to import.

Your object(s) should appear in the viewport. Depending on how you have Blender setup following your "basic" tutorials you may well see your import mesh as entirely grey even if you exported the textures. To change this go to the top right of the 3d viewport and enable the rendered view. This will put you into the Eevee rendering engine and your textures should now be visible.

As you can see from my images, there is an acne rash of little orange dots. These are the centres of the individual prims. We will normalise these, along with the scale and rotation. so that everything is starting from a nice origin. (If you forgot to align your model before saving it, now is the time you'll repay that debt).

Applying the loc/rot/scale is easy. Press 'a' to select all the objects, then ctrl-a to apply transforms. You will be presented with a menu, you can select "all transforms" or a subset if you prefer. There will be no noticeable change to the model except that any "origin acne" will be cleaned up as all the objects now have their centre at the global origin.

Joined up thinking

The viewer export has saved every prim as a separate object. Sometimes this is useful, but most of the time it is not what we want. At some point, we will need to join some or all of the prims together. In my example I am happy for this to be a single mesh, it will have fewer than 8 texture faces in total and thus it will be suitable to upload as a single item.

Linking meshes is simple enough. Ensure that you are in Object mode (you should be by default, press TAB if not). "Object Mode" will be shown on the top left. Working in Object Mode is a bit like working at prim level in SL. We can select the objects we want to link together (pressing A will select them all), selected objects will have an orange outline. 

Once you have them selected hit ctrl-J (join).

Oh dear.... that was not what we wanted at all. We selected all the objects but as soon as we joined them all the UVs went bad. You can see this in the video, the blurring of the textures is an indication that all the UV data was lost.

The problem here is that we have more than one UV map, in fact, the exporter gave every object a uniquely named UV map. This may be considered a bug in the exporter. I would certainly entertain making this option in a future Firestorm release. However, for now, it is how it is.

Ctrl-Z will safely undo the damage, Undo is you friend in Blender, there are 30 levels of undo by default I typically increase that to 100 in the preferences.

The next step is a bit of a pain, we need to go through each prim and rename the UV map to be the same as all the others, then when we join they will show as a single UV map..

The UVMap details are located in the mesh tab of the properties window on the right of the screen.
look for the green triangle with tiny circles at the points. Click in the box and rename the UVMaps from primN-map0 to something simple like combined-map or just map0

The important part is to ensure that all objects share the same map. Doing this for a large number of objects is a royal pain in the posterior, so I cheated...

(spoiler: I wrote some python to do this, but fear not, I will be releasing this as part of my free/open-source SL tools Addon SOON)

I have now updated all my UVmaps to share a "unifiedmap".

Now I can safely ctrl-J and all the meshes are joined as one and all the UV information has been retained. This gives us the combined single object mesh we see below.

Let's get cleaning

Press TAB to enter Edit mode. 

Tip #1: Convert to quads

The first thing we can see is that the mesh is made up of triangles. This should not be surprising, but it is inconvenient for editing and it breaks any "edge flow" and loops that we have. It is an unwritten rule of Mesh creation to work in Quads as much as possible.

The following animation will show the benefits of having proper edge flow in the mesh by showing the selection of edge rings and loops before and after the removal of triangles. 

To remove the triangles we select all (A) and then press alt-J, this converts triangles to Quads where possible.

The quad conversion process can be complicated, it is not an exact process; the "tunable" setting on the quads converter can be used to control the angles that are used in the conversion. You can see how I use this to tweak the behaviour in the neck area.

It is not unusual for a few triangles to get left where you would have expected quads. We can clean these up using the "dissolve and join" trick we'll look at shortly

Our mesh is far cleaner to look at but we've not actually improved the geometry because we've left all the vertices in place.

Simplifying and refining

One of the tricks that Mesh Studio does for us is combining co-located vertices where possible. We can actually do a far better job in Blender as we have direct control. But for now, we'll just keep it simple. The objective here is not to rebuild/redesign this mesh, those skills we can work on later, we simply want to clean up this mesh and optimise, replicating where we can the functionality of our more familiar inworld tool.

Tip #2: Merging

What do we want to merge? where prims were aligned next to one another in SL we want them to be physically joined. to do this we want to merge the vertices that are on top of one another. In Blender, we can select the whole mesh or just the parts we want to work on and then use alt-m to find the merge menu, and pick "merge by distance" this is the new and more logical name for what was called "remove doubles" in earlier versions of blender. When we merge by distance we can control how close vertices need to be in order to be merged.

  • Select some vertices
  • Alt-M "by distance"
  • Use the dialogue that appears to adjust the distance or press F9 to make it reappear.

The merge tool, as most are in Blender, is not fully applied until you commit the changes and move to another operation and thus it can be tweaked back and forth. Even after this, you have ctrl-z of course. I use undo a lot to test whether one operation works, then undo and try another.

Other merge options are equally useful. 
if you have two prims that you had wanted to join, but their vertices were not properly aligned then you can merge them manually. Select the vertex you wish to move and the one you wish to move it to, then Alt-M "merge at last", this merges all the selected vertices into the last vertex selected. Merge at first does the opposite, while "At center" while find the central point of the selected vertices and merge them there. Play with the various options to see which work best for you. 

Merge at cursor, is also powerful but is best used in conjunction with more advanced tricks that I will save for another post.

Getting more tricksy...

We've done the simple things, our precious UV layout is still in place, but look at the mesh, it is still more complex than it needs to be.

Second Life Prims have 4 vertices per straight edge, one at each end and two spaced along the edge. These do have an impact on surface lighting but are typically removed in mesh. This is most evident in the back of the "neck" of the seahorse

The edges (highlighted) are not needed and so we will remove them. There are (at least) two ways to do this, the first is the most simple but may also miss some opportunities that we, as humans, can spot.

Tip #3 : Limited dissolve

Limited dissolve is an awesome tool. It can help you in LOD production as well as the basic clean up. so what does it do? It traverses the mesh and examines the angles between edges if a given pair of edges have an intersection angle of less than the threshold then it will try to dissolve them. What we want to do here is the bare minimal dissolve, removing vertices that are on straight edges and add no real value to the mesh topolgy.

Select all of the parts that you want to clean. Probably this is everything, in which case, in edit mode, hit 'a' to select all. Next press 'x' to get the delete menu and select "limited dissolve". A small control panel should appear in the bottom left, inside this you can set the maximum angle beneath which you want to dissolve. Set this to 0.1. You should find that all extraneous geometry on flat faces has vanished. this may leave ngons (mesh "panels" with more than 4 sides) but don't worry this will be resolved later when we triangulate again. As we see in the video, that extra edges on the back of the neck are dissolved, but also the inner curves on the side of the neck, which when we triangulate later become a single triangle fan. In that case, I had 6 sides of a tube, there were 3 concentric rings of triangles as shown by the quads there beforehand. In total, 30 triangles. when we export this, it will be just the 6. That's not a bad result.

The following clip will show me performing this.

Tip #4 : Manual dissolving.

In edit mode: highlight the edges that you wish to remove.
note that now we have edge flow back we can use alt-shift-click to select the entire loop, be careful you have only selected what you need though.

Next press 'x' and from the menu that appears pick "dissolve edges"

Two points to note here. Firstly, dissolve only works when blender feels it is able to remove the edges and vertices without breaking the integrity of the model. If you cannot dissolve then there is probably a dependent vertex that is blocking you. Continue cleaning up and come back to this later it may have been freed up. Dealing with it otherwise is outside of the scope of this guide. Secondly, the quad conversion can go awry at times. We tried to minimise the problems using the sliders but often there are still places where the automation does something a little less than obvious. This is the time to fix those too.

I illustrate this in the following gif. This is a pretty extreme example, but one that can happen. The result here is nice clean quads.

Repeat this process across all the model until you feel you've removed all the unnecessary extras (this is why method 1 is preferred where possible - it saves a lot of time).

Patching and Repairing

We've gone a long way now to cleaning things up. I've used a particularly complicated model to test this with and for most simple items you may well be done at this point and can skip to the next step of re-exporting the DAE ready for Second Life. However, what if you have broken geometry that you'd like to clean up? Here's a few more tricks that might come in handy.

As always, this post is only scratching the surface of what you could do, and none of what I write here is necessarily the best way, it is certainly not the only way. With this in mind here are just a couple of final shortcuts and tricks that I use.

Tip #5 Hot key selection mode switching while editing.

In Blender, you can by default select one of vertices, edges or faces, in fact you can enable multiple at once but I find that confusing so I will not cover it here. As of Blender 2.8, you can quickly switch using the 1, 2 and 3 key on the top row (not the numpad as they control view).

Pressing 1 will let you select vertices, 2 for edges and 3 for faces.

Tip #6 : relinking vertices. 'f' for fill, is the best way to join

When you have two vertices and you wish to join them you can often highlight them both and press 'j' to join. but it does not always do what you want. You can quickly rebuild bad geometry by combining the dissolve edges, mode switching and filling tips.

Here you can see me cleaning up the results of a poor "limited dissolve" applied earlier using these few simple moves.

I iterate through the mesh, switching to vertex mode (1), selecting two vertices and joining them (f), then switching to edge mode (2), selecting the unwanted edge and dissolving it (x).

A few other tricks that are not essential but which I use a lot include:

Tip #7 Selecting things

I talk a lot about operations that act upon selections but how do we select?
In the gui there are many ways and I won't describe those in-depth, the icons and tools are mostly self-explanatory. box select, lasso select etc. I will instead focus on the keyboard short cuts and quick operations.

  1. Select all (a) - pressing 'a' selects all vertices/edges/faces depending on your selection mode. In object mode it selects all objects (this includes lights and cameras so use the outlined window in the top right is you want to select some specific items) 
  2. Deselect all (alt-a) - set the selection to nothing.
  3. Select linked vertices. (ctrl-L) select only the vertices that are linked in the same contiguous mesh as the selected vertices. e.g. if you have two cubes and join them, they are one object but they are not connected in the mesh highlighting the corner of one cube and hitting ctrl-l will select all the verts in that cube and leave the rest unselected. 
  4. Hide selection (h) - as the name suggests this makes the selected vertices and any edges connected to them vanish from view. Great for getting access to interiors.
  5. unhide hidden (alt-h) - brings back everything you previously hid. 

Tip #8 Iterate and save often

In the next section, I'll explain how to save and to export (two subtly different things). Save often, use the versioning I describe and don't be afraid to try things out. you can often go over the process a few times to continually improve the results.

Exporting our work.

Finally, we are ready to export so that we can return or work to Second Life.

Make sure that you leave edit mode and return to object mode. Like many 3d tools the changes made in edit mode in Blender are not "finalised" until you leave edit mode. to switch back we need only press tab.

We will save our work as a blend file first, an optional step but worth doing in case we want to make further changes once we see what this looks like in-world.

To do this go to the file menu at the top, and click save as ... (shift-ctrl-s is the short cut). You will be asked for a filename. One of my favourite "lesser known" features is that if you pick a name that already exists in the file selector, the field at the bottom will go red to warn that you are going to overwrite, there are two symbols a '+' and a '-' at the far right of the field, these will automatically add and increment (or decrement) a number in the filename allowing you to keep "versions" of your progress. I tend to use this all the time and end up with tens or hundreds of iterations that I clear up once I am finished.

This image shows that I am trying to save my prim cleanup work in progress. You can also see that I have 22 versions of another model (my fully blender-native recreation of this model as it happens) in the same folder. If I click the '+' it will save as 'hippocampus prim cleanup WIP1.blend".

Pick a filename and save your blend file.

Now we will export the Collada (DAE) file.

First, we will highlight just the mesh objects we wish to export.
If you joined things into a single mesh then click the object you need. If you left it in multiple parts then shift-click to select all the ones that you want.

Next go to the file menu, export, Collada

You will now be shown a file dialogue. It will default to the name we chose when we saved the .blend file. There will be an "Export COLLADA" button highlighted.


This is one aspect of the new Blender I don't like very much as it makes life harder for new users.
The defaults for Collada export are rarely what we need. To change the settings we have to press the "cog" to expand the settings on the right-hand side.

In this settings box, we need to enable selection only. But there is a preset available, so let's use that. Click the "Operator presets" and select "SL + Open Sim static".

If we do not do this, Blender will export all the objects in the scene including the lights and cameras, sometimes this is fine, but as you get into more complex objects it is worth getting into the habit of explicitly exporting only the parts that you want.

We can now press the "Export COLLADA" button. If things work properly you will see a small message pop up on the screen saying "Exported N objects" depending on how many objects you had selected. It is always worth keeping an eye on that, if it is not what you expected then something went wrong, double-check that you had "selection only" selected and that you had remembered to come out of edit mode.

And that's it, you can now upload as normal.

A few last notes

Don't forget that you may well have joined your objects. If you had prepared the linkset as if you were using Mesh Studio then you will presumably have limited your "mesh faces" to 8, if not then be careful to check that you only had at most 8 materials in your mesh or you will get one of the mysterious "MAV errors" or a "model not a subset..." type error in Second Life.

Most of what I have taught in this blog should be "non-destructive" with regard to UV layout. However, an over-zealous use of the dissolve tools will leave areas in a mess and I have not tried to explain how to dig yourself out of that hole. Try to keep things in rendered mode, so you can see the textures and the effect your changes have on them. 

This concludes what I think you'll agree was a far longer delve into the cleanup process than the 2016 one. The steps I show are I think quite straightforward, and hopefully, with a little practice, you'll learn not to fear the tools. What I have explained here can be translated into other tools such as Maya or 3DS Max. My weapon of choice is Blender and for me, it is the right tool for pretty much everything I need to do. The thing I want to say though is that no matter what tool you use if you are starting from a background of Second Life prim editing, they are all going to be daunting, they are all going to be hard, and you will struggle, stumble and fall at times. Start simple and build up from there, when you fail, pick yourself up, and try again. You'll get there. 



Monday, 9 March 2020

The evolution of a mechanical sea horse.

I don't sell things very often, there's a long story behind this which is not worthy of your time to read, but... I just made a new thing to sell!!

The all new "Baby seahorse" - the Hippocampus Janusii Minor.

The new creation is being launched at the Great Exhibition of New Babbage, a brilliant event that combines historical reconstruction in true steampunk style and a grand, sales event (in true Second Life style). You can visit the exhibition and see the "hippo" in all her glory by visiting the Verdigris stand

The new Baby will be available for the slashed price of L$299 at the event and includes future updates such as alternate colours, custom animations and a more detailed interior. The price after the event will return to the more normal L$600-ish price.

But is it really new?

Structurally this has been rebuilt completely, it is 100% custom mesh, with materials. It was the first full trial of my new (soon to be officially announced) SL addon for Blender. However, the concept is older and dates back to 2007/2008 when I first moved into my undersea home in the New Babbage ocean sim, the Vernian Sea.

The first Hippocampus submersible was a two or three-seater behemoth, a few months later, a baby version, a single person submersible appeared. The two models are shown here together in a photo from 2008, which finds me working on the engine of the larger beast, while the baby hangs on the hoist.

The original baby weighed in at 28 prims, with a sculpted tail and fins. It was later enhanced with two side propulsion pods.
The new model, I hope pays homage to the original design, but also serves to show how Second Life and my own content creation capabilities have evolved.

Watch this space for more news soon, I'm going to revise my 2016 tutorial on converting prims to mesh using Blender.

The great exhibition is open until April 1st, don't be an Aprils fool and miss it.




Wednesday, 13 February 2019

Compression depression - Tales of the unexpected.


Today I learned that bilinear resampling beats bicubic sampling when reducing image resolution.
Try it now. Even better, see if it allows you to get the detail into a 512x512 that you previous clung on to a 1024x1024 for.

In the beginning...

It started with a dismissive giggle. A blog post from Wagner James Au over at NWN, made the somewhat surprising claim that a debug setting in Firestorm gave much higher resolution textures.

How To Display Extremely High-Res Textures In SL's Firestorm Viewer

"What a lot of nonsense" was my first reaction, after all, everyone knows that images are clamped at 1024 by the server, viewers can't bypass that, because believe me, if they could someone would have done so at some point. But I do try to keep an open mind on things and so along with Whirly Fizzle, the ever curious Firestorm QA goddess we tried to work out what was going on.

The claim

The claim (asserted by SL resident "Frenchbloke Vanmoer" and reported by Wagner) is that by playing with a debug setting in the viewer you can get much better upload results. We automatically get jittery when such claims are made, they are typically spurious and have bad side effects (I refer you to the horrible history of RenderVolumeLODFactor). The post, however, shows evidence from the story's originator; something was clearly happening, this warranted a far closer look.

The setting in question is max_texture_dimension_X and Y

I show it here as 8192, as the blog suggests. But the clue to why this is not the true source of the improvement is that the default is 2048, not 1024 as you might expect.

Examining the evidence

It is still February so too early for April fool, but was the user deluding himself with local texture mode, seeing a high resolution that nobody else could see? Whirly did some experimental uploads and confirmed that in her view the user (Frenchbloke) was correct, there was a distinct improvement in the viewer texture if it was uploaded from the 8192x8192 source. How odd.

But again you have to be very careful with the science here. When you resize in photoshop, you then have to save the image. If you save as JPG then you leave your compressed image at the mercy of the jpeg compression and the quality settings used by photoshop. In effect, you lovingly craft a texture then crush the life out of it in jpeg compression, the uploader then decompresses it locally, before recompressing into the jpeg2000 format required by Second Life (losing more info in the process). The end result being worse than starting with a large source image and doing the compression one time in the uploader. Problem solved, that must be it, right?

Wrong. Testing with PNG, a lossless format, showed similar results. Resizing in Photoshop and saving lossless, then importing, was worse than letting the viewer do the resizing. No matter how devoted we might be to our Second Life we are not typically inclined to think that the viewer can be doing a better job than a more specialised tool, especially not when we are talking about the industry powerhouse photoshop, but the evidence was suggesting this.

So what does that setting do?

At best nothing at all, at worst very little. It has not explicit involvement in the quality of a texture.
The max_dimension parameter is used to test up front the size of an uploaded image and block anything "too large", but that is all. In fact, it is enforced in the interactive upload dialogue but it is not applied in the "batch upload" so with or without the debug setting it has always been possible to pass oversize images into the viewer and let the viewer "deal with it".Conventional wisdom, however, tells us that that cannot be the right thing, you are giving over control to the viewer.

The max_dimension setting lets you pick a larger file from disk, but the viewer still uploads at 1024 max.

ok, so the setting does more or less nothing, what on earth is going on?

Having ruled out the "double jeopardy" scenario by using a lossless input format, I walked through the upload process in a debugger, testing the theory that perhaps giving a large input resulted in the Kakadu image library that Firestorm and LL both use for handling images doing a better job at compressing than it might when given an already resized image. The theory is sound, more data on input must be a good thing, right?

Wrong. Well, wrong insofar as there is no extra data at that point. This is how the viewer image upload works...

  1. The user picks a file
  2. The file is loaded into memory
  3. It is forced to dimensions that are both a power of 2 and no greater than 1024.
  4. The preview is shown to the user.
  5. The user clicks upload
  6. The (already resized) image is compressed into jpeg 2000
  7. The result is uploaded.

So..another theory dies because by the end of step 3 we have lost the additional data because we've forcibly resized the image.

Perhaps we have a bug then? Do we think we resize but mess it up?

I examined the early stages of the above sequence, and sure enough, we get to step 3 and it takes your input image, in my case a photo that was about 3900x2800, and forcibly scales it down to 1024x1024. What was even more bizarre was that if the image was already 1024x1024 the code did not touch it (a good thing) which meant that the photoshop resized image was passing directly through to the upload stage in point 6 untainted.

OK... so what is this scaling we are doing? 

Perhaps the scaling that we do in the viewer is some advanced magic that gives better results for SecondLife type use cases and is part of some cunning image processing by Kakadu....

Wrong. Very wrong. Firstly, this is not a third party scaling algorithm, the code is in the viewer. and what is more, it is using a straightforward bilinear sampling.

Bi-linear? But that's crap, everyone knows that...Right?

Wrong. It turns out that whilst almost everyone has accepted the wisdom conveyed by Adobe (whose software states "Bicubic Sharpen - best for reduction", very few people have bothered to actually test this. A quick google search shows the conventional thought is deeply ingrained, but halfway down the results is a lone voice of opposition.

Nicky Page's post demonstrates quite clearly that bilinear sampling is a more effective reduction technique.

So prove it then.

Not one to take anyone's word at this stage I went back to the image that Whirly used, a red tiled roof.

I started with the same high-resolution image. I loaded it into photoshop (in this case I used the latest Photoshop CC 2019) and resized it first using the Adobe recommended bicubic-sharper. Then reverting back to the original, resized it using Photoshop's own bilinear algorithm. Both were saved out as Targa (TGA).

I then switched to Firestorm (using the latest build again) set the debug setting as per the original instruction and uploaded 3 textures

  1. The original texture, allowing the viewer to rescale it.
  2. The manually rescaled bicubic image.
  3. The manually rescaled bilinear image.
I then compared them inworld and sure enough, the quality of both 1 and 3 was near identical. The quality of 2, the bicubic, was noticeably lower. Click the image below to see the magnified comparison. (also available

Is there a less subjective way to illustrate this?

Looking at complex images for areas of blur is not a very scientific approach. I downloaded each of the textures, saving them as lossless Targa (TGA) images.

Loading all three back into photoshop I combined them as layers. Setting the relationship between the layers to subtract allowed me to show where the images differed.

As can be seen, the bi-cubic has a lot more artefacts than the two bilinears. Bi-linear resampling is the way to go it seems.

The observant among you will notice that the two bi-linears still have differences, so which is best?
They have both undergone the roundtrip through jpeg 2000 compression and when I applied the same test to the photoshop bilinear resampled image that had not been uploaded, they both showed very similar amounts of artefacts but in slightly different places. Which leaves the ultimate decision with the uploader I think.

So what have we learned?

Sometimes we learn things from the most unexpected sources. I owe a thank you to "Frenchbloke Vanmoer" for setting us on this path, and to Wagner James Au, for the post that brought this to my attention.

The key lesson here is you don't need debug settings to get better image quality. You need the right algorithm and from there it seems clear that bilinear resampling is the best way to go. A good reason not to use the debug setting is that by doing so you are limiting your improved textures to those that are 1024x1024. The same improvement can be gained for 512x512 and 256x256 if you do so in your photo editing tool of choice.

I hope this was a useful insight into not just how but why this effect is seen and a lesson to all that you should not always take advice at face value, but neither should you dismiss out of hand what seems cranky and illogical at first glance.

Take care


Another example

Friday, 7 December 2018

Easing the pain of importing Mesh.

A quick guide to the Mesh uploader changes in Firestorm 6.

But first a quick mention of the "other thing"

The big new thing in Firestorm 6 is, of course, Animated objects or "Animesh" which gives you the ability to take any rigged mesh item that you have modify permissions on and turn it into an animated independently moving item. You can read all about Animesh on the Linden Lab blog the regular places such as Inara and Nalates' blogs. Having spent quite a lot of time over the last few months looking at performance concerns around Animesh and tweaking some of the performance of rigged mesh in general, I am relatively happy that Animesh has an overhead not too much more than if that same mesh were being worn as clothing today. That is to say that a single animesh  of say 30,000 triangles will have an impact on your performance more or less equivalent to a 30,000 triangle dress or xmas sweater.

And now on to the main part of the blog...

A side-show to the main event of animated objects, nestling amongst the many fixes and tweaks since the last release, is my revamp of the Mesh Uploader. I teased some of the information on this previously but I'll now give a quick guide to the updates.

What's changed?

  • Cost breakdown, how the L$ charge is calculated
  • Physics details, the costs of the different types of physics (convex hull, prim)
  • Higher resolution preview image
  • Scalable preview window
  • Improved shading/lighting in the preview window
  • Correct highlighting of degenerate mesh
  • Improved error handling for physics models (avoid some of those MAV errors)
  • UV Guide overlay


So why change the uploader? Primarily because it is awful. A lot of creators struggle with the obscure and limited error handling, the postage stamp preview and poor rendering. The aim is to improve the tools, this is really the first step in what I hope will be a series of improvements both in the capability of the import tools but at least as importantly, in the feedback you get when things go wrong.

So what are these changes?

First of all, we'll look at additional information panels.
Taking the following object (an old prim building exported from SL)

Cost breakdown:

Ever wondered why that first upload cost you L$15 but the one after cost L$25? This information panel will at least tell you where that final number comes from.

The Download fee is derived from the streaming cost of the mesh, shown as "Download" in the standard Land Impact stats.
The Physics fee relates to the cost of the physics model. It is worth noting that the Convex Hull (Base Hull) is free, while a User supplied physics is charged based on its complexity whether it is mesh or analysed (more on that later).
The Instances fee is L$1 per mesh "prim" in the linkset. As can be seen this build has 70 separate meshes in a single model. 
The Textures fee is the standard L$10 fee per texture upload and is only added when the "inlcude textures" box is ticked on the "upload options" tab.
Finally, the Model fee, is normally L$10, the core upload fee irrespective of the complexity of the scene. It may be possible for this to be more in a multi-model DAE but I have not had a chance to test one.

Physics breakdown:

Personally, I think this is the more valuable of the two new panels. It has always been guesswork as to what the inworld physics cost will be if you use anything other than the default convex hull. 
This panel shows you the possible physics costs. There are 3 values shown but typically only two of these will have a value at any given time.
Base Hull: I should probably rename this to Convex Hull to correspond to the inworld name. The Base hull is the default physics shape, every mesh has one of these, in fact, if the uploader is unable to calculate a credible "base hull" you will get a dreaded "MAV block missing error".
This cost is the one traditionally shown in the LI summary because it is the default state of a newly uploaded mesh. However, if you provided your own physics shape, then inworld you can set the physics shape to the equally confusing "Prim". The next two values are related to the "Prim" physics

Mesh: User Mesh physics, this is the value is you have provided a Mesh model and not used the Havok Analyse function. It can sometimes be cheaper than the analysed equivalent but as all regular readers of this blog will know, it can vary with scale. The cost shown assumes the scale as uploaded.

Analysed: If your user-specified MEsh is analysed (and optionally simplified) using the Havok tools then when the fee is calculated it is based not on the original Mesh model but instead on the number of hulls. Using this new info panel you can, therefore, check the non-analysed physics cost and then examine the analysed costs and decide which you prefer before you upload. 

Moving on from the info panels, we'll look at the most obvious visual change, the preview panel itself.

The preview panel:

There have been a number of alterations to this panel. Firstly I have changed the Colour scheme to be more aligned with the inworld editing, yellow highlight for the edges, with translucent blue for physics. these can be overridden in the depths of the debug settings if you really want.

The next change is my favourite, the scalable preview window. The rearranged upload "floater" is already giving you a larger preview are, but depending on your screen size you can now grab the lower right corner and scale it out to as large as you wish. This comes in really handy for identifying those pesky degenerate triangles in your physics mesh. Alongside the increased physical size I have also increased the resolution of the preview giving a less jagged feel to the render. 

A more subtle change is the lighting of the model. The preview window always had very deep dark shadows and investigation showed that this was not actually the intended behaviour but that the 3 point lighting implementation was broken. I have made a quick fix that improves the general lighting but I have future plans to do more with this.

In addition to the existing edges and textures options, I have introduced a new "UV Guide". This displays a simple checkerboard pattern over the mesh and is useful for ensuring that you exported the right UV map before you get inworld. It is possible to add your own UV Guide and in a future release, I hope to make that directly editable from the preferences.

The final visual change was to fix an annoying bug that has meant that the intended "helpful" diagnostic display to highlight the presence of degenerate (i.e. long thin) triangles was more or less indistinguishable from the build. These errors in the physics mesh which were previously highlighted with tiny black lines marginally thicker than the mesh display are now highlighted clearly in bright red.

The following animation shows a quick overview of the new preview window

Finally, at least for this "overview", I have attempted to improve the error handling workflow.

Improved Error Handling:

Anyone who has spent any time uploading Mesh or helping others to do so will have suffered the pain of the obscure and often misleading errors. In this refresh I have tried to ease the pain a little, there's still some way to go I'm afraid but I hope that this start will save people some of the worst of the shortcomings of the old uploader.

Intercepting MAV errors....wait, rewind .. What is a MAV error?

MAV stands for Mesh Asset Validation (or something close) it is the process that occurs when you click the calculate weights button before the server decides on the costs. A MAV error is, therefore, one of a number of "fatal" errors that prevent the mesh being considered as well-formed and given a set of costs and weights. The annoyance factor of these is two-fold, firstly you have to click the button and wait for the response from the server, and secondly, you have to decipher the meaning of the error message. These MAV errors also commit the cardinal sin of error handling "Please look in the log for more information", if you've ever tried to look in a viewer log file and work out what went on you have my pity. 

MAV Errors then and now

There are four main MAV errors that I can think of:-
MAV error block missing: I referred to this earlier, and it can occur for a number of reasons, unfortunately, and because of this, for now at least, I have not trapped this one. The "block missing" means that part of the Mesh data structure was not present when it reached the server. This is purely a technical fault and of no use whatsoever to the user, so what causes this? The Mesh data upload structure has a number of mandatory "blocks" these include the LOD data, a convex hull etc. The most common (in my experience) occurrence of  "Missing block" is when the mesh is so poorly optimised that the convex hull creation failed. another cause is, once again, overly complex mesh that causes the LOD generation library (GLOD) to fail to produce an adequate simplified LOD.  There may well be others.

MAV error: Degenerate Triangles: (Now trapped) Traditionally this has been reported when your user-defined mesh physics shape is too complicated and in particular it has one or more long thin triangles. These are an error because they cause significant issues for the physics engine. As mentioned above I now highlight these in bright red, and this occurs as soon as the user mesh is specified. along with this the calculate button is deactivated (you would only get a MAV error so I am saving you from yourself) and a red error message explaining the issue is shown.

MAV error: Some hulls exceed vertex limit: (Now trapped) In the past your mesh was sent off for evaluation but I now perform this in the preview itself. Hulls are a simple convex shape made up of at most 256 vertices. If the analysis produced more complex hulls then this cannot be stored in the mesh data structure and is a fatal error to the uploader. This is now trapped and flagged as an error, the calc/upload button disabled and a suggestion of how you might fix the issue provided with the error.

MAV error: Too many hulls: (Now trapped) In the past, you would get a MAV error if your analysed results gave more than 256 hulls for any single instance (aka mesh unit) in the model. Once again this is a technical limitation imposed by the system and it prevents the model being uploadable. This is trapped and provides a suitable error and a suggestion of how to fix the problem. As you might expect by now, the calc/upload button will be disabled.

That's all folks

That about rounds up this Blog and the uploader changes. As I have said a few times above, this is the first stage of what I hope will be a more complete revision. If this is well-received I will look at the feasibility of contributing this back to the Linden Lab viewer so that everyone (not just Firestorm users) can take advantage of it. The Mesh Uploader is a complex and fickle beast and while I have tried to cover many areas and check for loopholes there is a chance I missed some. I have also deliberately neglected the rigged mesh tools a little, both to focus the changes and to not mix up any issues with uploader changes with Animesh.



Wednesday, 3 October 2018

Shedding light on Mesh uploading - Something I'm playing with...

For some, the entire Mesh upload process is wreathed in fog, a murky, mystery-filled place of confusion. Sometimes this is down to misinformation and poor tutorials out here on the web, but the Mesh uploader does nothing to help its own reputation.

With the above thought in mind, I've started to make a few tweaks to the uploader. Nothing major here but I thought I would share a little of the direction I am going in and see what the feedback is.

While I want to address a number of different problems, from the error reporting to the preview window, I've started with some additional information displays. It has been mentioned many times in the forum that the Mesh uploader is a little "random", and whilst there is a grain of truth to that, it is also in large part due to the opaque nature of the numbers we see. In particular, where is the cost derived from and why does the physics shown on the uploader bear no resemblance to that which we see inworld?

Blogger will downgrade this clip but you can peek at the original here

Very rough and ready but what this shows is some extended information that is returned when you "calculate weights & fee". So what goodies do we have here?

There are 3 sets of information I am showing, we will ignore the middle one for now as it is not useful in its present form, so that leaves...

1) The contribution to the fee

As you can see, your upload fee is derived from a number of components:-


Streaming is a charge derived from the streamable size of the object.
Physics is a fee derived from the physics model, and you can see that it varies with the physics costs that are normally hidden from sight.


Instances is a little misleading, it is not used in the context of repeats of a mesh, as those familiar with 3D modelling might use the term, it is instead derived from the number of mesh units making up the model. It is effectively the "prim count"


I don't show this in my quick clip above but it is the 10L charge for any textures uploaded with the mesh. Uploading textures with the mesh has always been an option but to my knowledge is rarely used.


I have never yet seen this as anything other than the 10L value shown in the clip. I suspect in the workflow it is effectively hardcoded.

And so on to the (arguably) more interesting information.

2) The physics costs

Here we find the hidden cost of physics. For years we've moaned about the fact that the Physics cost shown has little relation to that which we get after upload. Most of us will have made the link to the fact that the physics cost shown historically is just the "base hull" cost. That is to say, it is the cost assigned to the shape that is used when "convex hull" is selected. This is the default physics shape post-upload and is a mandatory part of the uploaded asset.

But we can also provide a custom physics model, if we choose to provide it as a mesh then a weight based on the number and area of the triangles that comprise that model is computed. While it has not been visible until now, it does influence the price we pay. For reasons we have discussed in this blog many a time in the past, there are occasions where a Mesh physics model is not suitable; in those cases we use the "analyse" function to convert the triangles into a set of hulls, or a "decomposition" in viewer-speak.

While a base hull is mandatory and always present, the mesh and hull based user supplied physics shapes are mutually exclusive, you may only have one. As such pressing analyze and then calculating weights will blank out the Mesh cost and retrieve an Analysed cost.

Will this help you?

OK, so that's it for now. How this will actually appear in a future Firestorm I'm not yet sure. There is a fine line between providing more information and causing more confusion. so while I think it will appear in some form I'll be hoping to discuss it with users and our support team as well.

Personally, while seeing the composition of the fee is interesting in passing, it is not essential and anyone tailoring their mesh to minimise the upload cost really needs to consider their motivations. However, knowing exactly what the physics cost will be in-world before you upload is a massive time saver and I believe that this will be popular with my builder friends.

I'd love to hear your thoughts on this. Am I completely off-piste here?

Saturday, 25 August 2018

Why did my LI just explode, I only linked in two simple prims?

Another tale from the tavern

The long-suffering bar staff at the builders' tavern can share many a tale heard over the sobs of a builder, driven to drink by the seemingly implausible accounting of Second Life. One of the more common tales is "the case of the lunatic link set". There are a few variations on this tale, but the underlying story remains the same.


Too lazy to read? Simple summary, when building link sets of prims be wary of mixing "new" features and the potential knock-on effects on seemingly innocent prims.

Once upon a time

Our happy builder starts his day merrily slinging prims as he builds a new home. Carefully avoiding linking any meshes to the link set (he's been caught by that before) he finishes around midday, and step back to look at his pretty little 28LI home. He muses over the building as he nibbles a cheese and pickle sandwich.

"You know what?" he says to himself, "it's just missing that little something extra. A little finesse on the front porch."

Putting aside his lunch, he quickly knocks up a couple of simple decorative columns from cylinders, popping on a normal map to give them some nice fluting, he links them into the build. 30LI, very nice, but the columns look unfinished and then he realises, they need a base and capitol. He quickly whips out a couple more prims, one torus top and bottom of each, 4LI extra, still a decent count for a prim house. He links them together and carries on working, it isn't until he stops for a tea break in the afternoon that he looks up and sees that his house now has an LI of 290.

In shock and denial, our builder paces up and down scratching his head. He checks every link in the link set, no meshes, not even a sculpt, (he never really trusted those). He unlinks and relinks, changes colours (cos why not?), restarts the region and moves to another sandbox. So distracted, in fact, that he lets his cup of tea go cold. In frustration, he downs tools and heads for the tavern.

So what is it that drives up the LI and the profits of virtual pub landlords?

He recounts the tale to the ever-patient barmaid. Explaining that he checked every single prim in the build, unlinked the entire thing and reassembled it, no single part has an LI more than 1 and yet when the 34 prims are linked the LI is many times more than the sum of the parts.

The barmaid smiles and pulls him another pint.

"You've used materials, 'aven't ya m'dear?", he blinks, she looks at him; "That'll be 2 Lindens please"

"What? oh!" He pays for the beer, "yes, yes, I used a little normal map, gives these lovely fluted effects to the columns, but even with the normal map those are only 1LI"

"Aye, but I bet you've got some toruses in there, right?" He blinks again, she's not wrong, but what on earth has that got to do with anything.

"I do, of course, but I checked them they are only 1LI too"

"Go back and look again, but look closely this time." She writes a little note on the beer mat, it simply says "Ask for more info"

Back to work

Somewhat puzzled he heads back to the cottage and once again starts to look through the prims, all at once he notices the "more info" link hidden on the object details.

His toruses are costing him 72 LI each, or so it says, but he checks again and sure enough, it says 1LI, what is going on? All of a sudden a distant memory comes to mind. It's not just Meshes that cause the LI to go mad. It's other stuff too... He hunts around and finds a long forgotten post on the community notice board.

The builder stares for a moment, taking in the new information.

"So," he muses, "the normal map on the cylinders may have seemed innocuous because their cost never changed, but it forced the entire link set to use the modern mesh accounting, which means that my pretty torus plinths are costing me a fortune because of the number of tiny triangles." Reinvigorated by new knowledge our builder hero, edits the link set and carefully sets the physics shape of the 4 toruses to be "none" eliminating the physics overhead, reducing the load on the physics engine and making the world a better place in all ways,.

And they all lived happily ever after...

Until the following morning, when while glazing the windows, the builder chose to use alpha masking (because it's better all round right?) and was later found sobbing into another pint of Builder's Bane.


The moral of this story is that any link set that uses a post-2011 feature such as mesh, materials or alpha masking will remove the legacy prim accounting cap from the entire link set. The most common case is linking to another Mesh but be aware it is more nuanced than that, as our merry builder friend discovered. Take heart though, all is not lost, you can use those whizzy new features, just take care to minimise the side-effects. Often this means you just need to find the culprits (the firestorm "show physics shape" can help here) and set their physics to none.

Friday, 8 June 2018

The Degeneration game - Nyrva's shower - a simple case study in physics shapes in Mesh Studio

I often come across frustrated builders who have struggled along the right path but for various reasons not quite got to the destination they had hoped. It often reads like a storybook, as our wannabe mesh warrior stumbles into the local inn, seeking solace and with a plea for help.
Nyrva: Hello, question please. If I am trying to build a "sci-fi shower" for RP, that you have to be able to walk inside of, do I have to make it square and boxy in the mesh and physics in order to avoid the "Degenerate Triangles" problem on import? It seems I'm not allowed to do a cylindrical design.

We meet our hero part way through their quest. They've already confronted the uploader troll, and unable to answer the riddle of the degenerate triangle, have retreated for help.

Back in the village tavern, our quester gets a lot of well-meaning advice. It variously consists or perpetuating myths and old wives tales, or valid advice that helped someone once, but does not really help our hero.
helpful soul#1: cylinders can be a pain ... i have found it "cheaper" to make the sides from a number of "box" type prims  for the physics
 helpful soul #2: your physics can be made up of a number of cube prims arrounged in a circle... sounds a pain ...but it is cheaper LI wise ( and i havent a clue why that is so ). I once made a smoke stack for a steam boat .... mesh funnel ... for some reason .... i forget why i need it physical ...... i was lazy and added a normal ( transparent ) cylinder when i added the prim cylinder to my mesh funnel the LI blew through the roof ....???? ( so i made a mesh physics one)
helpful soul #3: Also zeroing out the low and lowest LOD helps lower the LI because you wouldn't be looking at the shower from across the sim
In this case, all good advice in the right place and time but missing the point. Our embattled builder hacks away for a little longer, gets frustrated and gives up, limping defeated to the marketplace to buy something less fulfilling.

So what was the problem?

The MAV errors reported by the Second Life are often considered as dark arts, a kind of voodoo curse that nobody understands, but mostly they are just annoying badly reported errors. MAV comes from Mesh Asset Validation, so this was failing during the validation phase. OK, but what is a degenerate triangle? In mathematics, a degenerate triangle has zero area. In SL and other games use cases a degenerate triangle is one with a very small area. The degenerate triangle check, in SL, goes a step further and penalises "long thin triangles" which are defined as triangles where any one side is more than 10 times the length of any other side.

So the problem is that we have some tiny, probably stretched triangles. This is one of the reasons why I keep repeating over and over that a physics shape must be as simple as possible. If you have a triangle that fails the degenerate check you have definitely not optimised that model.

In the case of our intrepid mesher, they'd not removed all the hidden surfaces and thin edges. This is a common error, people think "this is a physics mesh, not a visible mesh so I don't need to hide the geometry, but it brings us back to rule #1 of physics shapes, every triangle that does not need to be there is a triangle too many.

Right then, how do I find these things?

Once you know what the cause is, it is often quite obvious where the problem lies; however, what many people do not realise is that the much-maligned uploader tries to help you. When it finds a degenerate triangle it will highlight it in the preview window.

Happily ever after?

Does this story have a happy ending? We left our hapless builder being bombarded with advice over a beer in the local tavern, but how did it end?

Having been asleep when this tale started, I caught up with Nyrva when I woke to see how they'd got on. 

Me: Hi, did you get past your problem earlier?
Nyrva: no, never did. just wound up buying something off the MP for 55L$. I couldn't make anything below 5LI. For me, it's just another item on the "What MS can't be used for" list. lol!"

Never one to pass up a challenge I asked Nyrva to send me the item. I was able to get the shower to be 1LI with a full physics shape relatively easily. So what magic did I use? Nothing really just careful attention to that law of physics models, delete every triangle that is not absolutely necessary,

The rest of this blog is a brief step by step guide through the process.

The visible mesh is always a good starting point.
As we can see the structure is very simple, with no obvious reasons why we cannot get a very low LI. The only complexity is that it is cylindrical, in fact, the cubicle is just 3 cylinders, one of which is hollow and 1/4 cut. 

Cylinders are made up of a series of flat edges, a cylinder in SL is by default 24-sided, and in Mesh studio you can step down to as low as 3 sides (where your cylinder will appear as a triangular prism)

For the visible mesh in the High LOD model leaving the default setting will be fine. However, for the physics, we need to economise.  I chose to use the cylinder and set the number of side to 8 in Mesh Studio, with the quarter cut away this results in a 6 sided cut cylinder, which is 12 triangles on the inner face and 12 triangles on the outer. however, there are also two long thin triangles on the vertical edges and 12 small triangles on the top and bottom surfaces. These triangles are extraneous and also quite likely to be degenerate, I have marked them in RED to highlight them. All of these should be made transparent in the model before meshing.

The two "caps" top and bottom do not need to be curved at all. Leaving them as cylinders, even 8 sided cylinders would have resulted in 16 triangles ( 8 top, 8 bottom - assumes we remove the 16 around the sides). Unless there is a very specific need have the physics shape match the shower visual shape using a square and getting just 4 triangles is far more efficient.

Some of you will be shouting, "but you don't need the underside and the inside surfaces. It is true that the inner shower wall and the underside of the shower ceiling are probably superfluous and would have been the next optimisation if this had remained higher. Note that we cannot remove the underside surface of the floor because we need to have at least one triangle there to match the bounding box of the mesh and avoid stretching.

Uploading with the original visible mesh resulted in a 1LI cylindrical shower. 

Bonus feature

There was a curious outtake during the making of this blog. having duplicated the curved shower glass and used it as the basis of my physics, I made the long thin edges and the top surfaces transparent and generated a mesh.

It refused to accept this as the physics, giving a Degenerate Triangle error. Looking at the image in the upload preview it was clear that the problem was that long thin cut edge, but it was equally obvious that there were no triangles there.

The problem was a little more subtle. Sometime during the editing of the original cylinder Nyrva had picked up a rounding error. and the cut was set to 1.2495 instead of 1.25. When Mesh Studio generates the mesh it obeys this. 0.125 is 1/8 of course. the size of one of our segments in our physics, so what Mesh studio was actually generating was 6 full-size sides and a tiny slither of the 7th side, which was of course, degenerate. Correcting the rounding error fixed the issue.