예제 #1
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("LengthenOp: must set valid MeshSource to compute!");
            }

            IMesh mesh = MeshSource.GetIMesh();

            if (mesh.HasVertexNormals == false)
            {
                throw new Exception("LengthenOp: input mesh does not have surface normals...");
            }

            Displacement.Resize(mesh.MaxVertexID);

            // todo: can do this in parallel
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v    = mesh.GetVertex(vid);
                double   dist = (v - basePt).Dot(direction);
                if (dist < -band_distance)
                {
                    continue;
                }

                dist = Math.Abs(Math.Min(0, dist));
                double falloff_dist = falloff_rate * band_distance;
                double t            = MathUtil.WyvillFalloff(dist, falloff_dist, band_distance);

                Displacement[vid] = t * distance * direction;
            }

            result_valid = true;
        }
예제 #2
0
        public virtual void Update()
        {
            base.begin_update();

            int Nd = Displacements.Count;

            if (Nd == 0)
            {
                for (int i = 0; i < CombinedDisplacement.Count; ++i)
                {
                    CombinedDisplacement[i] = Vector3d.Zero;
                }
                base.complete_update();
                return;
            }


            IVectorDisplacement[] children = new IVectorDisplacement[Nd];
            for (int i = 0; i < Nd; ++i)
            {
                children[i] = Displacements[i].GetDisplacement();
                if (children[i].Count != children[0].Count)
                {
                    throw new Exception("DisplacementCombinerOp.Update: child " + i.ToString() + " Count inconsistent: " + children[i].Count + " != " + children[0].Count);
                }
            }

            int Nv = children[0].Count;

            CombinedDisplacement.Resize(Nv);

            for (int vi = 0; vi < Nv; ++vi)
            {
                Vector3d sum = Vector3d.Zero;
                for (int di = 0; di < Nd; ++di)
                {
                    sum += children[di].GetDisplacementForIndex(vi);
                }

                CombinedDisplacement[vi] = sum;
            }

            base.complete_update();
        }
