public static void DoMeshExport(string sFilename) { if (sFilename != null && sFilename.Length > 0) { if (string.IsNullOrEmpty(Path.GetExtension(sFilename))) { sFilename = sFilename + ".obj"; } List <DMeshSO> exportSOs = new List <DMeshSO>(); foreach (var so in CC.ActiveScene.Selected) { if (so is PrintMeshSO && CC.ActiveScene.IsVisible(so)) { exportSOs.Add(so as PrintMeshSO); } } if (exportSOs.Count == 0) { exportSOs.AddRange(CC.Objects.PrintMeshes.Where(CC.ActiveScene.IsVisible).Cast <DMeshSO>()); } MeshExporter exporter = new MeshExporter(exportSOs, sFilename); exporter.OnCompletedF = (result) => { if (result.code == IOCode.Ok) { DebugUtil.Log("Export OK"); ThreadMailbox.PostToMainThread(() => { CotangentAnalytics.ExportMesh(sFilename); }); } else { DebugUtil.Log("Export ERROR: " + result.message); } }; FPlatform.CoroutineExec.StartAnonymousCoroutine(exporter.RunMainThreadProcessing()); } }
public void FillAllHoles() { if (IsComputing) { return; } is_computing = true; List <EdgeLoop> cur_loops = new List <EdgeLoop>(Loops.Loops); Task.Run((Action)(() => { var use_fill_type = FillType; DMesh3 filled_mesh = (DMesh3)previewSO.SafeMeshRead((mesh) => { return(new DMesh3(mesh)); }); try_fills_again: if (cancel_background_task) { return; } foreach (EdgeLoop loop in cur_loops) { if (cancel_background_task) { return; } try { // skip loops that have been filled if (loop.IsBoundaryLoop(filled_mesh) == false) { continue; } switch (use_fill_type) { case FillTypes.Trivial: fill_trivial(filled_mesh, loop); break; case FillTypes.Minimal: fill_minimal(filled_mesh, loop); break; case FillTypes.Smooth: fill_smooth(filled_mesh, loop); break; } } catch (Exception e) { DebugUtil.Log("FillHolesTool.FillAllHoles: Exception: " + e.Message); // ignore-and-continue for now } } // recompute loops in case any failed MeshBoundaryLoops loops = new MeshBoundaryLoops(filled_mesh, true); // if any did fail, fall back to simpler fills in second pass if (loops.Count > 0 && use_fill_type != FillTypes.Trivial) { if (use_fill_type == FillTypes.Smooth) { use_fill_type = FillTypes.Minimal; } else { use_fill_type = FillTypes.Trivial; } cur_loops = new List <EdgeLoop>(loops.Loops); goto try_fills_again; } if (cancel_background_task) { return; } ReplaceEntireMeshChange change = new ReplaceEntireMeshChange(previewSO, previewSO.Mesh, filled_mesh); ThreadMailbox.PostToMainThread((Action)(() => { this.Scene.History.PushChange(change, false); this.Scene.History.PushInteractionCheckpoint(); })); is_computing = false; })); // end task }
public bool ImportAutoUpdate(PrintMeshSO so) { SourceFilePath = so.SourceFilePath; if (!File.Exists(SourceFilePath)) { ErrorMessage = "MeshImporter.ImportAutoUpdate: file does not exist"; return(false); } DMesh3Builder builder = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = builder }; long timestamp = File.GetLastWriteTime(SourceFilePath).Ticks; IOReadResult result = reader.Read(SourceFilePath, ReadOptions.Defaults); if (result.code != IOCode.Ok) { ErrorMessage = "MeshImporter.ImportAutoUpdate: failed with message " + result.message; return(false); } if (builder.Meshes.Count == 0) { ErrorMessage = "MeshImporter.ImportAutoUpdate: no meshes in file!"; return(false); } if (builder.Meshes.Count != 1) { ErrorMessage = "MeshImporter.ImportAutoUpdate: can only auto-update from file with single mesh!"; return(false); } DMesh3 mesh = builder.Meshes[0]; // unity xforms MeshTransforms.ConvertZUpToYUp(mesh); MeshTransforms.FlipLeftRightCoordSystems(mesh); // wait for any active tools to finish // [TODO] do we need to do this? while (CC.ActiveContext.ToolManager.HasActiveTool()) { Thread.Sleep(1000); } if (CC.ActiveScene.SceneObjects.Contains(so) == false) { ErrorMessage = "MeshImporter.ImportAutoUpdate: SO no longer exists"; return(false); } // change event?? so.LastReadFileTimestamp = timestamp; ThreadMailbox.PostToMainThread(() => { so.ReplaceMesh(mesh, true); }); return(true); }