Exemplo n.º 1
0
        public int AppendVertex(NewVertexInfo info)
        {
            int i = Vertices.Length / 3;

            if (info.bHaveN && HasVertexNormals)
            {
                Normals.Add(info.n[0]); Normals.Add(info.n[1]); Normals.Add(info.n[2]);
            }
            else if (HasVertexNormals)
            {
                Normals.Add(0); Normals.Add(1); Normals.Add(0);
            }
            if (info.bHaveC && HasVertexColors)
            {
                Colors.Add(info.c[0]); Colors.Add(info.c[1]); Colors.Add(info.c[2]);
            }
            else if (HasVertexColors)
            {
                Colors.Add(1); Colors.Add(1); Colors.Add(1);
            }
            if (info.bHaveUV && HasVertexUVs)
            {
                UVs.Add(info.uv[0]); UVs.Add(info.uv[1]);
            }
            else if (HasVertexUVs)
            {
                UVs.Add(0); UVs.Add(0);
            }

            Vertices.Add(info.v[0]); Vertices.Add(info.v[1]); Vertices.Add(info.v[2]);
            return(i);
        }
Exemplo n.º 2
0
 public void MakeMesh(DMesh3 m)
 {
     int nV = vertices.Count;
     for (int i = 0; i < nV; ++i) {
         NewVertexInfo ni = new NewVertexInfo() { v = vertices[i] };
         if ( WantNormals ) {
             ni.bHaveN = true;
             ni.n = normals[i];
         }
         if ( WantUVs ) {
             ni.bHaveUV = true;
             ni.uv = uv[i];
         }
         int vID = m.AppendVertex(ni);
         Util.gDevAssert(vID == i);
     }
     int nT = triangles.Count;
     if (WantGroups && groups != null && groups.Length == nT) {
         for (int i = 0; i < nT; ++i)
             m.AppendTriangle(triangles[i], groups[i]);
     } else {
         for (int i = 0; i < nT; ++i)
             m.AppendTriangle(triangles[i]);
     }
 }
Exemplo n.º 3
0
 public bool GetVertex(int vID, ref NewVertexInfo vinfo, bool bWantNormals, bool bWantColors, bool bWantUVs)
 {
     if (vertices_refcount.isValid(vID) == false)
     {
         return(false);
     }
     vinfo.v.Set(vertices[3 * vID], vertices[3 * vID + 1], vertices[3 * vID + 2]);
     vinfo.bHaveN = vinfo.bHaveUV = vinfo.bHaveC = false;
     if (HasVertexColors && bWantNormals)
     {
         vinfo.bHaveN = true;
         vinfo.n.Set(normals[3 * vID], normals[3 * vID + 1], normals[3 * vID + 2]);
     }
     if (HasVertexColors && bWantColors)
     {
         vinfo.bHaveC = true;
         vinfo.c.Set(colors[3 * vID], colors[3 * vID + 1], colors[3 * vID + 2]);
     }
     if (HasVertexUVs && bWantUVs)
     {
         vinfo.bHaveUV = true;
         vinfo.uv.Set(uv[2 * vID], uv[2 * vID + 1]);
     }
     return(true);
 }
Exemplo n.º 4
0
        public NewVertexInfo GetVertexAll(int i)
        {
            NewVertexInfo vi = new NewVertexInfo();

            vi.v = GetVertex(i);
            if (HasVertexNormals)
            {
                vi.bHaveN = true;
                vi.n      = GetVertexNormal(i);
            }
            else
            {
                vi.bHaveN = false;
            }
            if (HasVertexColors)
            {
                vi.bHaveC = true;
                vi.c      = GetVertexColor(i);
            }
            else
            {
                vi.bHaveC = false;
            }
            if (HasVertexUVs)
            {
                vi.bHaveUV = true;
                vi.uv      = GetVertexUV(i);
            }
            else
            {
                vi.bHaveUV = false;
            }
            return(vi);
        }
