Beispiel #1
0
        private async Task <(string hash, GeometryInfo geoInfo, int resolution)> RebuildPreview(
            IFileSource source, string filePath,
            ConfigVector3?rotation, ConfigVector3?scale,
            string knownHash = null)
        {
            var fileName = Path.GetFileName(filePath);

            var fileBytes = await source
                            .GetFileBytesAsync(filePath)
                            .Timed("Reading file {0}", fileName);

            var(mesh, hash) = await StlImporter
                              .ImportMeshAsync(fileName, fileBytes, computeHash : knownHash == null)
                              .Timed("Imported {0}", fileName);

            var geoInfo = await GeometryInfo.FromMeshAsync(mesh, rotation, scale);

            var(previewData, resolution) = await _previewBuilder
                                           .GetPreviewImageDataAsync(mesh, rotation)
                                           .Timed("Building preview for {0}", fileName);

            StlImporter.Destroy(mesh);

            await _previewStore.StorePreviewAsync(hash ?? knownHash, previewData);

            return(hash, geoInfo, resolution);
        }
Beispiel #2
0
        public static Task <GeometryInfo> FromMeshAsync(Mesh mesh, ConfigVector3?rotation, ConfigVector3?scale)
        {
            var tcs = new TaskCompletionSource <GeometryInfo>();

            GuiCallbackQueue.Enqueue(() =>
            {
                var rot = rotation != null
                    ? (Vector3)rotation.Value
                    : Vector3.zero;

                var scl = scale != null
                    ? (Vector3)scale.Value
                    : Vector3.one;

                var rotated = Quaternion.Euler(rot) * mesh.bounds.size;
                var size    = new Vector3(rotated.x * scl.x, rotated.y * scl.y, rotated.z * scl.z);

                var vertices = mesh.vertices;

                Task.Run(() =>
                {
                    var volume = 0f;
                    for (var i = 0; i < vertices.Length; i += 3)
                    {
                        var a = vertices[i + 0];
                        var b = vertices[i + 1];
                        var c = vertices[i + 2];

                        volume += Vector3.Dot(Vector3.Cross(a, b), c) / 6f;
                    }

                    volume = Mathf.Abs(volume * scl.x * scl.y * scl.z) / 1000f;

                    var info = new GeometryInfo
                    {
                        Rotation      = rot,
                        Scale         = scl,
                        Size          = size,
                        Volume        = volume,
                        VertexCount   = vertices.Length,
                        TriangleCount = vertices.Length / 3
                    };

                    tcs.SetResult(info);
                });
            });

            return(tcs.Task);
        }
Beispiel #3
0
        public ItemPreviewModel AddOrUpdate(IFileSource source, IFileInfo file, PreviewInfo info, GeometryInfo geoInfo)
        {
            var hash = info.FileHash;

            if (!_modelsByHash.TryGetValue(hash, out var model))
            {
                model = _modelsByHash[hash] = new ItemPreviewModel(_store, _relay, info);
                model.GeometryInfo.Value = geoInfo;

                _models.Add(model);
            }

            _sources[source.DisplayName] = source;
            model.AddSourceFile(source.DisplayName, file);

            return(model);
        }