Example #1
0
        public static void TestRhinoInside()
        {
            // RhinoCommon code
            var plane  = Rhino.Geometry.Plane.WorldXY;
            var sphere = new Rhino.Geometry.Sphere(plane, 5.0);
            //var mesh = Rhino.Geometry.Mesh.CreateIcoSphere(sphere, 3);
            var mesh = Rhino.Geometry.Mesh.CreateQuadSphere(sphere, 3);

            // Get the current document and database, and start a transaction
            var document = Application.DocumentManager.MdiActiveDocument;
            var database = document.Database;

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                // Open the Block table record for read
                var block_table = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;

                // Open the Block table record Model space for write
                var block_table_record = transaction.GetObject(block_table[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                // Create a polyface mesh
                using (var poly_face_mesh = new PolyFaceMesh())
                {
                    // Add the new object to the block table record and the transaction
                    block_table_record.AppendEntity(poly_face_mesh);
                    transaction.AddNewlyCreatedDBObject(poly_face_mesh, true);

                    // Before adding vertexes, the polyline must be in the drawing
                    var points_collection = new Point3dCollection();
                    foreach (var v in mesh.Vertices)
                    {
                        points_collection.Add(new Point3d(v.X, v.Y, v.Z));
                    }

                    // Add mesh vertices
                    foreach (Point3d point in points_collection)
                    {
                        var mesh_vertex = new PolyFaceMeshVertex(point);
                        poly_face_mesh.AppendVertex(mesh_vertex);
                        transaction.AddNewlyCreatedDBObject(mesh_vertex, true);
                    }

                    // Add mesh faces. Note, BricsCAD face vertex indices start at 1, not 0.
                    foreach (var f in mesh.Faces)
                    {
                        using (var face_record = new FaceRecord((short)(f.A + 1), (short)(f.B + 1), (short)(f.C + 1), (short)(f.D + 1)))
                        {
                            poly_face_mesh.AppendFaceRecord(face_record);
                            transaction.AddNewlyCreatedDBObject(face_record, true);
                        }
                    }
                }

                document.Editor.UpdateTiledViewportsFromDatabase();

                transaction.Commit();
            }
        }
Example #2
0
        /// <summary> 将多面网格转换为细分网格 </summary>
        public static PolyFaceMesh ConvertToPolyFaceMesh(this SubDMesh subDMesh, BlockTableRecord btr, Transaction trans)
        {
            // 创建多面网格
            var acPFaceMesh = new PolyFaceMesh();

            // 将新对象添加到块表记录和事务
            btr.AppendEntity(acPFaceMesh);
            trans.AddNewlyCreatedDBObject(acPFaceMesh, true);
            // 添加顶点前,必须先将多边形网格添加到块表记录

            foreach (Point3d acPt3d in subDMesh.Vertices)
            {
                var acPMeshVer = new PolyFaceMeshVertex(acPt3d);
                acPFaceMesh.AppendVertex(acPMeshVer);
                trans.AddNewlyCreatedDBObject(acPMeshVer, true);
            }

            // FaceRecord constructor initializes the FaceRecord to use the mesh vertices specified by the indices vertex0 through vertex3 as the four corner points of the face. The vertex indices start with 1. Negative index numbers can be used to indicate that the edge that starts at that vertex is to be invisible.
            // If the face this FaceRecord is to represent has only three vertices, then set vertex3 to 0.
            var        faceVertices = subDMesh.FaceArray.ToArray();
            var        anchorIndex  = 0;
            FaceRecord faceRec;

            while (anchorIndex < faceVertices.Length)
            {
                var verCount = faceVertices[anchorIndex];
                if (verCount == 3)
                {
                    // 构造一个三角面
                    faceRec = new FaceRecord(
                        (short)(faceVertices[anchorIndex + 1] + 1),
                        (short)(faceVertices[anchorIndex + 2] + 1),
                        (short)(faceVertices[anchorIndex + 3] + 1),
                        0);
                }
                else if (verCount == 4)
                {
                    // 构造一个四边形的面
                    faceRec = new FaceRecord(
                        (short)(faceVertices[anchorIndex + 1] + 1),
                        (short)(faceVertices[anchorIndex + 2] + 1),
                        (short)(faceVertices[anchorIndex + 3] + 1),
                        (short)(faceVertices[anchorIndex + 4] + 1));
                }
                else
                {
                    throw new InvalidOperationException("网格中只能有三角形或者四边形");
                }
                // 添加到数据库中
                acPFaceMesh.AppendFaceRecord(faceRec);
                trans.AddNewlyCreatedDBObject(faceRec, true);
                // 下一个面的集合下标
                anchorIndex += verCount + 1;
            }
            return(acPFaceMesh);
        }
Example #3
0
        public void DrawSurface()
        {
            if (!CheckLicense.Check())
            {
                return;
            }

            Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            Topography topo = Topography.Instance;

            Topography.SurfaceType surface = Topography.PickSurface();
            if (surface == Topography.SurfaceType.None)
            {
                return;
            }
            if (!Topography.EnsureSurfaceNotEmpty(surface))
            {
                return;
            }
            TriangleNet.Mesh mesh = (surface == Topography.SurfaceType.Original ? topo.OriginalTIN : topo.ProposedTIN);

            // Object type
            PromptKeywordOptions opts = new PromptKeywordOptions("\nÇizim nesneleri [Geçici/3dFace/Point/polyfaceMesh] <Geçici>: ", "Temporary 3dFace Point polyfaceMesh");

            opts.Keywords.Default = "Temporary";
            opts.AllowNone        = true;
            PromptResult res        = doc.Editor.GetKeywords(opts);
            string       outputType = res.StringResult;

            if (res.Status == PromptStatus.None)
            {
                outputType = "Temporary";
            }
            else if (res.Status != PromptStatus.OK)
            {
                return;
            }

            // Color option
            opts = new PromptKeywordOptions("\nRenkli çizim [E/H] <E>: ", "Yes No");
            opts.Keywords.Default = "Yes";
            opts.AllowNone        = true;
            res = doc.Editor.GetKeywords(opts);
            bool useColor = true;

            if (res.Status == PromptStatus.None)
            {
                useColor = true;
            }
            else if (res.Status != PromptStatus.OK)
            {
                return;
            }
            else
            {
                useColor = (string.Compare(res.StringResult, "Yes", StringComparison.OrdinalIgnoreCase) == 0);
            }
            double zmin = double.MaxValue; double zmax = double.MinValue;

            foreach (TriangleNet.Data.Vertex v in mesh.Vertices)
            {
                zmin = Math.Min(zmin, v.Attributes[0]);
                zmax = Math.Max(zmax, v.Attributes[0]);
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
                using (BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite))
                {
                    try
                    {
                        if (string.Compare(outputType, "Temporary", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            EraseTemporaryGraphics();
                            foreach (TriangleNet.Data.Triangle tri in mesh.Triangles)
                            {
                                TriangleNet.Data.Vertex v1 = tri.GetVertex(0);
                                TriangleNet.Data.Vertex v2 = tri.GetVertex(1);
                                TriangleNet.Data.Vertex v3 = tri.GetVertex(2);
                                Face face = new Face(new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), true, true, true, true);
                                if (useColor)
                                {
                                    face.Color = ColorFromZ((v1.Attributes[0] + v2.Attributes[0] + v3.Attributes[0]) / 3, zmin, zmax);
                                }
                                temporaryGraphics.Add(face);
                            }
                            DrawTemporaryGraphics();
                        }
                        else if (string.Compare(outputType, "3dFace", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            foreach (TriangleNet.Data.Triangle tri in mesh.Triangles)
                            {
                                TriangleNet.Data.Vertex v1 = tri.GetVertex(0);
                                TriangleNet.Data.Vertex v2 = tri.GetVertex(1);
                                TriangleNet.Data.Vertex v3 = tri.GetVertex(2);
                                Face face = new Face(new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), true, true, true, true);
                                if (useColor)
                                {
                                    face.Color = ColorFromZ((v1.Attributes[0] + v2.Attributes[0] + v3.Attributes[0]) / 3, zmin, zmax);
                                }

                                btr.AppendEntity(face);
                                tr.AddNewlyCreatedDBObject(face, true);
                            }
                        }
                        else if (string.Compare(outputType, "Point", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            foreach (TriangleNet.Data.Vertex v in mesh.Vertices)
                            {
                                DBPoint point = new DBPoint(new Point3d(v.X, v.Y, v.Attributes[0]));
                                if (useColor)
                                {
                                    point.Color = ColorFromZ(v.Attributes[0], zmin, zmax);
                                }

                                btr.AppendEntity(point);
                                tr.AddNewlyCreatedDBObject(point, true);
                            }
                        }
                        else if (string.Compare(outputType, "polyfaceMesh", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            PolyFaceMesh pfm = new PolyFaceMesh();
                            btr.AppendEntity(pfm);
                            tr.AddNewlyCreatedDBObject(pfm, true);

                            // Vertices
                            SortedDictionary <int, Point3d> vertices = new SortedDictionary <int, Point3d>();
                            foreach (TriangleNet.Data.Vertex v in mesh.Vertices)
                            {
                                vertices.Add(v.ID, new Point3d(v.X, v.Y, v.Attributes[0]));
                            }
                            foreach (KeyValuePair <int, Point3d> v in vertices)
                            {
                                PolyFaceMeshVertex point = new PolyFaceMeshVertex(v.Value);
                                pfm.AppendVertex(point);
                                tr.AddNewlyCreatedDBObject(point, true);
                            }

                            // Faces
                            foreach (TriangleNet.Data.Triangle tri in mesh.Triangles)
                            {
                                FaceRecord face = new FaceRecord((short)(tri.P0 + 1), (short)(tri.P1 + 1), (short)(tri.P2 + 1), 0);
                                if (useColor)
                                {
                                    face.Color = ColorFromZ((tri.GetVertex(0).Attributes[0] + tri.GetVertex(1).Attributes[0] + tri.GetVertex(2).Attributes[0]) / 3, zmin, zmax);
                                }
                                pfm.AppendFaceRecord(face);
                                tr.AddNewlyCreatedDBObject(face, true);
                            }
                        }
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("Error: " + ex.ToString(), "XCOM", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    tr.Commit();
                }
        }
Example #4
0
        public static void CreatePolyfaceMesh()
        {
            // 获取当前文档和数据库,启动事务
            var acDoc   = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            var acCurDb = acDoc.Database;

            using (var acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // 以读模式打开块表
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                             OpenMode.ForRead) as BlockTable;

                // 以写模式打开块表记录模型空间
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                OpenMode.ForWrite) as BlockTableRecord;

                // 创建多面网格
                var acPFaceMesh = new PolyFaceMesh();

                // 将新对象添加到块表记录和事务
                acBlkTblRec.AppendEntity(acPFaceMesh);
                acTrans.AddNewlyCreatedDBObject(acPFaceMesh, true);

                // 添加顶点前,必须先将多边形网格添加到块表记录
                var acPts3dPFMesh = new Point3dCollection();
                acPts3dPFMesh.Add(new Point3d(4, 7, 0));
                acPts3dPFMesh.Add(new Point3d(5, 7, 0));
                acPts3dPFMesh.Add(new Point3d(6, 7, 0));

                acPts3dPFMesh.Add(new Point3d(4, 6, 0));
                acPts3dPFMesh.Add(new Point3d(5, 6, 0));
                acPts3dPFMesh.Add(new Point3d(6, 6, 1));

                foreach (Point3d acPt3d in acPts3dPFMesh)
                {
                    var acPMeshVer = new PolyFaceMeshVertex(acPt3d);
                    acPFaceMesh.AppendVertex(acPMeshVer);
                    acTrans.AddNewlyCreatedDBObject(acPMeshVer, true);
                }

                // FaceRecord constructor initializes the FaceRecord to use the mesh vertices specified by the indices vertex0 through vertex3 as the four corner points of the face. The vertex indices start with 1. Negative index numbers can be used to indicate that the edge that starts at that vertex is to be invisible.
                // If the face this FaceRecord is to represent has only three vertices, then set vertex3 to 0.
                FaceRecord acFaceRec1 = new FaceRecord(1, 4, 5, 2);
                acPFaceMesh.AppendFaceRecord(acFaceRec1);
                acTrans.AddNewlyCreatedDBObject(acFaceRec1, true);

                var acFaceRec2 = new FaceRecord(2, 5, 6, 0);
                acFaceRec2.MakeEdgeInvisibleAt(3); //设置第4个顶点开始的边不可见
                acPFaceMesh.AppendFaceRecord(acFaceRec2);
                acTrans.AddNewlyCreatedDBObject(acFaceRec2, true);

                // 打开当前视口
                ViewportTableRecord acVportTblRec;
                acVportTblRec = acTrans.GetObject(acDoc.Editor.ActiveViewportId,
                                                  OpenMode.ForWrite) as ViewportTableRecord;

                // 旋转当前视口的观察方向
                acVportTblRec.ViewDirection = new Vector3d(-1, -1, 1);
                acDoc.Editor.UpdateTiledViewportsFromDatabase();

                // 提交事务
                acTrans.Commit();
            }
        }
Example #5
0
        public void TriangulateCommand()
        {
            const double maxpoints = 1000000;
            Document     doc       = Application.DocumentManager.MdiActiveDocument;
            Database     db        = doc.Database;
            Editor       ed        = doc.Editor;

            TypedValue[]           tvs = { new TypedValue(0, "POINT") };
            SelectionFilter        sf  = new SelectionFilter(tvs);
            PromptSelectionOptions pso = new PromptSelectionOptions();

            pso.MessageForAdding = "Select Points:";
            pso.AllowDuplicates  = false;
            PromptSelectionResult psr = ed.GetSelection(pso, sf);

            if (psr.Status == PromptStatus.Error)
            {
                return;
            }
            if (psr.Status == PromptStatus.Cancel)
            {
                return;
            }
            SelectionSet ss   = psr.Value;
            int          npts = ss.Count;

            if (npts < 3)
            {
                ed.WriteMessage("Minimum 3 points must be selected!");
                return;
            }
            if (npts > maxpoints)
            {
                ed.WriteMessage("Maximum nuber of points exceeded!");
                return;
            }
            int  i, j, k, ntri, ned, status1 = 0, status2 = 0;
            bool status;

            // Point coordinates

            double[] ptx = new double[Convert.ToInt64(maxpoints + 3)];
            double[] pty = new double[Convert.ToInt64(maxpoints + 3)];
            double[] ptz = new double[Convert.ToInt64(maxpoints + 3)];

            // Triangle definitions
            int[] pt1 = new int[Convert.ToInt64(maxpoints * 2 + 1)];
            int[] pt2 = new int[Convert.ToInt64(maxpoints * 2 + 1)];
            int[] pt3 = new int[Convert.ToInt64(maxpoints * 2 + 1)];
            // Circumscribed circle
            double[] cex = new double[Convert.ToInt64(maxpoints * 2 + 1)];
            double[] cey = new double[Convert.ToInt64(maxpoints * 2 + 1)];
            double[] rad = new double[Convert.ToInt64(maxpoints * 2 + 1)];
            double   xmin, ymin, xmax, ymax, dx, dy, xmid, ymid;

            int[]       ed1     = new int[Convert.ToInt64(maxpoints * 2 + 1)];
            int[]       ed2     = new int[Convert.ToInt64(maxpoints * 2 + 1)];
            ObjectId[]  idarray = ss.GetObjectIds();
            Transaction tr      = db.TransactionManager.StartTransaction();

            using (tr)
            {
                DBPoint ent;
                k = 0;
                for (i = 0; i < npts; i++)
                {
                    ent    = (DBPoint)tr.GetObject(idarray[k], OpenMode.ForRead, false);
                    ptx[i] = ent.Position[0];
                    pty[i] = ent.Position[1];
                    ptz[i] = ent.Position[2];
                    for (j = 0; j < i; j++)
                    {
                        if ((ptx[i] == ptx[j]) && (pty[i] == pty[j]))
                        {
                            i--;
                            npts--;
                            status2++;
                        }
                    }
                    k++;
                }
                tr.Commit();
            }
            if (status2 > 0)
            {
                ed.WriteMessage("\nIgnored {0} point(s) with same coordinates.", status2);
            }

            // Supertriangle
            xmin = ptx[0]; xmax = xmin;
            ymin = pty[0]; ymax = ymin;
            for (i = 0; i < npts; i++)
            {
                if (ptx[i] < xmin)
                {
                    xmin = ptx[i];
                }
                if (ptx[i] > xmax)
                {
                    xmax = ptx[i];
                }
                if (pty[i] < xmin)
                {
                    ymin = pty[i];
                }
                if (pty[i] > xmin)
                {
                    ymax = pty[i];
                }
            }
            dx     = xmax - xmin; dy = ymax - ymin;
            xmid   = (xmin + xmax) / 2; ymid = (ymin + ymax) / 2;
            i      = npts;
            ptx[i] = xmid - (90 * (dx + dy)) - 100;
            pty[i] = ymid - (50 * (dx + dy)) - 100;
            ptz[i] = 0;
            pt1[0] = i;
            i++;
            ptx[i] = xmid + (90 * (dx + dy)) + 100;
            pty[i] = ymid - (50 * (dx + dy)) - 100;
            ptz[i] = 0;
            pt2[0] = i;
            i++;
            ptx[i] = xmid;
            pty[i] = ymid + 100 * (dx + dy + 1);
            ptz[i] = 0;
            pt3[0] = i;
            ntri   = 1;
            circum(ptx[pt1[0]], pty[pt1[0]], ptx[pt2[0]], pty[pt2[0]], ptx[pt3[0]], pty[pt3[0]], ref cex[0], ref cey[0], ref rad[0]);

            // main loop
            for (i = 0; i < npts; i++)
            {
                ned  = 0;
                xmin = ptx[i]; ymin = pty[i];
                j    = 0;
                while (j < ntri)
                {
                    dx = cex[j] - xmin; dy = cey[j] - ymin;
                    if (((dx * dx) + (dy * dy)) < rad[j])
                    {
                        ed1[ned] = pt1[j]; ed2[ned] = pt2[j];
                        ned++;
                        ed1[ned] = pt2[j]; ed2[ned] = pt3[j];
                        ned++;
                        ed1[ned] = pt3[j]; ed2[ned] = pt1[j];
                        ned++;
                        ntri--;
                        pt1[j] = pt1[ntri];
                        pt2[j] = pt2[ntri];
                        pt3[j] = pt3[ntri];
                        cex[j] = cex[ntri];
                        cey[j] = cey[ntri];
                        rad[j] = rad[ntri];
                        j--;
                    }
                    j++;
                }
                for (j = 0; j < ned - 1; j++)
                {
                    for (k = j + 1; k < ned; k++)
                    {
                        if ((ed1[j] == ed2[k]) && (ed2[j] == ed1[k]))
                        {
                            ed1[j] = -1; ed2[j] = -1; ed1[k] = -1; ed2[k] = -1;
                        }
                    }
                }
                for (j = 0; j < ned; j++)
                {
                    if ((ed1[j] >= 0) && (ed2[j] >= 0))
                    {
                        pt1[ntri] = ed1[j]; pt2[ntri] = ed2[j]; pt3[ntri] = i;
                        status    = circum(ptx[pt1[ntri]], pty[pt1[ntri]], ptx[pt2[ntri]], pty[pt2[ntri]], ptx[pt3[ntri]], pty[pt3[ntri]], ref cex[ntri], ref cey[ntri], ref rad[ntri]);
                        if (!status)
                        {
                            status1++;
                        }
                        ntri++;
                    }
                }
            }
            // removal of outer triangles
            i = 0;
            while (i < ntri)
            {
                if ((pt1[i] >= npts) || (pt2[i] >= npts) || (pt3[i] >= npts))
                {
                    ntri--;
                    pt1[i] = pt1[ntri];
                    pt2[i] = pt2[ntri];
                    pt3[i] = pt3[ntri];
                    cex[i] = cex[ntri];
                    cey[i] = cey[ntri];
                    rad[i] = rad[ntri];
                    i--;
                }
                i++;
            }
            tr = db.TransactionManager.StartTransaction();
            using (tr)
            {
                BlockTable       bt  = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);
                PolyFaceMesh     pfm = new PolyFaceMesh();
                btr.AppendEntity(pfm);
                tr.AddNewlyCreatedDBObject(pfm, true);
                for (i = 0; i < npts; i++)
                {
                    PolyFaceMeshVertex vert = new PolyFaceMeshVertex(new Point3d(ptx[i], pty[i], ptz[i]));
                    pfm.AppendVertex(vert);
                    tr.AddNewlyCreatedDBObject(vert, true);
                }
                for (i = 0; i < ntri; i++)
                {
                    FaceRecord face = new FaceRecord((short)(pt1[i] + 1), (short)(pt2[i] + 1), (short)(pt3[i] + 1), 0);
                    pfm.AppendFaceRecord(face);
                    tr.AddNewlyCreatedDBObject(face, true);
                    // add group
                    Group        group      = new Group();
                    DBDictionary dictionary = tr.GetObject(db.GroupDictionaryId, OpenMode.ForWrite) as DBDictionary;
                    dictionary.SetAt("123", group);
                    group.Append(face.ObjectId);
                    tr.AddNewlyCreatedDBObject(group, true);
                }
                tr.Commit();
            }
            if (status1 > 0)
            {
                ed.WriteMessage("\nWarning! {0} thin triangle(s) found!" + " Wrong result possible!", status1);
            }
            Application.UpdateScreen();
        }