Пример #1
0
            internal double GetTriangleAnglesQuality(g3.DMesh3 mesh)
            {
                Vector3d v0 = Vector3d.Zero, v1 = Vector3d.Zero, v2 = Vector3d.Zero;

                mesh.GetTriVertices(meshIndex, ref v0, ref v1, ref v2);

                Vector3d anglesD = Vector3d.Zero;

                Vector3d e00 = (v1 - v0);

                e00.Normalize();
                Vector3d e01 = (v2 - v0);

                e01.Normalize();
                anglesD.x = Vector3d.AngleD(e00, e01);

                Vector3d e10 = (v0 - v1);

                e10.Normalize();
                Vector3d e11 = (v2 - v1);

                e11.Normalize();
                anglesD.y = Vector3d.AngleD(e10, e11);

                anglesD.z = 180 - anglesD.x - anglesD.y;

                double resultA = Math.Min(Math.Min(Math.Abs(anglesD.x - 90) / 10.0, Math.Abs(anglesD.y - 90) / 10.0), Math.Abs(anglesD.z - 90) / 10.0);

                double resultB = Math.Abs(anglesD.x - 60) / 30.0 + Math.Abs(anglesD.y - 60) / 30.0 + Math.Abs(anglesD.z - 60) / 30.0;

                double result = Math.Min(resultA, resultB);

                return(Math.Pow(result, 3));
            }
Пример #2
0
            internal double CompuateAverageArea(g3.DMesh3 mesh)
            {
                double area = this.TriangleArea(mesh);

                foreach (var n in neighbors)
                {
                    area += n.TriangleArea(mesh);
                }

                area /= (neighbors.Count + 1);

                return(area);
            }
Пример #3
0
            internal bool Randomize(g3.DMesh3 mesh, DMeshAABBTree3 tree, Random r, double max, double moveTries, double average)
            {
                bool result = false;

                for (int i = 0; i < moveTries; i++)
                {
                    result |= this.RandomAdjust(mesh, tree, r, max, moveTries, average);

                    //foreach (var n in neighbors)
                    //    result |= n.RandomAdjust(mesh, tree, r, max, moveTries, average);
                }

                return(result);
            }
Пример #4
0
        public static g3.DMesh3 ConvertToD3Mesh(Rhino.Geometry.Mesh mesh)
        {
            g3.DMesh3 ret = new g3.DMesh3(true, false, false, false);

            if (mesh.Normals.Count < mesh.Vertices.Count)
            {
                mesh.Normals.ComputeNormals();
            }

            if (mesh.Normals.Count != mesh.Vertices.Count)
            {
                return(ret);
            }

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                var vertex = new g3.NewVertexInfo();
                vertex.n = new g3.Vector3f(mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z);
                vertex.v = new g3.Vector3d(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z);
                ret.AppendVertex(vertex);
            }


            foreach (var mf in mesh.Faces)
            {
                if (mf.IsQuad)
                {
                    double dist1 = mesh.Vertices[mf.A].DistanceTo(mesh.Vertices[mf.C]);
                    double dist2 = mesh.Vertices[mf.B].DistanceTo(mesh.Vertices[mf.D]);
                    if (dist1 > dist2)
                    {
                        ret.AppendTriangle(mf.A, mf.B, mf.D);
                        ret.AppendTriangle(mf.B, mf.C, mf.D);
                    }
                    else
                    {
                        ret.AppendTriangle(mf.A, mf.B, mf.C);
                        ret.AppendTriangle(mf.A, mf.C, mf.D);
                    }
                }
                else
                {
                    ret.AppendTriangle(mf.A, mf.B, mf.C);
                }
            }

            return(ret);
        }
Пример #5
0
            double GetNormalQuality(g3.DMesh3 mesh, g3.Vector3d target, int depth)
            {
                if (depth == 0)
                {
                    return(1 - (mesh.GetTriNormal(meshIndex).Dot(target)));
                }

                double amount = GetNormalQuality(mesh, target, 0);

                foreach (var n in neighbors)
                {
                    amount += GetNormalQuality(mesh, target, depth - 1);
                }

                return(amount);
            }
Пример #6
0
            internal double GetTriangleTotalAnglesQualityHelper(g3.DMesh3 mesh, int depth)
            {
                double total = GetTriangleAnglesQuality(mesh);

                if (depth == 0)
                {
                    return(total);
                }

                foreach (var n in neighbors)
                {
                    total += GetTriangleTotalAnglesQualityHelper(mesh, depth - 1);
                }

                return(total / (neighbors.Count + 1));
            }
Пример #7
0
            internal double HowCloseToTargetArea(g3.DMesh3 mesh, double targetArea, int depth)
            {
                double area = Math.Pow(Math.Abs(this.TriangleArea(mesh) - targetArea) / targetArea, 3) * 3;

                if (depth == 0)
                {
                    return(area);
                }

                foreach (var n in neighbors)
                {
                    area += n.HowCloseToTargetArea(mesh, targetArea, depth - 1);
                }

                return(area / (neighbors.Count + 1));
            }
Пример #8
0
        public static Rhino.Geometry.Mesh ConvertToRhinoMesh(g3.DMesh3 largeMesh)
        {
            var mesh = new g3.DMesh3();

            mesh.CompactCopy(largeMesh);

            Rhino.Geometry.Mesh ret = new Rhino.Geometry.Mesh();

            foreach (var p in mesh.Vertices())
            {
                ret.Vertices.Add(new Rhino.Geometry.Point3d(p.x, p.y, p.z));
            }

            ret.Normals.Count = ret.Vertices.Count;

            for (int i = 0; i < ret.Vertices.Count; i++)
            {
                var n = mesh.GetVertexNormal(i);
                ret.Normals[i] = new Rhino.Geometry.Vector3f(n.x, n.y, n.z);
            }


            foreach (var f in mesh.Triangles())
            {
                if (f.a >= 0 && f.a < ret.Vertices.Count &&
                    f.b >= 0 && f.b < ret.Vertices.Count &&
                    f.c >= 0 && f.c < ret.Vertices.Count)
                {
                    ret.Faces.AddFace(new Rhino.Geometry.MeshFace(f.a, f.b, f.c));
                }
                else
                {
                    Rhino.RhinoApp.WriteLine("Error Triangle:" + f.a + "," + f.b + ",", +f.c);
                }
            }

            ret.Normals.ComputeNormals();

            return(ret);
        }
