/// <summary> /// transfer source mesh to target /// TODO: more efficiencies /// </summary> static void replace_single(DMeshSO target, DMeshSO source) { ReplaceEntireMeshChange replaceChange = new ReplaceEntireMeshChange(target, new DMesh3(target.Mesh), source.Mesh); CC.ActiveScene.History.PushChange(replaceChange, false); }
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 }