Exemplo n.º 5
0
        //public void CopyTo(SimpleMesh mTo)
        //{
        //    mTo.Vertices = Util.BufferCopy(this.Vertices, mTo.Vertices);
        //    mTo.Normals = Util.BufferCopy(this.Normals, mTo.Normals);
        //    mTo.Colors = Util.BufferCopy(this.Colors, mTo.Colors);
        //    mTo.Triangles = Util.BufferCopy(this.Triangles, mTo.Triangles);
        //    mTo.FaceGroups = Util.BufferCopy(this.FaceGroups, mTo.FaceGroups);
        //}

        //public object Clone()
        //{
        //    SimpleMesh mTo = new SimpleMesh();
        //    this.CopyTo(mTo);
        //    return mTo;
        //}

        public SimpleMesh(IMesh copy)
        {
            Initialize(copy.HasVertexNormals, copy.HasVertexColors, copy.HasVertexUVs, copy.HasTriangleGroups);
            int[] mapV = new int[copy.MaxVertexID];
            foreach (int vid in copy.VertexIndices())
            {
                NewVertexInfo vi      = copy.GetVertexAll(vid);
                int           new_vid = AppendVertex(vi);
                mapV[vid] = new_vid;
            }
            foreach (int tid in copy.TriangleIndices())
            {
                Index3i t = copy.GetTriangle(tid);
                t[0] = mapV[t[0]];
                t[1] = mapV[t[1]];
                t[2] = mapV[t[2]];
                if (copy.HasTriangleGroups)
                {
                    AppendTriangle(t[0], t[1], t[2], copy.GetTriangleGroup(tid));
                }
                else
                {
                    AppendTriangle(t[0], t[1], t[2]);
                }
            }
        }
Exemplo n.º 6
0
        private int append_vertex(IMeshBuilder builder, Vector3d vtx, Vector3f norm, Vector3f cols, Vector2f uvs, bool bHaveNormals, bool bHaveColors, bool bHaveUVs)
        {
            if (bHaveNormals == false && bHaveColors == false && bHaveUVs == false)
            {
                return(builder.AppendVertex(vtx.x, vtx.y, vtx.z));
            }

            NewVertexInfo vinfo = new NewVertexInfo();

            vinfo.bHaveC = vinfo.bHaveN = vinfo.bHaveUV = false;
            vinfo.v      = vtx;
            if (bHaveNormals)
            {
                vinfo.bHaveN = true;
                vinfo.n      = norm;
            }
            if (bHaveColors)
            {
                vinfo.bHaveC = true;
                vinfo.c      = cols;
            }
            if (bHaveUVs)
            {
                vinfo.bHaveUV = true;
                vinfo.uv      = uvs;
            }

            return(builder.AppendVertex(vinfo));
        }
Exemplo n.º 7
0
        public bool AppendMesh(IMesh appendMesh, IndexMap mergeMapV, out int[] mapV, int appendGID = -1)
        {
            mapV = new int[appendMesh.MaxVertexID];
            foreach (int vid in appendMesh.VertexIndices())
            {
                if (mergeMapV.Contains(vid))
                {
                    mapV[vid] = mergeMapV[vid];
                }
                else
                {
                    NewVertexInfo vinfo  = appendMesh.GetVertexAll(vid);
                    int           newvid = Mesh.AppendVertex(vinfo);
                    mapV[vid] = newvid;
                }
            }

            foreach (int tid in appendMesh.TriangleIndices())
            {
                Index3i t = appendMesh.GetTriangle(tid);
                t.a = mapV[t.a];
                t.b = mapV[t.b];
                t.c = mapV[t.c];
                int gid = appendMesh.GetTriangleGroup(tid);
                if (appendGID >= 0)
                {
                    gid = appendGID;
                }
                Mesh.AppendTriangle(t, gid);
            }

            return(true);
        }