Пример #9
0
 public DSubmesh3(DMesh3 mesh, IEnumerable <int> subTriangles, int nTriEstimate = 0)
 {
     BaseMesh = mesh;
     compute(subTriangles, nTriEstimate);
 }
Пример #10
0
        public static DMesh3 RemeshMesh(g3.DMesh3 mesh, float minEdgeLength, float maxEdgeLength, float contraintAngle, float smoothSpeed, int smoothPasses, List <Line3d> constrainedLines)
        {
            // construct mesh projection target
            DMesh3         meshCopy = new DMesh3(mesh);
            DMeshAABBTree3 tree     = new DMeshAABBTree3(meshCopy);

            tree.Build();
            MeshProjectionTarget target = new MeshProjectionTarget()
            {
                Mesh    = meshCopy,
                Spatial = tree
            };

            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);

                Index2i ev = mesh.GetEdgeV(eid);

                if (fAngle > contraintAngle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));


                    // TODO Ids based off of ?? What?
                    int nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    int nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true, nSetID0));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true, nSetID1));
                }

                Vector3d p1 = mesh.GetVertex(ev.a);
                Vector3d p2 = mesh.GetVertex(ev.b);


                foreach (var v in constrainedLines)
                {
                    if (p1.CompareTo(v.Origin) == 0)
                    {
                        Vector3d p = v.PointAt(1.0);

                        if (p2.CompareTo(p) == 0)
                        {
                            cons.SetOrUpdateEdgeConstraint(eid, EdgeConstraint.FullyConstrained);
                            break;
                        }
                    }
                }

                foreach (var v in constrainedLines)
                {
                    if (p2.CompareTo(v.Origin) == 0)
                    {
                        Vector3d p = v.PointAt(1.0);

                        if (p1.CompareTo(p) == 0)
                        {
                            cons.SetOrUpdateEdgeConstraint(eid, EdgeConstraint.FullyConstrained);
                            break;
                        }
                    }
                }
            }

            Remesher r = new Remesher(mesh);

            r.SetExternalConstraints(cons);
            r.SetProjectionTarget(target);
            r.Precompute();
            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.MinEdgeLength   = minEdgeLength;     //0.1f;
            r.MaxEdgeLength   = maxEdgeLength;     // 0.2f;
            r.EnableSmoothing = true;
            r.SmoothSpeedT    = smoothSpeed;       // .5;
            for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
            {
                r.BasicRemeshPass();
            }
            return(mesh);
        }
Пример #11
0
        //

        public static DMesh3 RemeshMeshNew(g3.DMesh3 mesh, float minEdgeLength, float maxEdgeLength, float contraintAngle, float smoothSpeed, int smoothPasses, g3.DMesh3 projectMeshInput = null, float projectAmount = 1.0f, float projectedDistance = float.MaxValue)
        {
            g3.DMesh3 projectMesh = projectMeshInput;

            if (projectMesh == null)
            {
                projectMesh = mesh;
            }

            DMesh3         projectMeshCopy = new DMesh3(projectMesh);
            DMeshAABBTree3 treeProject     = new DMeshAABBTree3(projectMeshCopy);

            treeProject.Build();
            GopherMeshProjectionTarget targetProject = new GopherMeshProjectionTarget()
            {
                Mesh        = projectMeshCopy,
                Spatial     = treeProject,
                amount      = projectAmount,
                maxDistance = projectedDistance
            };

            MeshConstraints cons     = new MeshConstraints();
            EdgeRefineFlags useFlags = EdgeRefineFlags.NoFlip;

            foreach (int eid in mesh.EdgeIndices())
            {
                double fAngle = MeshUtil.OpeningAngleD(mesh, eid);
                if (fAngle > contraintAngle)
                {
                    cons.SetOrUpdateEdgeConstraint(eid, new EdgeConstraint(useFlags));
                    Index2i ev = mesh.GetEdgeV(eid);
                    //int nSetID0 = (mesh.GetVertex(ev[0]).y > 1) ? 1 : 2;
                    //int nSetID1 = (mesh.GetVertex(ev[1]).y > 1) ? 1 : 2;
                    cons.SetOrUpdateVertexConstraint(ev[0], new VertexConstraint(true));
                    cons.SetOrUpdateVertexConstraint(ev[1], new VertexConstraint(true));
                }
            }

            // TODO Constrain Vertices too far away
            foreach (int vid in mesh.VertexIndices())
            {
                var v = mesh.GetVertex(vid);

                //v.Distance()
                //targetProject.Project()
            }

            Remesher rProjected = new Remesher(mesh);

            rProjected.SetExternalConstraints(cons);
            rProjected.SetProjectionTarget(targetProject);
            rProjected.Precompute();
            rProjected.EnableFlips     = rProjected.EnableSplits = rProjected.EnableCollapses = true;
            rProjected.MinEdgeLength   = minEdgeLength; //0.1f;
            rProjected.MaxEdgeLength   = maxEdgeLength; // 0.2f;
            rProjected.EnableSmoothing = true;
            rProjected.SmoothSpeedT    = smoothSpeed;   // .5;

            if (projectMeshInput != null)
            {
                float bestSmoothPassProjectAmount     = projectAmount / smoothPasses;
                float testbestSmoothPassProjectAmount = float.MaxValue;
                for (float smoothPassProjectAmount = -.1f; smoothPassProjectAmount < 1.1f; smoothPassProjectAmount += 0.005f)
                {
                    double test = 0;

                    for (int i = 0; i < smoothPasses; i++)
                    {
                        test = 1.0 * smoothPassProjectAmount + test * (1 - smoothPassProjectAmount);
                    }

                    if (Math.Abs(test - projectAmount) < Math.Abs(testbestSmoothPassProjectAmount - projectAmount))
                    {
                        bestSmoothPassProjectAmount     = (float)smoothPassProjectAmount;
                        testbestSmoothPassProjectAmount = (float)test;
                    }
                }

                targetProject.amount      = bestSmoothPassProjectAmount;
                targetProject.maxDistance = projectedDistance;

                for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
                {
                    rProjected.BasicRemeshPass();
                }
            }
            else
            {
                for (int k = 0; k < smoothPasses; ++k) // smoothPasses = 20
                {
                    rProjected.BasicRemeshPass();
                }
            }


            return(mesh);
        }
 public LaplacianMeshDeformer(DMesh3 mesh)
 {
     Mesh = mesh;
     Util.gDevAssert(mesh.IsCompact);
 }
