public override void Update() { base.begin_update(); int start_timestamp = this.CurrentInputTimestamp; if (MeshSource == null) { throw new Exception("ReprojectOp: must set valid MeshSource to compute!"); } try { if (ReprojectMode == ReprojectModes.SmoothSurfaceFlow) { ResultMesh = compute_smooth(); } else if (ReprojectMode == ReprojectModes.SharpEdgesFlow) { ResultMesh = compute_sharp_edge_flow(); } else { ResultMesh = compute_bounded_distance(); } base.complete_update(); } catch (Exception e) { PostOnOperatorException(e); ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe()); base.complete_update(); } }
public virtual void Update() { base.begin_update(); int start_timestamp = this.CurrentInputTimestamp; if (MeshSource == null) { throw new Exception("GenerateClosedMeshOp: must set valid MeshSource to compute!"); } try { DMesh3 inputmesh = MeshSource.GetDMeshUnsafe(); ISpatial inputSpatial = MeshSource.HasSpatial ? MeshSource.GetSpatial() : null; DMeshAABBTree3 spatial = (inputSpatial != null && inputSpatial is DMeshAABBTree3) ? inputSpatial as DMeshAABBTree3 : get_cached_spatial(inputmesh); DMesh3 meshIn = new DMesh3(inputmesh); MeshRepairOrientation repair = new MeshRepairOrientation(meshIn, spatial); repair.OrientComponents(); repair.SolveGlobalOrientation(); if (invert_result) { meshIn.ReverseOrientation(true); } ResultMesh = meshIn; base.complete_update(); } catch (Exception e) { PostOnOperatorException(e); ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe()); base.complete_update(); } }
public virtual void Update() { base.begin_update(); int start_timestamp = this.CurrentInputTimestamp; if (MeshSource == null) { throw new Exception("GenerateClosedMeshOp: must set valid MeshSource to compute!"); } try { DMesh3 inputmesh = MeshSource.GetDMeshUnsafe(); DMesh3 meshIn = new DMesh3(inputmesh); MeshAutoRepair repair = new MeshAutoRepair(meshIn); repair.RemoveMode = (MeshAutoRepair.RemoveModes)(int) remove_inside_mode; repair.MinEdgeLengthTol = min_edge_length; repair.ErosionIterations = erosion_iters; repair.Progress = new ProgressCancel(is_invalidated); bool bOK = repair.Apply(); if (bOK && invert_result) { meshIn.ReverseOrientation(true); } if (is_invalidated()) { meshIn = null; } if (bOK) { ResultMesh = meshIn; } else { ResultMesh = base.make_failure_output(inputmesh); } base.complete_update(); } catch (Exception e) { PostOnOperatorException(e); ResultMesh = base.make_failure_output(MeshSource.GetDMeshUnsafe()); base.complete_update(); } }
public virtual void Update() { base.begin_update(); int start_timestamp = this.LastUpdateTimestamp; if (MeshSource == null) { throw new Exception("TrimMeshFromCurveOp: must set valid MeshSource to compute!"); } if (CurveSource == null) { throw new Exception("TrimMeshFromCurveOp: must set valid CurveSource to compute!"); } LocalProfiler p = new LocalProfiler(); p.Start("offset"); bool is_preview = false; // cache copy of input mesh and spatial DS DMesh3 inputMesh = MeshSource.GetDMeshUnsafe(); if (cachedInputMesh == null || input_mesh_modified_counter != input_mesh_cache_timestamp) { cachedInputMesh = new DMesh3(inputMesh, false, MeshComponents.All); cachedInputMeshSpatial = new DMeshAABBTree3(cachedInputMesh, true); input_mesh_cache_timestamp = input_mesh_modified_counter; } // have to cache this in case it changes during compute // TODO: should be caching all parameters! cachedInputsTransform = InputsTransform; // discard caches // TODO: we still have a race condition, because we could get an invalidate() between // begin_update() above and here. In that case we will be losing the cache discard flag. // Should be using update timestamp... if (pending_cache_discard) { cached_sdf_max_offset = 0; cached_inner_sdf_offset = 0; cached_outer_sdf_offset = 0; pending_cache_discard = true; } try { //compute_offset_meshes(); compute_offset_meshes_nosdf(); } catch { // we will do nothing here, let later failures handle it } p.Stop("offset"); p.Start("trim"); // trimmed mesh doesn't change unless curve changed... try { compute_trimmed_mesh(); } catch { set_failure_output(null); goto failed; } p.Stop("trim"); p.Start("inner_wall"); try { compute_inner_wall(); } catch { set_failure_output(null); goto failed; } p.Stop("inner_wall"); p.Start("outer_wall"); try { compute_outer_wall(); } catch { set_failure_output(InnerMesh); goto failed; } p.Stop("outer_wall"); p.Start("base"); is_preview = (this.CurrentInputTimestamp != start_timestamp); try { DMesh3 baseMesh = new DMesh3(SocketMesh); bool base_failed = false; do_base(baseMesh, is_preview, out base_failed); if (base_failed) { set_failure_output(SocketMesh); goto failed; } else { SocketMesh = baseMesh; } } catch (Exception e) { set_failure_output(SocketMesh); goto failed; } p.Stop("base"); f3.DebugUtil.Log(p.AllTimes()); Vector3f setColor = is_preview ? PartialSocketVertexColor : SocketVertexColor; foreach (int vid in SocketMesh.VertexIndices()) { SocketMesh.SetVertexColor(vid, setColor); } ResultMesh = SocketMesh; last_result_status = (is_preview) ? ResultStatus.PreviewResult : ResultStatus.FullResult; failed: base.complete_update(); }
protected virtual DMesh3 compute_sharp_edge_flow() { DMesh3 sourceMesh = MeshSource.GetDMeshUnsafe(); ISpatial inputSpatial = MeshSource.GetSpatial(); DMesh3 targetMesh = TargetSource.GetDMeshUnsafe(); ISpatial targetSpatial = TargetSource.GetSpatial(); DMesh3 meshIn = new DMesh3(sourceMesh); if (is_invalidated()) { return(null); } RemesherPro remesher = new RemesherPro(meshIn); remesher.SetTargetEdgeLength(TargetEdgeLength); remesher.PreventNormalFlips = this.PreventNormalFlips; remesher.EnableFlips = this.EnableFlips; remesher.EnableSplits = this.EnableSplits; remesher.EnableCollapses = this.EnableCollapses; remesher.EnableSmoothing = this.EnableSmoothing; remesher.SmoothSpeedT = this.SmoothingSpeed; TransformedMeshProjectionTarget target = new TransformedMeshProjectionTarget(targetMesh, targetSpatial) { SourceToTargetXForm = source_to_target, TargetToSourceXForm = target_to_source }; remesher.SetProjectionTarget(target); if (sourceMesh.CachedIsClosed == false) { if (remesher.Constraints == null) { remesher.SetExternalConstraints(new MeshConstraints()); } if (BoundaryMode == BoundaryModes.FreeBoundaries) { MeshConstraintUtil.PreserveBoundaryLoops(remesher.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.FixedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges(remesher.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.ConstrainedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(remesher.Constraints, meshIn, 0); } } if (is_invalidated()) { return(null); } remesher.Progress = new ProgressCancel(is_invalidated); remesher.SharpEdgeReprojectionRemesh(RemeshRounds, ProjectionRounds); if (is_invalidated()) { return(null); } return(meshIn); }
protected virtual DMesh3 compute_bounded_distance() { DMesh3 sourceMesh = MeshSource.GetDMeshUnsafe(); ISpatial inputSpatial = MeshSource.GetSpatial(); DMesh3 targetMesh = TargetSource.GetDMeshUnsafe(); ISpatial targetSpatial = TargetSource.GetSpatial(); double max_dist = (TargetMaxDistance == double.MaxValue) ? double.MaxValue : TargetMaxDistance; DMesh3 meshIn = new DMesh3(sourceMesh); bool target_closed = targetMesh.IsClosed(); MeshVertexSelection roiV = new MeshVertexSelection(meshIn); SpinLock roi_lock = new SpinLock(); gParallel.ForEach(meshIn.VertexIndices(), (vid) => { Vector3d pos = meshIn.GetVertex(vid); Vector3d posTarget = TransformToTarget.TransformP(pos); double dist = MeshQueries.NearestPointDistance(targetMesh, targetSpatial, posTarget, max_dist); bool inside = (target_closed && targetSpatial.IsInside(posTarget)); if (dist < max_dist || inside) { bool taken = false; roi_lock.Enter(ref taken); roiV.Select(vid); roi_lock.Exit(); } }); if (is_invalidated()) { return(null); } MeshFaceSelection roi_faces = new MeshFaceSelection(meshIn, roiV, 1); roi_faces.ExpandToOneRingNeighbours(3); roi_faces.LocalOptimize(); if (is_invalidated()) { return(null); } RegionOperator op = new RegionOperator(meshIn, roi_faces); DMesh3 meshROI = op.Region.SubMesh; if (is_invalidated()) { return(null); } RemesherPro remesher = new RemesherPro(meshROI); remesher.SetTargetEdgeLength(TargetEdgeLength); remesher.PreventNormalFlips = this.PreventNormalFlips; remesher.EnableFlips = this.EnableFlips; remesher.EnableSplits = this.EnableSplits; remesher.EnableCollapses = this.EnableCollapses; remesher.EnableSmoothing = this.EnableSmoothing; remesher.SmoothSpeedT = this.SmoothingSpeed; BoundedProjectionTarget target = new BoundedProjectionTarget() { Source = sourceMesh, SourceSpatial = inputSpatial, Target = targetMesh, TargetSpatial = targetSpatial, SourceToTargetXForm = source_to_target, TargetToSourceXForm = target_to_source, MaxDistance = max_dist, Smoothness = transition_smoothness }; remesher.SetProjectionTarget(target); if (remesher.Constraints == null) { remesher.SetExternalConstraints(new MeshConstraints()); } MeshConstraintUtil.FixAllBoundaryEdges(remesher.Constraints, meshROI); if (is_invalidated()) { return(null); } remesher.Progress = new ProgressCancel(is_invalidated); remesher.FastestRemesh(RemeshRounds); if (is_invalidated()) { return(null); } op.BackPropropagate(); return(meshIn); }
public virtual void Update() { base.begin_update(); if (MeshSource == null) { throw new Exception("MeshVertexDisplacementOp: must set valid MeshSource to compute!"); } if (DisplacementSource == null) { throw new Exception("MeshVertexDisplacementOp: must set valid DisplacementSource to compute!"); } DMesh3 meshIn = MeshSource.GetDMeshUnsafe(); IVectorDisplacement displace = DisplacementSource.GetDisplacement(); if (displace.Count != 0 && displace.Count != meshIn.MaxVertexID) { throw new Exception("MeshVertexDisplacementOp: inconsistent counts " + displace.Count.ToString() + " != " + meshIn.MaxVertexID.ToString()); } DMesh3 mesh = new DMesh3(meshIn, MeshHints.None); //if (!mesh.HasVertexNormals) // MeshNormals.QuickCompute(mesh); if (displace.Count > 0) { gParallel.ForEach(mesh.VertexIndices(), (vid) => { Vector3d dv = displace.GetDisplacementForIndex(vid); //Vector3f n = mesh.GetVertexNormal(vid); Vector3d v = mesh.GetVertex(vid); v += dv; mesh.SetVertex(vid, v); }); if (enable_heat_map) { // compute max displace len ColorMap map = new ColorMap(); map.AddPoint(0, Colorf.CornflowerBlue); float d = (float)HeatMapMaxDistance; map.AddPoint(d, Colorf.Orange); map.AddPoint(2 * d, Colorf.VideoYellow); map.AddPoint(4 * d, Colorf.VideoRed); map.AddPoint(-d, Colorf.VideoMagenta); float max_displace = d; gParallel.ForEach(mesh.VertexIndices(), (vid) => { Vector3f dv = (Vector3f)displace.GetDisplacementForIndex(vid); Vector3f n = mesh.GetVertexNormal(vid); float sign = n.Dot(dv) > 0 ? 1 : -1; Colorf c = map.Linear(dv.Length * sign); Colorf existing_c = mesh.GetVertexColor(vid); float preserve__max = max_displace / 2; float t = MathUtil.Clamp(dv.Length / preserve__max, 0.0f, 1.0f); c = (1.0f - t) * existing_c + (t) * c; mesh.SetVertexColor(vid, c); //float t = MathUtil.Clamp(dv.Length / max_displace, -1.0f, 1.0f); //mesh.SetVertexColor(vid, t * Colorf.Orange); }); } } MeshNormals.QuickCompute(mesh); DisplacedMesh = mesh; base.complete_update(); }