Exemplo n.º 8
0
        public void Apply(DMesh3 mesh)
        {
            int NV = AddedV.size;

            if (NV > 0)
            {
                NewVertexInfo vinfo = new NewVertexInfo(Positions[0]);
                mesh.BeginUnsafeVerticesInsert();
                for (int i = 0; i < NV; ++i)
                {
                    int vid = AddedV[i];
                    vinfo.v = Positions[i];
                    if (Normals != null)
                    {
                        vinfo.bHaveN = true; vinfo.n = Normals[i];
                    }
                    if (Colors != null)
                    {
                        vinfo.bHaveC = true; vinfo.c = Colors[i];
                    }
                    if (UVs != null)
                    {
                        vinfo.bHaveUV = true; vinfo.uv = UVs[i];
                    }
                    MeshResult result = mesh.InsertVertex(vid, ref vinfo, true);
                    if (result != MeshResult.Ok)
                    {
                        throw new Exception("AddTrianglesMeshChange.Revert: error in InsertVertex(" + vid.ToString() + "): " + result.ToString());
                    }
                }
                mesh.EndUnsafeVerticesInsert();
            }

            int NT = AddedT.size;

            if (NT > 0)
            {
                mesh.BeginUnsafeTrianglesInsert();
                for (int i = 0; i < NT; ++i)
                {
                    int        tid    = AddedT[i];
                    Index4i    tdata  = Triangles[i];
                    Index3i    tri    = new Index3i(tdata.a, tdata.b, tdata.c);
                    MeshResult result = mesh.InsertTriangle(tid, tri, tdata.d, true);
                    if (result != MeshResult.Ok)
                    {
                        throw new Exception("AddTrianglesMeshChange.Revert: error in InsertTriangle(" + tid.ToString() + "): " + result.ToString());
                    }
                }
                mesh.EndUnsafeTrianglesInsert();
            }

            if (OnApplyF != null)
            {
                OnApplyF(AddedV, AddedT);
            }
        }
        public void Generate()
        {
            append_mesh();

            AxisAlignedBox3i bounds = Voxels.GridBounds;

            bounds.Max -= Vector3i.One;

            int[] vertices = new int[4];

            foreach (Vector3i nz in Voxels.NonZeros())
            {
                check_counts_or_append(6, 2);

                Box3d cube = Box3d.UnitZeroCentered;
                cube.Center = (Vector3d)nz;

                for (int fi = 0; fi < 6; ++fi)
                {
                    // checks dependent on neighbours
                    Index3i nbr = nz + gIndices.GridOffsets6[fi];
                    if (bounds.Contains(nbr))
                    {
                        if (SkipInteriorFaces && Voxels.Get(nbr))
                        {
                            continue;
                        }
                    }
                    else if (CapAtBoundary == false)
                    {
                        continue;
                    }


                    int           ni = gIndices.BoxFaceNormals[fi];
                    Vector3f      n  = (Vector3f)(Math.Sign(ni) * cube.Axis(Math.Abs(ni) - 1));
                    NewVertexInfo vi = new NewVertexInfo(Vector3d.Zero, n);
                    if (ColorSourceF != null)
                    {
                        vi.c      = ColorSourceF(nz);
                        vi.bHaveC = true;
                    }
                    for (int j = 0; j < 4; ++j)
                    {
                        vi.v        = cube.Corner(gIndices.BoxFaces[fi, j]);
                        vertices[j] = cur_mesh.AppendVertex(vi);
                    }

                    Index3i t0 = new Index3i(vertices[0], vertices[1], vertices[2], Clockwise);
                    Index3i t1 = new Index3i(vertices[0], vertices[2], vertices[3], Clockwise);
                    cur_mesh.AppendTriangle(t0);
                    cur_mesh.AppendTriangle(t1);
                }
            }
        }
Exemplo n.º 10
0
        public virtual void MakeMesh(DMesh3 m)
        {
            int  nV           = vertices.Count;
            bool bWantNormals = WantNormals && normals != null && normals.Count == vertices.Count;

            if (bWantNormals)
            {
                m.EnableVertexNormals(Vector3f.AxisY);
            }

            bool bWantUVs = WantUVs && uv != null && uv.Count == vertices.Count;

            if (bWantUVs)
            {
                m.EnableVertexUVs(Vector2f.Zero);
            }

            for (int i = 0; i < nV; ++i)
            {
                var ni = new NewVertexInfo()
                {
                    v = vertices[i]
                };
                if (bWantNormals)
                {
                    ni.bHaveN = true;
                    ni.n      = normals[i];
                }
                if (bWantUVs)
                {
                    ni.bHaveUV = true;
                    ni.uv      = uv[i];
                }
                int vID = m.AppendVertex(ni);
                Util.gDevAssert(vID == i);
            }
            int nT = triangles.Count;

            if (WantGroups && groups != null && groups.Length == nT)
            {
                m.EnableTriangleGroups();
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i], groups[i]);
                }
            }
            else
            {
                for (int i = 0; i < nT; ++i)
                {
                    m.AppendTriangle(triangles[i]);
                }
            }
        }