Пример #13
0
 internal double TriangleArea(g3.DMesh3 mesh)
 {
     return(mesh.GetTriArea(meshIndex));
 }
Пример #14
0
 public MeshBoundaryLoops(DMesh3 mesh)
 {
     this.Mesh = mesh;
     Compute();
 }
Пример #15
0
 public MeshProjectionTarget(DMesh3 mesh, ISpatial spatial)
 {
     Mesh    = mesh;
     Spatial = spatial;
 }
Пример #16
0
        static List <int> walk_edge_span_forward(DMesh3 mesh, int start_edge, int start_pivot_v, HashSet <int> EdgeSet, out bool bClosedLoop)
        {
            bClosedLoop = false;

            List <int> edgeSpan = new List <int>();

            edgeSpan.Add(start_edge);

            // we update this as we step
            //int cur_edge = start_edge;
            int cur_pivot_v  = start_pivot_v;
            int stop_pivot_v = IndexUtil.find_edge_other_v(mesh.GetEdgeV(start_edge), start_pivot_v);

            Util.gDevAssert(stop_pivot_v != DMesh3.InvalidID);

            bool done = false;

            while (!done)
            {
                // fink outgoing edge in set and connected to current pivot vtx
                int next_edge = -1;
                foreach (int nbr_edge in mesh.VtxEdgesItr(cur_pivot_v))
                {
                    if (EdgeSet.Contains(nbr_edge))
                    {
                        next_edge = nbr_edge;
                        break;
                    }
                }

                // could not find - must be done span
                if (next_edge == -1)
                {
                    done = true;
                    break;
                }

                // figure out next pivot vtx (is 'other' from current pivot on next edge)
                Index2i next_edge_v = mesh.GetEdgeV(next_edge);
                if (next_edge_v.a == cur_pivot_v)
                {
                    cur_pivot_v = next_edge_v.b;
                }
                else if (next_edge_v.b == cur_pivot_v)
                {
                    cur_pivot_v = next_edge_v.a;
                }
                else
                {
                    throw new Exception("walk_edge_span_forward: found valid next edge but not connected to previous vertex??");
                }

                edgeSpan.Add(next_edge);
                EdgeSet.Remove(next_edge);

                // if this happens, we closed a loop
                if (cur_pivot_v == stop_pivot_v)
                {
                    done        = true;
                    bClosedLoop = true;
                }
            }

            return(edgeSpan);
        }
 public MeshIsoCurves(DMesh3 mesh, Func <Vector3d, double> valueF)
 {
     Mesh   = mesh;
     ValueF = valueF;
 }
Пример #18
0
 public Remesher(DMesh3 m) : base(m)
 {
 }
Пример #19
0
        public IndexHashSet BaseBorderV;        // list of border vertex indices on base mesh


        public DSubmesh3(DMesh3 mesh, int[] subTriangles)
        {
            BaseMesh = mesh;
            compute(subTriangles, subTriangles.Length);
        }
 public DMeshIntersectionTarget(DMesh3 mesh, ISpatial spatial)
 {
     Mesh    = mesh;
     Spatial = spatial;
 }
Пример #21
0
            internal bool RandomAdjust(g3.DMesh3 mesh, DMeshAABBTree3 tree, Random r, double max, double moveTries, double targetArea)
            {
                bool moved = false;

                if (this.locked)
                {
                    return(false);
                }

                for (int i = 0; i < moveTries; i++)
                {
                    var v0 = mesh.GetVertex(vertex_index.a);
                    var v1 = mesh.GetVertex(vertex_index.b);
                    var v2 = mesh.GetVertex(vertex_index.c);

                    var v0_old = mesh.GetVertex(vertex_index.a);
                    var v1_old = mesh.GetVertex(vertex_index.b);
                    var v2_old = mesh.GetVertex(vertex_index.c);

                    v0.x += (r.NextDouble() * max * 2 - max);
                    v0.y += (r.NextDouble() * max * 2 - max);
                    v0.z += (r.NextDouble() * max * 2 - max);

                    v1.x += (r.NextDouble() * max * 2 - max);
                    v1.y += (r.NextDouble() * max * 2 - max);
                    v1.z += (r.NextDouble() * max * 2 - max);

                    v2.x += (r.NextDouble() * max * 2 - max);
                    v2.y += (r.NextDouble() * max * 2 - max);
                    v2.z += (r.NextDouble() * max * 2 - max);

                    int tNearestID        = tree.FindNearestTriangle(v0);
                    DistPoint3Triangle3 q = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v0);
                    v0 = q.TriangleClosest;

                    tNearestID = tree.FindNearestTriangle(v1);
                    q          = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v1);
                    v1         = q.TriangleClosest;

                    tNearestID = tree.FindNearestTriangle(v2);
                    q          = MeshQueries.TriangleDistance(tree.Mesh, tNearestID, v2);
                    v2         = q.TriangleClosest;

                    double oldArea = (HowCloseToTargetArea(mesh, targetArea, 2) / targetArea) * 3;

                    double oldAngleQuality = GetTriangleTotalAnglesQualityHelper(mesh, 2);

                    var n = mesh.GetTriNormal(meshIndex);

                    double oldNormalQuality = GetNormalQuality(mesh, n, 2) * 6;

                    mesh.SetVertex(vertex_index.a, v0);
                    mesh.SetVertex(vertex_index.b, v1);
                    mesh.SetVertex(vertex_index.c, v2);

                    double newArea          = (HowCloseToTargetArea(mesh, targetArea, 2) / targetArea) * 3;
                    double newAngleQuality  = GetTriangleTotalAnglesQualityHelper(mesh, 2);
                    double newNormalQuality = GetNormalQuality(mesh, n, 2) * 6;

                    if ((oldArea + oldAngleQuality + oldNormalQuality) < (newArea + newAngleQuality + newNormalQuality))
                    {
                        mesh.SetVertex(vertex_index.a, v0_old);
                        mesh.SetVertex(vertex_index.b, v1_old);
                        mesh.SetVertex(vertex_index.c, v2_old);
                    }
                    else
                    {
                        moved = true;
                    }
                }

                return(moved);
            }
