public async Task StoreMesh(IObject3D object3D, bool publishAfterSave, CancellationToken cancellationToken, Action <double, string> progress = null) { if (object3D.Mesh == Object3D.FileMissingMesh) { return; } // In memory mesh is always saved to stl string tempStlPath = CreateNewLibraryPath(".stl"); // Save the embedded asset to disk bool savedSuccessfully = StlProcessing.Save( object3D.Mesh, tempStlPath, CancellationToken.None, new MeshOutputSettings(MeshOutputSettings.OutputType.Binary)); if (savedSuccessfully) { // There's currently no way to know the actual mesh file hashcode without saving it to disk, thus we save at least once in // order to compute the hash but then throw away the duplicate file if an existing copy exists in the assets directory string assetPath = await this.StoreFile(tempStlPath, publishAfterSave, cancellationToken, progress); // Remove the temp file if (File.Exists(tempStlPath)) { File.Delete(tempStlPath); } // Update MeshPath with Assets relative filename object3D.MeshPath = Path.GetFileName(assetPath); } }
public async Task StoreMesh(IObject3D object3D, bool publishAfterSave, CancellationToken cancellationToken, Action <double, string> progress = null) { if (object3D.Mesh == Object3D.FileMissingMesh) { return; } var memoryStream = new MemoryStream(); // Save the embedded asset to a memory stream bool savedSuccessfully = StlProcessing.Save( object3D.Mesh, memoryStream, CancellationToken.None, new MeshOutputSettings(MeshOutputSettings.OutputType.Binary), true); if (savedSuccessfully) { // reset the memory stream to the start memoryStream.Position = 0; // save the asset to the asset store string assetPath = await this.StoreStream(memoryStream, ".stl", publishAfterSave, cancellationToken, progress); // Update MeshPath with Assets relative filename object3D.MeshPath = Path.GetFileName(assetPath); } memoryStream.Close(); }
public static Mesh Do(Mesh transformedKeep, Mesh transformedRemove, int opperation, IProgress <ProgressStatus> reporter, double amountPerOperation, double percentCompleted, ProgressStatus progressStatus, CancellationToken cancellationToken) { var libiglExe = "libigl_boolean.exe"; if (File.Exists(libiglExe) && IntPtr.Size == 8) // only try to run the improved booleans if we are 64 bit and it is there { string folderToSaveStlsTo = Path.Combine(ApplicationDataStorage.Instance.ApplicationTempDataPath, "amf_to_stl"); // Create directory if needed Directory.CreateDirectory(folderToSaveStlsTo); string stlFileA = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl")); StlProcessing.Save(transformedKeep, stlFileA, CancellationToken.None); string stlFileB = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl")); StlProcessing.Save(transformedRemove, stlFileB, CancellationToken.None); // wait for files to close Thread.Sleep(1000); string stlFileResult = Path.Combine(folderToSaveStlsTo, Path.ChangeExtension(Path.GetRandomFileName(), ".stl")); // if we have the libigl_boolean.exe var opperationString = "-"; switch (opperation) { case 0: opperationString = "+"; break; case 1: opperationString = "-"; break; case 2: opperationString = "&"; break; } var slicerProcess = new Process() { StartInfo = new ProcessStartInfo() { Arguments = "{0} {1} {2} {3}".FormatWith(stlFileA, stlFileB, stlFileResult, opperationString), CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardError = true, RedirectStandardOutput = true, FileName = libiglExe, UseShellExecute = false } }; slicerProcess.Start(); slicerProcess.WaitForExit(); // wait for file to close Thread.Sleep(1000); // load up the var result = StlProcessing.Load(stlFileResult, CancellationToken.None); if (result != null) { return(result); } } switch (opperation) { case 0: return(PolygonMesh.Csg.CsgOperations.Union(transformedKeep, transformedRemove, (status, progress0To1) => { // Abort if flagged cancellationToken.ThrowIfCancellationRequested(); progressStatus.Status = status; progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1; reporter.Report(progressStatus); }, cancellationToken)); case 1: return(PolygonMesh.Csg.CsgOperations.Subtract(transformedKeep, transformedRemove, (status, progress0To1) => { // Abort if flagged cancellationToken.ThrowIfCancellationRequested(); progressStatus.Status = status; progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1; reporter?.Report(progressStatus); }, cancellationToken)); case 2: return(PolygonMesh.Csg.CsgOperations.Intersect(transformedKeep, transformedRemove, (status, progress0To1) => { // Abort if flagged cancellationToken.ThrowIfCancellationRequested(); progressStatus.Status = status; progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1; reporter.Report(progressStatus); }, cancellationToken)); } return(null); }