Exemplo n.º 11
0
        int append_duplicate_triangle(int i, int j, int k, int g)
        {
            var vinfo = new NewVertexInfo();

            Meshes[nActiveMesh].GetVertex(i, ref vinfo, true, true, true);
            int new_i = Meshes[nActiveMesh].AppendVertex(vinfo);

            Meshes[nActiveMesh].GetVertex(j, ref vinfo, true, true, true);
            int new_j = Meshes[nActiveMesh].AppendVertex(vinfo);

            Meshes[nActiveMesh].GetVertex(k, ref vinfo, true, true, true);
            int new_k = Meshes[nActiveMesh].AppendVertex(vinfo);

            return(Meshes[nActiveMesh].AppendTriangle(new_i, new_j, new_k, g));
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        public void CompactCopy(DMesh3 copy, bool bNormals = true, bool bColors = true, bool bUVs = true)
        {
            if (copy.IsCompact)
            {
                Copy(copy, bNormals, bColors, bUVs);
                return;
            }

            vertices           = new DVector <double>();
            vertex_edges       = new DVector <List <int> >();
            vertices_refcount  = new RefCountVector();
            triangles          = new DVector <int>();
            triangle_edges     = new DVector <int>();
            triangles_refcount = new RefCountVector();
            edges          = new DVector <int>();
            edges_refcount = new RefCountVector();

            normals = (bNormals && copy.normals != null) ? new DVector <float>() : null;
            colors  = (bColors && copy.colors != null) ? new DVector <float>() : null;
            uv      = (bUVs && copy.uv != null) ? new DVector <float>() : null;

            // [TODO] if we knew some of these were dense we could copy directly...

            NewVertexInfo vinfo = new NewVertexInfo();

            int[] mapV = new int[copy.MaxVertexID];
            foreach (int vid in copy.vertices_refcount)
            {
                copy.GetVertex(vid, ref vinfo, bNormals, bColors, bUVs);
                mapV[vid] = AppendVertex(vinfo);
            }

            // [TODO] would be much faster to explicitly copy triangle & edge data structures!!

            foreach (int tid in copy.triangles_refcount)
            {
                Index3i t = copy.GetTriangle(tid);
                t.a = mapV[t.a]; t.b = mapV[t.b]; t.c = mapV[t.c];
                int g = (copy.HasTriangleGroups) ? copy.GetTriangleGroup(tid) : InvalidID;
                AppendTriangle(t, g);
            }
        }
Exemplo n.º 14
0
        int append_vertex(IMeshBuilder builder, vtx_key vk, bool bHaveNormals, bool bHaveColors, bool bHaveUVs)
        {
            int vi = 3 * vk.vi;

            if (vk.vi < 0 || vk.vi >= vPositions.Length / 3)
            {
                emit_warning("[OBJReader] append_vertex() referencing invalid vertex " + vk.vi.ToString());
                return(-1);
            }

            if (bHaveNormals == false && bHaveColors == false && bHaveUVs == false)
            {
                return(builder.AppendVertex(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2]));
            }

            NewVertexInfo vinfo = new NewVertexInfo();

            vinfo.bHaveC = vinfo.bHaveN = vinfo.bHaveUV = false;
            vinfo.v      = new Vector3d(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2]);
            if (bHaveNormals)
            {
                vinfo.bHaveN = true;
                int ni = 3 * vk.ni;
                vinfo.n = new Vector3f(vNormals[ni], vNormals[ni + 1], vNormals[ni + 2]);
            }
            if (bHaveColors)
            {
                vinfo.bHaveC = true;
                int ci = 3 * vk.ci;
                vinfo.c = new Vector3f(vColors[ci], vColors[ci + 1], vColors[ci + 2]);
            }
            if (bHaveUVs)
            {
                vinfo.bHaveUV = true;
                int ui = 2 * vk.ui;
                vinfo.uv = new Vector2f(vUVs[ui], vUVs[ui + 1]);
            }

            return(builder.AppendVertex(vinfo));
        }