Пример #22
0
        public static bool RandomizeMesh(g3.DMesh3 mesh, out g3.DMesh3 outputMesh, double amount, double moveTries)
        {
            System.Collections.Generic.SortedDictionary <int, MeshNode> faces = new System.Collections.Generic.SortedDictionary <int, MeshNode>();

            int index = 0;

            foreach (var meshFaceIndex in mesh.TriangleIndices())
            {
                var frame = mesh.GetTriFrame(meshFaceIndex);

                g3.Index3i neighbors    = mesh.GetTriNeighbourTris(meshFaceIndex);
                g3.Index3i vertex_index = mesh.GetTriangle(meshFaceIndex);

                faces.Add(meshFaceIndex, new MeshNode(index++, meshFaceIndex, frame, neighbors, vertex_index));
            }

            foreach (var f in faces)
            {
                f.Value.neighbors.Clear();
                f.Value.neighbors.Capacity = 3;
                for (int i = 0; i < 3; ++i)
                {
                    int fn = f.Value.neighbors_index[i];
                    if (fn >= 0)
                    {
                        f.Value.neighbors.Add(faces[fn]);
                    }
                }

                if (f.Value.neighbors.Count < 3)
                {
                    f.Value.locked = true;

                    foreach (var n in f.Value.neighbors)
                    {
                        n.locked = true;
                    }
                }
            }

            DMesh3 projectMeshCopy = new DMesh3(mesh);

            outputMesh = new DMesh3(mesh);

            if (faces.Count == 0)
            {
                return(false);
            }


            DMeshAABBTree3 treeProject = new DMeshAABBTree3(projectMeshCopy);

            treeProject.Build();

            Random r = new Random();

            bool result = false;


            //for (int i = 0; i < moveTries; i++)
            //{
            double faceArea = 0;

            foreach (var f in faces)
            {
                faceArea += f.Value.TriangleArea(outputMesh);
            }

            faceArea /= faces.Count;

            foreach (var f in faces)
            {
                result |= f.Value.Randomize(outputMesh, treeProject, r, amount, moveTries, faceArea);
            }

            double newFaceArea = 0;

            foreach (var f in faces)
            {
                newFaceArea += f.Value.TriangleArea(outputMesh);
            }

            newFaceArea /= faces.Count;

            return(result);
        }
Пример #23
0
 public MeshConnectedComponents(DMesh3 mesh)
 {
     Mesh       = mesh;
     Components = new List <Component>();
 }
Пример #24
0
        public bool Fill()
        {
            compute_polygon();

            // translate/scale fill loops to unit box. This will improve
            // accuracy in the calcs below...
            Vector2d shiftOrigin = Bounds.Center;
            double   scale       = 1.0 / Bounds.MaxDim;

            SpansPoly.Translate(-shiftOrigin);
            SpansPoly.Scale(scale * Vector2d.One, Vector2d.Zero);

            Dictionary <PlanarComplex.Element, int> ElemToLoopMap = new Dictionary <PlanarComplex.Element, int>();

            // generate planar mesh that we will insert polygons into
            MeshGenerator meshgen;
            float         planeW     = 1.5f;
            int           nDivisions = 0;

            if (FillTargetEdgeLen < double.MaxValue && FillTargetEdgeLen > 0)
            {
                int n = (int)((planeW / (float)scale) / FillTargetEdgeLen) + 1;
                nDivisions = (n <= 1) ? 0 : n;
            }

            if (nDivisions == 0)
            {
                meshgen = new TrivialRectGenerator()
                {
                    IndicesMap = new Index2i(1, 2), Width = planeW, Height = planeW,
                };
            }
            else
            {
                meshgen = new GriddedRectGenerator()
                {
                    IndicesMap   = new Index2i(1, 2), Width = planeW, Height = planeW,
                    EdgeVertices = nDivisions
                };
            }
            DMesh3 FillMesh = meshgen.Generate().MakeDMesh();

            FillMesh.ReverseOrientation();   // why?!?

            int[] polyVertices = null;

            // insert each poly
            MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(FillMesh, SpansPoly);
            ValidationStatus      status = insert.Validate(MathUtil.ZeroTolerancef * scale);
            bool failed = true;

            if (status == ValidationStatus.Ok)
            {
                if (insert.Apply())
                {
                    insert.Simplify();
                    polyVertices = insert.CurveVertices;
                    failed       = false;
                }
            }
            if (failed)
            {
                return(false);
            }

            // remove any triangles not contained in gpoly
            // [TODO] degenerate triangle handling? may be 'on' edge of gpoly...
            List <int> removeT = new List <int>();

            foreach (int tid in FillMesh.TriangleIndices())
            {
                Vector3d v = FillMesh.GetTriCentroid(tid);
                if (SpansPoly.Contains(v.xy) == false)
                {
                    removeT.Add(tid);
                }
            }
            foreach (int tid in removeT)
            {
                FillMesh.RemoveTriangle(tid, true, false);
            }

            //Util.WriteDebugMesh(FillMesh, "c:\\scratch\\CLIPPED_MESH.obj");

            // transform fill mesh back to 3d
            MeshTransforms.PerVertexTransform(FillMesh, (v) => {
                Vector2d v2 = v.xy;
                v2         /= scale;
                v2         += shiftOrigin;
                return(to3D(v2));
            });


            //Util.WriteDebugMesh(FillMesh, "c:\\scratch\\PLANAR_MESH_WITH_LOOPS.obj");
            //Util.WriteDebugMesh(MeshEditor.Combine(FillMesh, Mesh), "c:\\scratch\\FILLED_MESH.obj");

            // figure out map between new mesh and original edge loops
            // [TODO] if # of verts is different, we can still find correspondence, it is just harder
            // [TODO] should check that edges (ie sequential verts) are boundary edges on fill mesh
            //    if not, can try to delete nbr tris to repair
            IndexMap mergeMapV = new IndexMap(true);

            if (MergeFillBoundary && polyVertices != null)
            {
                throw new NotImplementedException("PlanarSpansFiller: merge fill boundary not implemented!");

                //int[] fillLoopVerts = polyVertices;
                //int NV = fillLoopVerts.Length;

                //PlanarComplex.Element sourceElem = (pi == 0) ? gsolid.Outer : gsolid.Holes[pi - 1];
                //int loopi = ElemToLoopMap[sourceElem];
                //EdgeLoop sourceLoop = Loops[loopi].edgeLoop;

                //for (int k = 0; k < NV; ++k) {
                //    Vector3d fillV = FillMesh.GetVertex(fillLoopVerts[k]);
                //    Vector3d sourceV = Mesh.GetVertex(sourceLoop.Vertices[k]);
                //    if (fillV.Distance(sourceV) < MathUtil.ZeroTolerancef)
                //        mergeMapV[fillLoopVerts[k]] = sourceLoop.Vertices[k];
                //}
            }

            // append this fill to input mesh
            MeshEditor editor = new MeshEditor(Mesh);

            int[] mapV;
            editor.AppendMesh(FillMesh, mergeMapV, out mapV, Mesh.AllocateTriangleGroup());

            // [TODO] should verify that we actually merged the loops...

            return(true);
        }
