public static bool NeedUVGeneration(ChiselModel model)
        {
            haveUVsToUpdate = false;

#if UNITY_EDITOR
            if (!model)
            {
                return(false);
            }

            var staticFlags = UnityEditor.GameObjectUtility.GetStaticEditorFlags(model.gameObject);
            if ((staticFlags & UnityEditor.StaticEditorFlags.LightmapStatic) != UnityEditor.StaticEditorFlags.LightmapStatic)
            {
                return(false);
            }

            for (int i = 0; i < model.generatedMeshes.Length; i++)
            {
                var generatedMesh = model.generatedMeshes[i];

                // Avoid light mapping multiple times, when the same mesh is used on multiple MeshRenderers
                if (!ChiselSharedUnityMeshManager.HasLightmapUVs(generatedMesh.sharedMesh))
                {
                    return(true);
                }
            }
#endif
            return(false);
        }
        private static void GenerateLightmapUVsForInstance(ChiselModel model, ChiselRenderComponents renderComponents, Mesh generatedMesh)
        {
            // Avoid light mapping multiple times, when the same mesh is used on multiple MeshRenderers
            if (ChiselSharedUnityMeshManager.HasLightmapUVs(generatedMesh))
            {
                return;
            }

            if (renderComponents == null ||
                !renderComponents.meshFilter ||
                !renderComponents.meshRenderer)
            {
                return;
            }

            var uvSettings = model.UVGenerationSettings;
            var param      = new UnityEditor.UnwrapParam();

            UnityEditor.UnwrapParam.SetDefaults(out param);
            param.angleError = Mathf.Clamp(uvSettings.angleError, SerializableUnwrapParam.minAngleError, SerializableUnwrapParam.maxAngleError);
            param.areaError  = Mathf.Clamp(uvSettings.areaError, SerializableUnwrapParam.minAreaError, SerializableUnwrapParam.maxAreaError);
            param.hardAngle  = Mathf.Clamp(uvSettings.hardAngle, SerializableUnwrapParam.minHardAngle, SerializableUnwrapParam.maxHardAngle);
            param.packMargin = Mathf.Clamp(uvSettings.packMarginPixels, SerializableUnwrapParam.minPackMargin, SerializableUnwrapParam.maxPackMargin) / 256.0f;

            var oldVertices = generatedMesh.vertices;

            if (oldVertices.Length == 0)
            {
                return;
            }

            // TODO: can we avoid creating a temporary Mesh? if not; make sure CSGSharedUnityMeshManager is handled correctly

            var oldUV        = generatedMesh.uv;
            var oldNormals   = generatedMesh.normals;
            var oldTangents  = generatedMesh.tangents;
            var oldTriangles = generatedMesh.triangles;

            var tempMesh = new Mesh
            {
                vertices  = oldVertices,
                normals   = oldNormals,
                uv        = oldUV,
                tangents  = oldTangents,
                triangles = oldTriangles
            };

            var lightmapGenerationTime = UnityEditor.EditorApplication.timeSinceStartup;

            UnityEditor.Unwrapping.GenerateSecondaryUVSet(tempMesh, param);
            lightmapGenerationTime = UnityEditor.EditorApplication.timeSinceStartup - lightmapGenerationTime;

            // TODO: make a nicer text here
            Debug.Log("Generating lightmap UVs (by Unity) for the mesh '" + generatedMesh.name + "' of the Model named \"" + model.name + "\"\n" +
                      "\tUV generation in " + (lightmapGenerationTime * 1000) + " ms\n", model);

            // Modify the original mesh, since it is shared
            generatedMesh.uv2 = tempMesh.uv2;   // static lightmaps
            generatedMesh.uv3 = tempMesh.uv3;   // real-time lightmaps
            ChiselSharedUnityMeshManager.SetHasLightmapUVs(generatedMesh, true);

            renderComponents.meshFilter.sharedMesh = null;
            renderComponents.meshFilter.sharedMesh = generatedMesh;
            UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(model.gameObject.scene);
        }