예제 #3
0
        public virtual void Update()
        {
            base.begin_update();

            if (MeshSource == null)
            {
                throw new Exception("VectorDisplacementMapOp: must set valid MeshSource to compute!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("VectorDisplacementMapOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("VectorDisplacementMapOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3 mesh = imesh as DMesh3;

            lock (Displacement) {
                if (have_set_displacement)
                {
                    lock (set_displacement) {
                        if (set_displacement.Count == mesh.MaxVertexID)
                        {
                            Displacement.Set(set_displacement);
                        }
                        have_set_displacement = false;
                    }
                }
                else if (Displacement.Count != mesh.MaxVertexID)
                {
                    Displacement.Clear();
                    Displacement.Resize(mesh.MaxVertexID);
                }
            }

            base.complete_update();
        }
예제 #4
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("PlaneBandExpansionOp: must set valid MeshSource to compute!");
            }

            IMesh mesh = MeshSource.GetIMesh();

            if (mesh.HasVertexNormals == false)
            {
                throw new Exception("PlaneBandExpansionOp: input mesh does not have surface normals...");
            }

            Displacement.Resize(mesh.MaxVertexID);

            // todo: can do this in parallel
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v    = mesh.GetVertex(vid);
                double   dist = (v - origin).Dot(normal);
                dist = Math.Abs(dist);
                if (dist > band_distance)
                {
                    continue;
                }

                double falloff = MathUtil.WyvillFalloff(dist, band_distance * 0.1, band_distance);

                Vector3d n = mesh.GetVertexNormal(vid);
                n = n - n.Dot(normal) * normal;
                n.Normalize();

                Displacement[vid] = falloff * offset_distance * n;
            }

            result_valid = true;
        }
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("PlaneBandExpansionOp: must set valid MeshSource to compute!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("PlaneBandExpansionOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("RegionOffsetOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3 mesh = imesh as DMesh3;

            IList <int> faces = IndexSource.GetIndices();

            // [RMS] this is all f'n ugly!

            MeshVertexSelection selection = new MeshVertexSelection(mesh);

            selection.SelectTriangleVertices(faces);

            // ugly
            List <Vector2d> seeds = new List <Vector2d>();

            foreach (int vid in selection)
            {
                foreach (int nbrvid in mesh.VtxVerticesItr(vid))
                {
                    if (selection.IsSelected(nbrvid) == false)
                    {
                        seeds.Add(new Vector2d(vid, 0));
                        break;
                    }
                }
            }
            Func <int, int, float> distanceF = (a, b) => { return((float)mesh.GetVertex(a).Distance(mesh.GetVertex(b))); };
            Func <int, bool>       nodeF     = (vid) => { return(selection.IsSelected(vid)); };
            DijkstraGraphDistance  dijkstra  = new DijkstraGraphDistance(mesh.MaxVertexID, true, nodeF, distanceF, mesh.VtxVerticesItr, seeds);

            dijkstra.Compute();
            float maxDist = dijkstra.MaxDistance;


            Displacement.Clear();
            Displacement.Resize(mesh.MaxVertexID);


            // todo: can do this in parallel...
            foreach (int vid in selection)
            {
                //Vector3d v = mesh.GetVertex(vid);

                // [TODO]...
                double dist    = maxDist - dijkstra.GetDistance(vid);
                double falloff = MathUtil.WyvillFalloff(dist, maxDist * 0.0, maxDist);

                Vector3d n = mesh.GetVertexNormal(vid);
                n = n - n.Dot(normal) * normal;
                n.Normalize();

                Displacement[vid] = falloff * offset_distance * n;
            }

            // smooth it?

            result_valid = true;
        }
예제 #6
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("LegSqueezeOp: must set valid MeshSource to compute!");
            }

            IMesh mesh = MeshSource.GetIMesh();

            if (mesh.HasVertexNormals == false)
            {
                throw new Exception("LegSqueezeOp: input mesh does not have surface normals...");
            }

            Displacement.Resize(mesh.MaxVertexID);

            // compute extents along axis
            double     upper_t      = UpperPoint.Dot(Axis);
            Interval1d axis_extents = MeshMeasurements.ExtentsOnAxis(mesh, axis);
            double     lower_t      = axis_extents.a;


            // compute approximate skeleton
            int nVertices = midPoints.Count + 2;

            Vector3d[] centers = new Vector3d[nVertices];
            int[]      counts  = new int[nVertices];
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v    = mesh.GetVertex(vid);
                double   t    = v.Dot(ref axis);
                int      iBin = 0;
                if (t > upper_t)
                {
                    iBin = nVertices - 1;
                }
                else if (t > lower_t)
                {
                    double unit_t = (t - lower_t) / (upper_t - lower_t);
                    iBin = 1;
                    for (int k = 0; k < midPoints.Count; ++k)
                    {
                        if (unit_t > midPoints[k].x)
                        {
                            iBin++;
                        }
                    }
                }   // else iBin = 0, as initialized
                centers[iBin] += v;
                counts[iBin]++;
            }
            for (int k = 0; k < centers.Length; ++k)
            {
                centers[k] /= counts[k];
            }


            // todo: can do this in parallel
            foreach (int vid in mesh.VertexIndices())
            {
                Vector3d v = mesh.GetVertex(vid);
                double   t = v.Dot(axis);
                if (t > upper_t)
                {
                    continue;
                }

                Vector3d center  = centers[0];
                double   percent = 0;

                if (t >= upper_t)
                {
                    percent = reduce_percent_top;
                    center  = centers[nVertices - 1];
                }
                else if (t <= lower_t)
                {
                    percent = reduce_percent_bottom;
                    center  = centers[0];
                }
                else if (midPoints.Count == 0)
                {
                    double unit_t = (t - lower_t) / (upper_t - lower_t);
                    unit_t  = MathUtil.WyvillRise01(unit_t);
                    percent = MathUtil.Lerp(reduce_percent_bottom, reduce_percent_top, unit_t);
                }
                else
                {
                    double   unit_t = (t - lower_t) / (upper_t - lower_t);
                    double   low_percent = reduce_percent_bottom;
                    double   high_percent = reduce_percent_top;
                    Vector3d low_center = centers[0];
                    Vector3d high_center = centers[0];
                    double   low_t = 0.0, high_t = 0;
                    for (int i = 0; i < midPoints.Count; ++i)
                    {
                        if (unit_t < midPoints[i].x)
                        {
                            high_t       = midPoints[i].x;
                            high_percent = midPoints[i].y;
                            high_center  = centers[i + 1];
                            break;
                        }
                        low_t       = midPoints[i].x;
                        low_percent = midPoints[i].y;
                        low_center  = centers[i + 1];
                    }
                    if (high_t == 0)
                    {
                        high_t       = 1.0;
                        high_percent = reduce_percent_top;
                        high_center  = centers[nVertices - 1];
                    }
                    double a = (unit_t - low_t) / (high_t - low_t);
                    a       = MathUtil.WyvillRise01(a);
                    percent = MathUtil.Lerp(low_percent, high_percent, a);
                    center  = Vector3d.Lerp(low_center, high_center, a);
                }

                percent = percent / 100;

                double   scale    = 1.0 - percent;
                Vector3d v_scaled = (v - center) * new Vector3d(scale, 1, scale) + center;
                Displacement[vid] = v_scaled - v;
            }

            result_valid = true;
        }