Пример #25
0
        // compute distance from point to triangle ti in mesh, with minimal extra objects/etc
        // TODO: take in current-max-distance so we can early-out?
        public static double TriDistanceSqr(DMesh3 mesh, int ti, Vector3d point)
        {
            Vector3d V0 = Vector3d.Zero, V1 = Vector3d.Zero, V2 = Vector3d.Zero;

            mesh.GetTriVertices(ti, ref V0, ref V1, ref V2);

            Vector3d diff  = V0 - point;
            Vector3d edge0 = V1 - V0;
            Vector3d edge1 = V2 - V0;
            double   a00   = edge0.LengthSquared;
            double   a01   = edge0.Dot(edge1);
            double   a11   = edge1.LengthSquared;
            double   b0    = diff.Dot(edge0);
            double   b1    = diff.Dot(edge1);
            double   c     = diff.LengthSquared;
            double   det   = Math.Abs(a00 * a11 - a01 * a01);
            double   s     = a01 * b1 - a11 * b0;
            double   t     = a01 * b0 - a00 * b1;
            double   sqrDistance;

            if (s + t <= det)
            {
                if (s < 0)
                {
                    if (t < 0)   // region 4
                    {
                        if (b0 < 0)
                        {
                            t = 0;
                            if (-b0 >= a00)
                            {
                                s           = 1;
                                sqrDistance = a00 + (2) * b0 + c;
                            }
                            else
                            {
                                s           = -b0 / a00;
                                sqrDistance = b0 * s + c;
                            }
                        }
                        else
                        {
                            s = 0;
                            if (b1 >= 0)
                            {
                                t           = 0;
                                sqrDistance = c;
                            }
                            else if (-b1 >= a11)
                            {
                                t           = 1;
                                sqrDistance = a11 + (2) * b1 + c;
                            }
                            else
                            {
                                t           = -b1 / a11;
                                sqrDistance = b1 * t + c;
                            }
                        }
                    }
                    else     // region 3
                    {
                        s = 0;
                        if (b1 >= 0)
                        {
                            t           = 0;
                            sqrDistance = c;
                        }
                        else if (-b1 >= a11)
                        {
                            t           = 1;
                            sqrDistance = a11 + (2) * b1 + c;
                        }
                        else
                        {
                            t           = -b1 / a11;
                            sqrDistance = b1 * t + c;
                        }
                    }
                }
                else if (t < 0)     // region 5
                {
                    t = 0;
                    if (b0 >= 0)
                    {
                        s           = 0;
                        sqrDistance = c;
                    }
                    else if (-b0 >= a00)
                    {
                        s           = 1;
                        sqrDistance = a00 + (2) * b0 + c;
                    }
                    else
                    {
                        s           = -b0 / a00;
                        sqrDistance = b0 * s + c;
                    }
                }
                else     // region 0
                // minimum at interior point
                {
                    double invDet = (1) / det;
                    s          *= invDet;
                    t          *= invDet;
                    sqrDistance = s * (a00 * s + a01 * t + (2) * b0) +
                                  t * (a01 * s + a11 * t + (2) * b1) + c;
                }
            }
            else
            {
                double tmp0, tmp1, numer, denom;
                if (s < 0)   // region 2
                {
                    tmp0 = a01 + b0;
                    tmp1 = a11 + b1;
                    if (tmp1 > tmp0)
                    {
                        numer = tmp1 - tmp0;
                        denom = a00 - (2) * a01 + a11;
                        if (numer >= denom)
                        {
                            s           = 1;
                            t           = 0;
                            sqrDistance = a00 + (2) * b0 + c;
                        }
                        else
                        {
                            s           = numer / denom;
                            t           = 1 - s;
                            sqrDistance = s * (a00 * s + a01 * t + (2) * b0) +
                                          t * (a01 * s + a11 * t + (2) * b1) + c;
                        }
                    }
                    else
                    {
                        s = 0;
                        if (tmp1 <= 0)
                        {
                            t           = 1;
                            sqrDistance = a11 + (2) * b1 + c;
                        }
                        else if (b1 >= 0)
                        {
                            t           = 0;
                            sqrDistance = c;
                        }
                        else
                        {
                            t           = -b1 / a11;
                            sqrDistance = b1 * t + c;
                        }
                    }
                }
                else if (t < 0)      // region 6
                {
                    tmp0 = a01 + b1;
                    tmp1 = a00 + b0;
                    if (tmp1 > tmp0)
                    {
                        numer = tmp1 - tmp0;
                        denom = a00 - (2) * a01 + a11;
                        if (numer >= denom)
                        {
                            t           = 1;
                            s           = 0;
                            sqrDistance = a11 + (2) * b1 + c;
                        }
                        else
                        {
                            t           = numer / denom;
                            s           = 1 - t;
                            sqrDistance = s * (a00 * s + a01 * t + (2) * b0) +
                                          t * (a01 * s + a11 * t + (2) * b1) + c;
                        }
                    }
                    else
                    {
                        t = 0;
                        if (tmp1 <= 0)
                        {
                            s           = 1;
                            sqrDistance = a00 + (2) * b0 + c;
                        }
                        else if (b0 >= 0)
                        {
                            s           = 0;
                            sqrDistance = c;
                        }
                        else
                        {
                            s           = -b0 / a00;
                            sqrDistance = b0 * s + c;
                        }
                    }
                }
                else      // region 1
                {
                    numer = a11 + b1 - a01 - b0;
                    if (numer <= 0)
                    {
                        s           = 0;
                        t           = 1;
                        sqrDistance = a11 + (2) * b1 + c;
                    }
                    else
                    {
                        denom = a00 - (2) * a01 + a11;
                        if (numer >= denom)
                        {
                            s           = 1;
                            t           = 0;
                            sqrDistance = a00 + (2) * b0 + c;
                        }
                        else
                        {
                            s           = numer / denom;
                            t           = 1 - s;
                            sqrDistance = s * (a00 * s + a01 * t + (2) * b0) +
                                          t * (a01 * s + a11 * t + (2) * b1) + c;
                        }
                    }
                }
            }

            if (sqrDistance < 0)
            {
                sqrDistance = 0;
            }
            return(sqrDistance);
        }
 public GraphSupportGenerator(DMesh3 mesh, DMeshAABBTree3 spatial, double cellSize)
 {
     Mesh = mesh;
     MeshSpatial = spatial;
     CellSize = cellSize;
 }