Exemplo n.º 15
0
        int append_vertex(IMeshBuilder builder, Index3i vertIdx, bool bHaveNormals, bool bHaveColors, bool bHaveUVs)
        {
            int vi = 3 * vertIdx.a;

            if (vertIdx.a < 0 || vertIdx.a >= vPositions.Length / 3)
            {
                emit_warning("[OBJReader] append_vertex() referencing invalid vertex " + vertIdx.a.ToString());
                return(-1);
            }

            if (bHaveNormals == false && bHaveColors == false && bHaveUVs == false)
            {
                return(builder.AppendVertex(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2]));
            }

            var vinfo = new NewVertexInfo();

            vinfo.bHaveC = vinfo.bHaveN = vinfo.bHaveUV = false;
            vinfo.v      = new Vector3d(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2]);
            if (bHaveNormals)
            {
                vinfo.bHaveN = true;
                int ni = 3 * vertIdx.b;
                vinfo.n = new Vector3f(vNormals[ni], vNormals[ni + 1], vNormals[ni + 2]);
            }
            if (bHaveColors)
            {
                vinfo.bHaveC = true;
                vinfo.c      = new Vector3f(vColors[vi], vColors[vi + 1], vColors[vi + 2]);
            }
            if (bHaveUVs)
            {
                vinfo.bHaveUV = true;
                int ui = 2 * vertIdx.c;
                vinfo.uv = new Vector2f(vUVs[ui], vUVs[ui + 1]);
            }

            return(builder.AppendVertex(vinfo));
        }
Exemplo n.º 16
0
        public bool AppendMesh(IMesh appendMesh)
        {
            int[] mapV = new int[appendMesh.MaxVertexID];
            foreach (int vid in appendMesh.VertexIndices())
            {
                NewVertexInfo vinfo  = appendMesh.GetVertexAll(vid);
                int           newvid = Mesh.AppendVertex(vinfo);
                mapV[vid] = newvid;
            }

            foreach (int tid in appendMesh.TriangleIndices())
            {
                Index3i t = appendMesh.GetTriangle(tid);
                t.a = mapV[t.a];
                t.b = mapV[t.b];
                t.c = mapV[t.c];
                int gid = appendMesh.GetTriangleGroup(tid);
                Mesh.AppendTriangle(t, gid);
            }

            return(true);
        }
Exemplo n.º 17
0
        public int AppendVertex(NewVertexInfo info)
        {
            int vid = vertices_refcount.allocate();
            int i   = 3 * vid;

            vertices.insert(info.v[2], i + 2);
            vertices.insert(info.v[1], i + 1);
            vertices.insert(info.v[0], i);

            if (normals != null)
            {
                Vector3f n = (info.bHaveN) ? info.n : Vector3f.AxisY;
                normals.insert(n[2], i + 2);
                normals.insert(n[1], i + 1);
                normals.insert(n[0], i);
            }

            if (colors != null)
            {
                Vector3f c = (info.bHaveC) ? info.c : Vector3f.One;
                colors.insert(c[2], i + 2);
                colors.insert(c[1], i + 1);
                colors.insert(c[0], i);
            }

            if (uv != null)
            {
                Vector2f u = (info.bHaveUV) ? info.uv : Vector2f.Zero;
                int      j = 2 * vid;
                uv.insert(u[1], j + 1);
                uv.insert(u[0], j);
            }

            vertex_edges.insert(new List <int>(), vid);

            updateTimeStamp();
            return(vid);
        }
Exemplo n.º 18
0
 public int AppendVertex(NewVertexInfo info)
 {
     return(Meshes[nActiveMesh].AppendVertex(info));
 }
Exemplo n.º 19
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);
        }