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); }
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); }
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); }