Пример #27
0
 public Remesher(DMesh3 m)
 {
     mesh = m;
 }
Пример #28
0
        //public static void VoronoiMesh(List<g3.PolyLine3d> mesh, out List<g3.Line3d> listLines, out List<g3.PolyLine3d> listPolylines)
        //{
        //    System.Collections.Generic.SortedDictionary<int, MeshNode> faces = new System.Collections.Generic.SortedDictionary<int, MeshNode>();

        //    int index = 0;
        //    foreach (var meshFaceIndex in mesh.TriangleIndices())
        //    {
        //        var frame = mesh.GetTriFrame(meshFaceIndex);

        //        g3.Index3i neighbors = mesh.GetTriNeighbourTris(meshFaceIndex);
        //        g3.Index3i vertex_index = mesh.GetTriangle(meshFaceIndex);

        //        faces.Add(meshFaceIndex, new MeshNode(index++, meshFaceIndex, frame, neighbors, vertex_index));
        //    }


        //    foreach (var f in faces)
        //    {
        //        f.Value.neighbors.Clear();
        //        f.Value.neighbors.Capacity = 3;
        //        for (int i = 0; i < 3; ++i)
        //        {
        //            int fn = f.Value.neighbors_index[i];
        //            if (fn >= 0)
        //                f.Value.neighbors.Add(faces[fn]);
        //        }

        //        if (f.Value.neighbors.Count < 3)
        //        {
        //            f.Value.locked = true;

        //            foreach (var n in f.Value.neighbors)
        //                n.locked = true;
        //        }
        //    }

        //    outputMesh = new g3.DMesh3(g3.MeshComponents.None);
        //    listLines = new List<g3.Line3d>();
        //    listPolylines = new List<g3.PolyLine3d>();
        //    foreach (var f in faces)
        //    {
        //        outputMesh.AppendVertex(f.Value.frame.Origin);
        //    }

        //    HashSet<int> processedPoints = new HashSet<int>();

        //    foreach (var f in faces)
        //    {
        //        for (int i = 0; i < 3; i++)
        //        {
        //            List<int> outputLine = new List<int>();

        //            if (processedPoints.Contains(f.Value.vertex_index[i]))
        //                continue;

        //            int checkVertex = f.Value.vertex_index[i];

        //            MeshNode currentFaces = f.Value;
        //            MeshNode prevFace = null;

        //            bool fullLoop = false;

        //            while (true)
        //            {
        //                for (int j = 0; j < currentFaces.neighbors.Count; j++)
        //                {

        //                    var neighbor = currentFaces.neighbors[j];
        //                    if (neighbor.UsesVertex(checkVertex))
        //                    {

        //                        if (neighbor == prevFace)
        //                            continue;

        //                        if (neighbor == f.Value)
        //                        {
        //                            fullLoop = true;
        //                            break; // Found full loop
        //                        }

        //                        outputLine.Add(neighbor.index);

        //                        prevFace = currentFaces;
        //                        currentFaces = neighbor;
        //                        j = -1;
        //                    }
        //                }

        //                break;
        //            }

        //            if (fullLoop)
        //            {
        //                processedPoints.Add(checkVertex);

        //                var polyline = new g3.PolyLine3d();

        //                if (outputLine.Count > 2)
        //                {
        //                    g3.Vector3d centerPoint = f.Value.frame.Origin;

        //                    foreach (var p in outputLine)
        //                        centerPoint += outputMesh.GetVertex(p);

        //                    centerPoint /= (outputLine.Count + 1);

        //                    int center = outputMesh.AppendVertex(centerPoint);

        //                    var pS = outputMesh.GetVertex(f.Value.index);
        //                    var p0 = outputMesh.GetVertex(outputLine[0]);
        //                    var pE = outputMesh.GetVertex(outputLine[outputLine.Count - 1]);

        //                    var normal = mesh.GetTriNormal(f.Value.meshIndex);

        //                    polyline.AppendVertex(pS);
        //                    polyline.AppendVertex(p0);

        //                    listLines.Add(new g3.Line3d(pS, p0 - pS));

        //                    var n = MathUtil.Normal(centerPoint, pS, p0);

        //                    bool reverseTri = n.Dot(normal) < 0;

        //                    if (!reverseTri)
        //                        outputMesh.AppendTriangle(center, f.Value.index, outputLine[0]);
        //                    else
        //                        outputMesh.AppendTriangle(center, outputLine[0], f.Value.index);

        //                    for (int j = 0; j < outputLine.Count - 1; j++)
        //                    {
        //                        var p1 = outputMesh.GetVertex(outputLine[j]);
        //                        var p2 = outputMesh.GetVertex(outputLine[j + 1]);

        //                        listLines.Add(new g3.Line3d(p1, p2 - p1));
        //                        polyline.AppendVertex(p2);

        //                        if (!reverseTri)
        //                            outputMesh.AppendTriangle(center, outputLine[j], outputLine[j + 1]);
        //                        else
        //                            outputMesh.AppendTriangle(center, outputLine[j + 1], outputLine[j]);
        //                    }

        //                    polyline.AppendVertex(pS);
        //                    listLines.Add(new g3.Line3d(pE, pS - pE));

        //                    listPolylines.Add(polyline);

        //                    if (!reverseTri)
        //                        outputMesh.AppendTriangle(center, outputLine[outputLine.Count - 1], f.Value.index);
        //                    else
        //                        outputMesh.AppendTriangle(center, f.Value.index, outputLine[outputLine.Count - 1]);
        //                }
        //            }
        //        }

        //    }
        //}

        public static void VoronoiMesh(g3.DMesh3 mesh, out g3.DMesh3 outputMesh, out List <g3.Line3d> listLines, out List <g3.PolyLine3d> listPolylines)
        {
            System.Collections.Generic.SortedDictionary <int, MeshNode> faces = new System.Collections.Generic.SortedDictionary <int, MeshNode>();

            int index = 0;

            foreach (var meshFaceIndex in mesh.TriangleIndices())
            {
                var frame = mesh.GetTriFrame(meshFaceIndex);

                g3.Index3i neighbors    = mesh.GetTriNeighbourTris(meshFaceIndex);
                g3.Index3i vertex_index = mesh.GetTriangle(meshFaceIndex);

                faces.Add(meshFaceIndex, new MeshNode(index++, meshFaceIndex, frame, neighbors, vertex_index));
            }


            foreach (var f in faces)
            {
                f.Value.neighbors.Clear();
                f.Value.neighbors.Capacity = 3;
                for (int i = 0; i < 3; ++i)
                {
                    int fn = f.Value.neighbors_index[i];
                    if (fn >= 0)
                    {
                        f.Value.neighbors.Add(faces[fn]);
                    }
                }

                if (f.Value.neighbors.Count < 3)
                {
                    f.Value.locked = true;

                    foreach (var n in f.Value.neighbors)
                    {
                        n.locked = true;
                    }
                }
            }

            outputMesh    = new g3.DMesh3(g3.MeshComponents.None);
            listLines     = new List <g3.Line3d>();
            listPolylines = new List <g3.PolyLine3d>();
            foreach (var f in faces)
            {
                outputMesh.AppendVertex(f.Value.frame.Origin);
            }

            HashSet <int> processedPoints = new HashSet <int>();

            foreach (var f in faces)
            {
                for (int i = 0; i < 3; i++)
                {
                    List <int> outputLine = new List <int>();

                    if (processedPoints.Contains(f.Value.vertex_index[i]))
                    {
                        continue;
                    }

                    int checkVertex = f.Value.vertex_index[i];

                    MeshNode currentFaces = f.Value;
                    MeshNode prevFace     = null;

                    bool fullLoop = false;

                    while (true)
                    {
                        for (int j = 0; j < currentFaces.neighbors.Count; j++)
                        {
                            var neighbor = currentFaces.neighbors[j];
                            if (neighbor.UsesVertex(checkVertex))
                            {
                                if (neighbor == prevFace)
                                {
                                    continue;
                                }

                                if (neighbor == f.Value)
                                {
                                    fullLoop = true;
                                    break; // Found full loop
                                }

                                outputLine.Add(neighbor.index);

                                prevFace     = currentFaces;
                                currentFaces = neighbor;
                                j            = -1;
                            }
                        }

                        break;
                    }

                    if (fullLoop)
                    {
                        processedPoints.Add(checkVertex);

                        var polyline = new g3.PolyLine3d();

                        if (outputLine.Count > 2)
                        {
                            g3.Vector3d centerPoint = f.Value.frame.Origin;

                            foreach (var p in outputLine)
                            {
                                centerPoint += outputMesh.GetVertex(p);
                            }

                            centerPoint /= (outputLine.Count + 1);

                            int center = outputMesh.AppendVertex(centerPoint);

                            var pS = outputMesh.GetVertex(f.Value.index);
                            var p0 = outputMesh.GetVertex(outputLine[0]);
                            var pE = outputMesh.GetVertex(outputLine[outputLine.Count - 1]);

                            var normal = mesh.GetTriNormal(f.Value.meshIndex);

                            polyline.AppendVertex(pS);
                            polyline.AppendVertex(p0);

                            listLines.Add(new g3.Line3d(pS, p0 - pS));

                            var n = MathUtil.Normal(centerPoint, pS, p0);

                            bool reverseTri = n.Dot(normal) < 0;

                            if (!reverseTri)
                            {
                                outputMesh.AppendTriangle(center, f.Value.index, outputLine[0]);
                            }
                            else
                            {
                                outputMesh.AppendTriangle(center, outputLine[0], f.Value.index);
                            }

                            for (int j = 0; j < outputLine.Count - 1; j++)
                            {
                                var p1 = outputMesh.GetVertex(outputLine[j]);
                                var p2 = outputMesh.GetVertex(outputLine[j + 1]);

                                listLines.Add(new g3.Line3d(p1, p2 - p1));
                                polyline.AppendVertex(p2);

                                if (!reverseTri)
                                {
                                    outputMesh.AppendTriangle(center, outputLine[j], outputLine[j + 1]);
                                }
                                else
                                {
                                    outputMesh.AppendTriangle(center, outputLine[j + 1], outputLine[j]);
                                }
                            }

                            polyline.AppendVertex(pS);
                            listLines.Add(new g3.Line3d(pE, pS - pE));

                            listPolylines.Add(polyline);

                            if (!reverseTri)
                            {
                                outputMesh.AppendTriangle(center, outputLine[outputLine.Count - 1], f.Value.index);
                            }
                            else
                            {
                                outputMesh.AppendTriangle(center, f.Value.index, outputLine[outputLine.Count - 1]);
                            }
                        }
                    }
                }
            }
        }
