예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
        }
예제 #5
0
        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);
        }
예제 #6
0
        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();
        }