예제 #7
0
        public virtual void Update()
        {
            if (MeshSource == null)
            {
                throw new Exception("EnclosedRegionOffsetOp: must set valid MeshSource to compute!");
            }
            if (MeshSource.HasSpatial == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: MeshSource must have spatial data structure!");
            }

            IMesh imesh = MeshSource.GetIMesh();

            if (imesh.HasVertexNormals == false)
            {
                throw new Exception("EnclosedRegionOffsetOp: input mesh does not have surface normals...");
            }
            if (imesh is DMesh3 == false)
            {
                throw new Exception("RegionOffsetOp: in current implementation, input mesh must be a DMesh3. Ugh.");
            }
            DMesh3   mesh    = imesh as DMesh3;
            ISpatial spatial = MeshSource.GetSpatial();

            DCurve3           curve = new DCurve3(CurveSource.GetICurve());
            MeshFacesFromLoop loop  = new MeshFacesFromLoop(mesh, curve, spatial);

            // extract submesh
            RegionOperator op      = new RegionOperator(mesh, loop.InteriorTriangles);
            DMesh3         submesh = op.Region.SubMesh;

            // find boundary verts and nbr ring
            HashSet <int> boundaryV    = new HashSet <int>(MeshIterators.BoundaryEdgeVertices(submesh));
            HashSet <int> boundaryNbrs = new HashSet <int>();

            foreach (int vid in boundaryV)
            {
                foreach (int nbrvid in submesh.VtxVerticesItr(vid))
                {
                    if (boundaryV.Contains(nbrvid) == false)
                    {
                        boundaryNbrs.Add(nbrvid);
                    }
                }
            }

            // [TODO] maybe should be not using vertex normal here?
            // use an averaged normal, or a constant for patch?

            // offset mesh if requested
            if (Math.Abs(offset_distance) > 0.0001)
            {
                foreach (int vid in submesh.VertexIndices())
                {
                    if (boundaryV.Contains(vid))
                    {
                        continue;
                    }
                    // if inner ring is non-zero, then it gets preserved below, and
                    // creates a crease...
                    //double dist = boundaryNbrs.Contains(vid) ? (offset_distance / 2) : offset_distance;
                    double dist = boundaryNbrs.Contains(vid) ? 0 : offset_distance;
                    submesh.SetVertex(vid,
                                      submesh.GetVertex(vid) + (float)dist * submesh.GetVertexNormal(vid));
                }
            }


            //double t = MathUtil.Clamp(1.0 - SmoothAlpha, 0.1, 1.0);
            double t = 1.0 - SmoothAlpha;

            t = t * t;
            double boundary_t = 5.0;
            double ring_t     = 1.0;

            // smooth submesh, with boundary-ring constraints
            LaplacianMeshSmoother smoother = new LaplacianMeshSmoother(submesh);

            foreach (int vid in submesh.VertexIndices())
            {
                if (boundaryV.Contains(vid))
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), boundary_t, true);
                }
                else if (boundaryNbrs.Contains(vid))
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), ring_t);
                }
                else
                {
                    smoother.SetConstraint(vid, submesh.GetVertex(vid), t);
                }
            }
            smoother.SolveAndUpdateMesh();


            // turn into displacement vectors
            Displacement.Clear();
            Displacement.Resize(mesh.MaxVertexID);
            foreach (int subvid in op.Region.SubMesh.VertexIndices())
            {
                Vector3d subv    = op.Region.SubMesh.GetVertex(subvid);
                int      basevid = op.Region.SubToBaseV[subvid];
                Vector3d basev   = op.Region.BaseMesh.GetVertex(basevid);
                Displacement[basevid] = subv - basev;
            }


            result_valid = true;
        }