Пример #29
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            bool bHavePreselectedObjects = false;

            const ObjectType geometryFilter = ObjectType.MeshFace;

            OptionDouble  minEdgeLengthOption     = new OptionDouble(minEdgeLength, 0.001, 200);
            OptionDouble  maxEdgeLengthOption     = new OptionDouble(maxEdgeLength, 0.001, 200);
            OptionDouble  constriantAngleOption   = new OptionDouble(constriantAngle, 0.001, 360);
            OptionInteger smoothStepsOptions      = new OptionInteger(smoothSteps, 0, 100);
            OptionDouble  smoothSpeedOption       = new OptionDouble(smoothSpeed, 0.01, 1.0);
            OptionDouble  projectAmountOption     = new OptionDouble(projectedAmount, 0.01, 1.0);
            OptionDouble  projectedDistanceOption = new OptionDouble(projectedDistance, 0.01, 100000.0);

            GetObject go = new GetObject();

            go.SetCommandPrompt("Select mesh faces to project onto another mesh");
            go.GeometryFilter = geometryFilter;

            go.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            go.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            go.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            go.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            go.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);

            go.GroupSelect     = true;
            go.SubObjectSelect = true;

            for (; ;)
            {
                GetResult faceres = go.GetMultiple(1, 0);

                if (faceres == GetResult.Option)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

                else if (go.CommandResult() != Result.Success)
                {
                    return(go.CommandResult());
                }

                if (go.ObjectsWerePreselected)
                {
                    bHavePreselectedObjects = true;
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            minEdgeLength   = minEdgeLengthOption.CurrentValue;
            maxEdgeLength   = maxEdgeLengthOption.CurrentValue;
            constriantAngle = constriantAngleOption.CurrentValue;
            smoothSteps     = smoothStepsOptions.CurrentValue;
            smoothSpeed     = smoothSpeedOption.CurrentValue;

            //System.Collections.Generic.List<System.Guid> meshes = new System.Collections.Generic.List<System.Guid>();

            System.Guid rhinoMesh = System.Guid.Empty;

            System.Collections.Generic.List <int> removeFaces = new System.Collections.Generic.List <int>();

            g3.DMesh3 projectFaces = new g3.DMesh3(true, false, false, false);

            Rhino.Geometry.Mesh rhinoInputMesh = new Rhino.Geometry.Mesh();

            for (int i = 0; i < go.ObjectCount; i++)
            {
                ObjRef obj = go.Object(i);

                if (rhinoMesh == System.Guid.Empty)
                {
                    rhinoMesh      = obj.ObjectId;
                    rhinoInputMesh = obj.Mesh();

                    for (int j = 0; j < rhinoInputMesh.Vertices.Count; j++)
                    {
                        var vertex = new g3.NewVertexInfo();
                        vertex.n = new g3.Vector3f(rhinoInputMesh.Normals[j].X, rhinoInputMesh.Normals[j].Y, rhinoInputMesh.Normals[j].Z);
                        vertex.v = new g3.Vector3d(rhinoInputMesh.Vertices[j].X, rhinoInputMesh.Vertices[j].Y, rhinoInputMesh.Vertices[j].Z);
                        projectFaces.AppendVertex(vertex);
                    }
                }

                var m = rhinoInputMesh;

                if (rhinoMesh != obj.ObjectId)
                {
                    continue;
                }

                removeFaces.Add(obj.GeometryComponentIndex.Index);

                var mf = rhinoInputMesh.Faces[obj.GeometryComponentIndex.Index];


                if (mf.IsQuad)
                {
                    double dist1 = m.Vertices[mf.A].DistanceTo(m.Vertices[mf.C]);
                    double dist2 = m.Vertices[mf.B].DistanceTo(m.Vertices[mf.D]);
                    if (dist1 > dist2)
                    {
                        projectFaces.AppendTriangle(mf.A, mf.B, mf.D);
                        projectFaces.AppendTriangle(mf.B, mf.C, mf.D);
                    }
                    else
                    {
                        projectFaces.AppendTriangle(mf.A, mf.B, mf.C);
                        projectFaces.AppendTriangle(mf.A, mf.C, mf.D);
                    }
                }
                else
                {
                    projectFaces.AppendTriangle(mf.A, mf.B, mf.C);
                }
            }

            if (rhinoInputMesh == null)
            {
                return(Result.Failure);
            }

            removeFaces.Sort();
            removeFaces.Reverse();

            foreach (var removeFace in removeFaces)
            {
                rhinoInputMesh.Faces.RemoveAt(removeFace);
            }

            rhinoInputMesh.Compact();

            GetObject goProjected = new GetObject();

            goProjected.EnablePreSelect(false, true);
            goProjected.SetCommandPrompt("Select mesh to project to");
            goProjected.GeometryFilter = ObjectType.Mesh;
            goProjected.AddOptionDouble("ConstraintAngle", ref constriantAngleOption);
            goProjected.AddOptionDouble("MinEdge", ref minEdgeLengthOption);
            goProjected.AddOptionDouble("MaxEdge", ref maxEdgeLengthOption);
            goProjected.AddOptionInteger("SmoothSteps", ref smoothStepsOptions);
            goProjected.AddOptionDouble("SmoothSpeed", ref smoothSpeedOption);
            goProjected.AddOptionDouble("ProjectAmount", ref projectAmountOption);
            goProjected.AddOptionDouble("ProjectDistance", ref projectedDistanceOption);

            goProjected.GroupSelect     = true;
            goProjected.SubObjectSelect = false;
            goProjected.EnableClearObjectsOnEntry(false);
            goProjected.EnableUnselectObjectsOnExit(false);


            for (; ;)
            {
                GetResult resProject = goProjected.Get();

                if (resProject == GetResult.Option)
                {
                    continue;
                }
                else if (goProjected.CommandResult() != Result.Success)
                {
                    return(goProjected.CommandResult());
                }

                break;
            }


            minEdgeLength     = minEdgeLengthOption.CurrentValue;
            maxEdgeLength     = maxEdgeLengthOption.CurrentValue;
            constriantAngle   = constriantAngleOption.CurrentValue;
            smoothSteps       = smoothStepsOptions.CurrentValue;
            smoothSpeed       = smoothSpeedOption.CurrentValue;
            projectedAmount   = projectAmountOption.CurrentValue;
            projectedDistance = projectedDistanceOption.CurrentValue;

            if (bHavePreselectedObjects)
            {
                // Normally, pre-selected objects will remain selected, when a
                // command finishes, and post-selected objects will be unselected.
                // This this way of picking, it is possible to have a combination
                // of pre-selected and post-selected. So, to make sure everything
                // "looks the same", lets unselect everything before finishing
                // the command.
                for (int i = 0; i < go.ObjectCount; i++)
                {
                    RhinoObject rhinoObject = go.Object(i).Object();
                    if (null != rhinoObject)
                    {
                        rhinoObject.Select(false);
                    }
                }
                doc.Views.Redraw();
            }

            bool result = false;

            if (goProjected.ObjectCount < 1)
            {
                return(Result.Failure);
            }


            var rhinoMeshProject = goProjected.Object(0).Mesh();

            if (rhinoMeshProject == null || !rhinoMeshProject.IsValid)
            {
                return(Result.Failure);
            }

            var meshProjected = GopherUtil.ConvertToD3Mesh(rhinoMeshProject);

            var res = GopherUtil.RemeshMesh(projectFaces, (float)minEdgeLength, (float)maxEdgeLength, (float)constriantAngle, (float)smoothSpeed, smoothSteps, meshProjected, (float)projectedAmount, (float)projectedDistance);

            var newRhinoMesh = GopherUtil.ConvertToRhinoMesh(res);

            if (newRhinoMesh != null && newRhinoMesh.IsValid)
            {
                newRhinoMesh.Append(rhinoInputMesh);

                result |= doc.Objects.Replace(rhinoMesh, newRhinoMesh);
            }

            doc.Views.Redraw();

            return(Result.Success);
        }
Пример #30
0
 public PlanarSpansFiller(DMesh3 mesh, IList <EdgeSpan> spans)
 {
     Mesh      = mesh;
     FillSpans = new List <EdgeSpan>(spans);
     Bounds    = AxisAlignedBox2d.Empty;
 }