Example #1
0
        //----------------------------------------------------------------------------------------------------------------

        private static void SchrijfObject(Entity acEnt)
        {
            MeshDataCollection meshData    = SubDMesh.GetObjectMesh(acEnt, new MeshFaceterData());
            Point3dCollection  vertexarray = meshData.VertexArray;
            Int32Collection    facearray   = meshData.FaceArray;

            //Schrijf aantalvertices
            int aantalvertices = vertexarray.Count;

            binWriter.Write(aantalvertices);

            //Schrijf vertices weg
            for (int i = 0; i < aantalvertices; i++)
            {
                Point3d punt = vertexarray[i];
                binWriter.Write(Convert.ToSingle(punt.X));
                binWriter.Write(Convert.ToSingle(punt.Y));
                binWriter.Write(Convert.ToSingle(punt.Z));
            }

            //Schrijf facearraycount
            int facearraycount = facearray.Count;

            binWriter.Write(facearraycount);

            //Schrijf facearray weg
            for (int i = 0; i < facearraycount; i++)
            {
                binWriter.Write(facearray[i]);
            }
        }
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 static void CreateSubDMesh()
        {
            // 获取当前文档和数据库,启动事务
            var acDoc   = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            var acCurDb = acDoc.Database;

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

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

                var subDMesh = new SubDMesh();
                // 将新对象添加到块表记录和事务
                btr.AppendEntity(subDMesh);
                acTrans.AddNewlyCreatedDBObject(subDMesh, true);

                // 添加顶点前,必须先将多边形网格添加到块表记录
                var vertexArr = new Point3dCollection
                {
                    new Point3d(-1, -1, 0),
                    new Point3d(1, -1, 0),
                    new Point3d(0, 1, 0),
                    new Point3d(0, 0, 1)
                };

                // 根据顶点信息构建三棱锥网格中的四个面
                var faceIndices = new int[]
                {
                    3, 0, 1, 2,   // 最前面的 3 表示这个面所包含的顶点的个数,后面的“0,1,2”表示对应数量的顶点在 indexArray 集合中的位置(第一个元素下标为0)。
                    3, 0, 1, 3,
                    3, 0, 2, 3,
                    3, 1, 2, 3
                };
                var faceArray = new Int32Collection(faceIndices);
                // SubDMesh 对象(或者Surface、Solid3D、PolygonMesh等)的创建,大致都是先构造一个空的实例,然后通过 Set***()方法向其中添加成员。
                subDMesh.SetSubDMesh(vertexArray: vertexArr, indexArray: faceArray, smoothLevel: 0);

                //// 将网格对象直接转换为实体对象
                //Solid3d solid = subDMesh.ConvertToSolid(convertAsSmooth: false, optimize: false);
                //btr.AppendEntity(solid); // 将新对象添加到块表记录和事务
                //acTrans.AddNewlyCreatedDBObject(solid, true);

                //// 删除原来的网格(如果不删除,则网格对象与实体对象会同时存在)
                //subDMesh.Erase(erasing: true);

                // 提交事务
                acTrans.Commit();
            }
        }
Example #4
0
        public SubDMeshHandler.MeshGenerationResult GenerateSubDMesh()
        {
            if (this.list_4 == null)
            {
                throw new InvalidOperationException("Can not start SubDMesh handler: no triangles defined.");
            }
            if (this.list_4.Count < 1)
            {
                return(new SubDMeshHandler.MeshGenerationResult());
            }
            Database workingDatabase = HostApplicationServices.WorkingDatabase;
            Editor   arg_3C_0        = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            SubDMeshHandler.MeshGenerationResult result;
            using (Transaction transaction = workingDatabase.TransactionManager.StartTransaction())
            {
                this.BuildDataStructure(true);
                Point3dCollection point3dCollection = new Point3dCollection();
                for (int i = 0; i < this.list_0.Count; i++)
                {
                    point3dCollection.Add(new Point3d(this.list_0[i].X, this.list_0[i].Y, this.list_0[i].Z));
                }
                Int32Collection int32Collection = new Int32Collection(3 * this.list_4.Count);
                for (int j = 0; j < this.list_4.Count; j++)
                {
                    int32Collection.Add(3);
                    int32Collection.Add(this.list_1[j]);
                    int32Collection.Add(this.list_2[j]);
                    int32Collection.Add(this.list_3[j]);
                }
                SubDMesh subDMesh = new SubDMesh();
                subDMesh.SetDatabaseDefaults();
                subDMesh.SetSubDMesh(point3dCollection, int32Collection, 0);
                subDMesh.SetPropertiesFrom(this.list_4[0].AcDbFace);
                BlockTable       blockTable       = (BlockTable)transaction.GetObject(workingDatabase.BlockTableId, (OpenMode)1);
                BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], (OpenMode)1);
                blockTableRecord.AppendEntity(subDMesh);
                transaction.AddNewlyCreatedDBObject(subDMesh, true);
                transaction.Commit();
                result = new SubDMeshHandler.MeshGenerationResult
                {
                    objectId_0 = subDMesh.ObjectId,
                    int_0      = this.list_0.Count,
                    int_1      = this.list_4.Count,
                    string_0   = DBManager.GetLayerName(subDMesh.LayerId)
                };
            }
            return(result);
        }
Example #5
0
        /// <summary> 将任意实体转换为网格 </summary>
        public static void CreateMeshFromSolid()
        {
            //Select a solid.
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptEntityOptions opts = new PromptEntityOptions("\r\n" + "Select Solid:");

            opts.SetRejectMessage("\r\n" + "That\'s not a solid!");
            opts.AddAllowedClass(typeof(Solid3d), false);
            PromptEntityResult res = ed.GetEntity(opts);

            //Exit sub if user cancelled selection.
            if (res.Status != PromptStatus.OK)
            {
                return;
            }

            //Usual transaction stuff
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Solid3d   mySolid = tr.GetObject(res.ObjectId, OpenMode.ForRead, false) as Solid3d;
                Extents3d ext     = mySolid.Bounds.Value;
                Vector3d  vec     = ext.MaxPoint - ext.MinPoint;

                // 实体转换为网格的生成算法,即平滑或插值的参数
                //Define params governing mesh generation algorithm(See ObjectARX helpfiles for explanation of params you may need to change them depending on the scale of the solid)
                MeshFaceterData myFaceterData = new MeshFaceterData(0.01 * vec.Length, 40 * Math.PI / 180, 2, 2, 15, 5, 5, 0);

                //Create new mesh from solid (smoothing level 1)
                MeshDataCollection meshData = SubDMesh.GetObjectMesh(mySolid, myFaceterData);
                SubDMesh           myMesh   = new SubDMesh();
                myMesh.SetSubDMesh(meshData.VertexArray, meshData.FaceArray, 1);

                //Add mesh to database. (Don't remove solid).
                myMesh.SetDatabaseDefaults();
                var btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                btr.AppendEntity(myMesh);
                tr.AddNewlyCreatedDBObject(myMesh, true);

                //Our work here is done
                tr.Commit();
            }
        }
Example #6
0
        /// <summary> 将多面网格转换为细分网格 </summary>
        public static SubDMesh ConvertToSubDMesh(this PolyFaceMesh pfMesh)
        {
            var vertexArr = new Point3d[pfMesh.NumVertices]; // 多面网格中的所有顶点集合
            var faceArr   = new List <int>();                // 多面网格中的所有面集合
            var vv        = pfMesh.Cast <ObjectId>().ToArray();

            for (int i = 0; i < pfMesh.NumVertices; i++)
            {
                var v = vv[i].GetObject(OpenMode.ForRead) as PolyFaceMeshVertex;
                vertexArr[i] = v.Position;
            }
            for (int i = pfMesh.NumVertices; i < vv.Length; i++)
            {
                var f           = vv[i].GetObject(OpenMode.ForRead) as FaceRecord;
                var lastVertice = f.GetVertexAt(3);

                // Face corner indices start with 0, so faceIndex must be 0, 1, 2, or 3.PolyFaceMesh vertex indices start with 1, and will be negative if the edge is invisible or positive if the edge is visible.
                if (lastVertice == 0) // indicates that face is a trangular face.
                {
                    faceArr.AddRange(new[] { 3,
                                             Math.Abs(f.GetVertexAt(0)) - 1,
                                             Math.Abs(f.GetVertexAt(1)) - 1,
                                             Math.Abs(f.GetVertexAt(2)) - 1 });
                }
                else
                {
                    faceArr.AddRange(new[] { 4,
                                             Math.Abs(f.GetVertexAt(0)) - 1,
                                             Math.Abs(f.GetVertexAt(1)) - 1,
                                             Math.Abs(f.GetVertexAt(2)) - 1,
                                             Math.Abs(lastVertice) - 1 });
                }
            }

            var subDMesh = new SubDMesh();

            // SubDMesh 对象(或者Surface、Solid3D、PolygonMesh等)的创建,大致都是先构造一个空的实例,然后通过 Set***()方法向其中添加成员。
            subDMesh.SetSubDMesh(
                vertexArray: new Point3dCollection(vertexArr),
                indexArray: new Int32Collection(faceArr.ToArray()),
                smoothLevel: 0);
            return(subDMesh);
        }
Example #7
0
        public Entity CreateMesh()
        {
            // Get the data from the current model

            var vertices =
                _currentFaceModel.CalculateVerticesForAlignment(
                    _currentFaceAlignment
                    );

            var indices = _currentFaceModel.TriangleIndices;

            // Copy the vertices to our point array

            var verts = new Point3dCollection();

            for (int i = 0; i < vertices.Count; ++i)
            {
                var vert = vertices[i];
                verts.Add(new Point3d(vert.X, vert.Y, -vert.Z));
            }

            // Get our faces in the right format

            var faces = new Int32Collection();

            for (int i = 0; i < indices.Count; i += 3)
            {
                faces.Add(3);
                faces.Add((int)indices[i]);
                faces.Add((int)(indices[i + 1]));
                faces.Add((int)(indices[i + 2]));
            }

            // Create and return the SubDMesh

            var sdm = new SubDMesh();

            sdm.SetSubDMesh(verts, faces, 0);

            return(sdm);
        }
        public static List <MeshDatas> GetMeshDatas()
        {
            Document activeDoc = Application.DocumentManager.MdiActiveDocument;
            Database db        = activeDoc.Database;
            Editor   ed        = activeDoc.Editor;

            TypedValue[] values = { new TypedValue((int)DxfCode.Start, "MESH") };

            SelectionFilter       filter = new SelectionFilter(values);
            PromptSelectionResult psr    = ed.SelectAll(filter);
            SelectionSet          ss     = psr.Value;

            if (ss == null)
            {
                return(null);
            }

            List <MeshDatas> datas = new List <MeshDatas>();

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                for (int i = 0; i < ss.Count; ++i)
                {
                    SubDMesh          mesh       = trans.GetObject(ss[i].ObjectId, OpenMode.ForRead) as SubDMesh;
                    Point3dCollection collPoints = new Point3dCollection();

                    // Get the vertices information
                    int vcount = 0;
                    foreach (Point3d vertex in mesh.Vertices)
                    {
                        //ed.WriteMessage(String.Format("\n Vertex {0} - {1} {2}", vcount++, vertex.X, vertex.Y));
                        collPoints.Add(new Point3d(vertex.X, vertex.Y, vertex.Z));
                    }
                    datas.Add(new MeshDatas {
                        Mesh = mesh, Increment = i, Points = collPoints
                    });
                }
                trans.Commit();
            }
            return(datas);
        }
Example #9
0
        public static void Draw(double width, double height, double thickness = 2.1)
        {
            Document acDoc   = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            using (DocumentLock acDocLock = acDoc.LockDocument())
            {
                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    /*BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                     * BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;*/
                    BlockTableRecord currentSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                    SubDMesh         plywood      = new SubDMesh();
                    plywood.Setbox(width, thickness, height, 1, 1, 1, 0);
                    plywood.TransformBy(Matrix3d.Displacement(new Vector3d(width * 0.5, thickness * 0.5, height * 0.5)));

                    currentSpace.AppendEntity(plywood);
                    acTrans.AddNewlyCreatedDBObject(plywood, true);
                    acTrans.Commit();
                }
            }
        }
Example #10
0
        internal static List <MeshData> SolidInfoForCollection(Document doc, Point3d camPos, ObjectIdCollection ids)
        {
            var sols = new List <MeshData>();

            using (var tr = doc.TransactionManager.StartOpenCloseTransaction())
            {
                foreach (ObjectId id in ids)
                {
                    Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;

                    // Entity handle to name the Three.js objects
                    String hand = ent.Handle.ToString();
                    Autodesk.AutoCAD.Colors.EntityColor clr = ent.EntityColor;

                    // Entity color to use for the Three.js objects
                    long b, g, r;
                    if (ent.ColorIndex < 256)
                    {
                        System.Byte byt = System.Convert.ToByte(ent.ColorIndex);
                        int         rgb = Autodesk.AutoCAD.Colors.EntityColor.LookUpRgb(byt);
                        b = (rgb & 0xffL);
                        g = (rgb & 0xff00L) >> 8;
                        r = rgb >> 16;
                    }
                    else
                    {
                        b = 127;
                        g = 127;
                        r = 127;
                    }
                    String entColor = "0x" + String.Format("{0:X2}{1:X2}{2:X2}", r, g, b);

                    // Entity extents
                    Extents3d ext  = ent.GeometricExtents;
                    var       tmp  = ext.MinPoint + 0.5 * (ext.MaxPoint - ext.MinPoint);
                    Vector3d  dir  = ext.MaxPoint - ext.MinPoint;
                    var       mid  = new Point3d(ext.MinPoint.X, tmp.Y, tmp.Z);
                    var       dist = camPos.DistanceTo(mid);

                    if (id.ObjectClass.Name.Equals("AcDbSubDMesh"))
                    {
                        // Already a Mesh. Get the face info and clean it up
                        // a bit to export it as a THREE.Face3 which only has three vertices

                        var mesh = ent as SubDMesh;

                        Point3dCollection threeVertices = new Point3dCollection();
                        Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        Point3dCollection vertices = mesh.Vertices;

                        int[] faceArr = mesh.FaceArray.ToArray();
                        int[] edgeArr = mesh.EdgeArray.ToArray();

                        Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        int verticesInFace = 0;
                        int facecnt        = 0;
                        for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1)
                        {
                            faceVertices.Clear();

                            verticesInFace = faceArr[x];
                            for (int y = x + 1; y <= x + verticesInFace; y++)
                            {
                                faceVertices.Add(faceArr[y]);
                            }

                            // Merging of mesh faces can result in faces with multiple vertices
                            // A simple collinearity check can help remove those redundant vertices
                            bool continueCollinearCheck = false;
                            do
                            {
                                continueCollinearCheck = false;
                                for (int index = 0; index < faceVertices.Count; index++)
                                {
                                    int v1 = index;
                                    int v2 = (index + 1) >= faceVertices.Count ? (index + 1) - faceVertices.Count : index + 1;
                                    int v3 = (index + 2) >= faceVertices.Count ? (index + 2) - faceVertices.Count : index + 2;

                                    // Check collinear
                                    Point3d p1 = vertices[faceVertices[v1]];
                                    Point3d p2 = vertices[faceVertices[v2]];
                                    Point3d p3 = vertices[faceVertices[v3]];

                                    Vector3d vec1 = p1 - p2;
                                    Vector3d vec2 = p2 - p3;
                                    if (vec1.IsCodirectionalTo(vec2))
                                    {
                                        faceVertices.RemoveAt(v2);
                                        continueCollinearCheck = true;
                                        break;
                                    }
                                }
                            } while (continueCollinearCheck);

                            if (faceVertices.Count == 3)
                            {
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                            else if (faceVertices.Count == 4)
                            { // A face with 4 vertices, lets split it to
                                // make it easier later to create a THREE.Face3
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));

                                p1 = vertices[faceVertices[2]];
                                p2 = vertices[faceVertices[3]];
                                p3 = vertices[faceVertices[0]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                            else
                            {
                                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Face with more than 4 vertices will need triangulation to import in Three.js ");
                            }
                        }

                        sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor));
                    }
                    else if (id.ObjectClass.Name.Equals("AcDb3dSolid"))
                    {
                        // Mesh the solid to export to Three.js
                        Autodesk.AutoCAD.DatabaseServices.Solid3d sld = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Solid3d;

                        MeshFaceterData mfd = new MeshFaceterData();
                        // Only triangles
                        mfd.FaceterMeshType = 2;

                        // May need change based on how granular we want the mesh to be.
                        mfd.FaceterMaxEdgeLength = dir.Length * 0.025;

                        MeshDataCollection md = SubDMesh.GetObjectMesh(sld, mfd);

                        Point3dCollection threeVertices = new Point3dCollection();
                        Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        Point3dCollection vertices = md.VertexArray;

                        int[] faceArr = md.FaceArray.ToArray();

                        Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection();

                        int verticesInFace = 0;
                        int facecnt        = 0;
                        for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1)
                        {
                            faceVertices.Clear();

                            verticesInFace = faceArr[x];
                            for (int y = x + 1; y <= x + verticesInFace; y++)
                            {
                                faceVertices.Add(faceArr[y]);
                            }

                            if (faceVertices.Count == 3)
                            {
                                Point3d p1 = vertices[faceVertices[0]];
                                Point3d p2 = vertices[faceVertices[1]];
                                Point3d p3 = vertices[faceVertices[2]];

                                if (!threeVertices.Contains(p1))
                                {
                                    threeVertices.Add(p1);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p1));

                                if (!threeVertices.Contains(p2))
                                {
                                    threeVertices.Add(p2);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p2));

                                if (!threeVertices.Contains(p3))
                                {
                                    threeVertices.Add(p3);
                                }
                                threeFaceInfo.Add(threeVertices.IndexOf(p3));
                            }
                        }

                        sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor));

                        tr.Commit();
                    }
                }
            }
            return(sols);
        }
        public void SurfaceMeshByBoundary()
        {
            Document adoc = Application.DocumentManager.MdiActiveDocument;

            if (adoc == null)
            {
                return;
            }

            Database db = adoc.Database;

            DB = db;

            Editor ed = adoc.Editor;

            ED = ed;

            CivilDocument cdok = CivilDocument.GetCivilDocument(adoc.Database);


            try
            {
                Color currColor = db.Cecolor;
                if (!currColor.IsByLayer)//Если текущий слой не по слою, то расчитать более темный цвет для границ участков
                {
                    Color dimmerColor = Utils.GetDimmerColor(currColor, BORDER_DIM_MULTIPLIER);

                    ColorForBorder = dimmerColor;
                }
                else
                {
                    ColorForBorder = Color.FromColorIndex(ColorMethod.ByAci, 256);
                }


                if (!TinSurfIdIsValid())
                {
                    //Выбрать поверхность
                    if (!PickTinSurf(ed))
                    {
                        return;//Если выбор не успешен, прервать выполнение
                    }
                }
                //Подсветить поверхность
                HighlightTinSurf(true);


                //Запрос ключевых слов
                while (true)
                {
                    const string kw1 = "ПОВерхность";
                    const string kw2 = "ВОЗвышение";
                    const string kw3 = "ОТКлонкниеОтДуг";
                    const string kw4 = "СОЗдаватьГраницы";

                    PromptKeywordOptions pko = new PromptKeywordOptions("\nЗадайте параметры или пустой ввод для продолжения");
                    pko.Keywords.Add(kw1);
                    pko.Keywords.Add(kw2);
                    pko.Keywords.Add(kw3);
                    pko.Keywords.Add(kw4);
                    pko.AllowNone = true;
                    PromptResult pr = ed.GetKeywords(pko);
                    if (pr.Status == PromptStatus.Cancel)
                    {
                        return;
                    }

                    if (String.IsNullOrEmpty(pr.StringResult))
                    {
                        break;
                    }

                    switch (pr.StringResult)
                    {
                    case kw1:
                        if (!PickTinSurf(ed))
                        {
                            return;
                        }
                        break;

                    case kw2:
                        if (!GetMeshElevation(ed))
                        {
                            return;
                        }
                        break;

                    case kw3:
                        if (!GetApproxParam(ed))
                        {
                            return;
                        }
                        break;

                    case kw4:
                        if (!GetCreateBorders(ed))
                        {
                            return;
                        }

                        break;
                    }
                }


                //Проверка текущего набора выбора
                acSSet = null;
                PromptSelectionResult acSSPrompt;
                acSSPrompt = ed.SelectImplied();
                if (acSSPrompt.Status == PromptStatus.OK)
                {
                    acSSet = acSSPrompt.Value;
                }
                else
                {
                    //Множественный выбор блоков
                    TypedValue[] tv = new TypedValue[]
                    {
                        new TypedValue(0, "INSERT")
                    };
                    SelectionFilter flt = new SelectionFilter(tv);


                    PromptSelectionOptions pso = new PromptSelectionOptions();
                    pso.MessageForAdding = "\nВыберите блоки участков";

                    acSSPrompt = adoc.Editor.GetSelection(pso, flt);
                    if (acSSPrompt.Status == PromptStatus.OK)
                    {
                        acSSet = acSSPrompt.Value;
                    }
                }

                if (acSSet != null)
                {
                    Common.Timer timerMain = new Common.Timer();
                    timerMain.Start();
                    foreach (SelectedObject acSSObj in acSSet)
                    {
                        string       blockName = null;
                        Common.Timer timer     = new Common.Timer();
                        timer.Start();
                        try
                        {
                            if (acSSObj != null)
                            {
                                //полилинии внутри блока
                                List <ObjectId> polylines      = new List <ObjectId>();
                                BlockReference  blockReference = null;
                                ObjectId        btrId          = ObjectId.Null;
                                using (Transaction tr = db.TransactionManager.StartTransaction())
                                {
                                    //блок внутри набора выбора
                                    blockReference = tr.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as BlockReference;
                                    tr.Commit();
                                }
                                Matrix3d transform = Matrix3d.Identity;
                                if (blockReference != null)
                                {
                                    //трансформация из системы координат блока в мировую систему координат
                                    transform = blockReference.BlockTransform;

                                    //Перебор всех объектов внутри блока
                                    //Найти все правильные полилинии в блоке
                                    using (Transaction tr = db.TransactionManager.StartTransaction())
                                    {
                                        btrId = blockReference.BlockTableRecord;
                                        BlockTableRecord blockTableRecord = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;

                                        if (blockTableRecord.XrefStatus == XrefStatus.NotAnXref)
                                        {
                                            blockName = blockTableRecord.Name;
                                            foreach (ObjectId id in blockTableRecord)
                                            {
                                                using (Polyline poly = tr.GetObject(id, OpenMode.ForRead) as Polyline)
                                                {
                                                    if (poly != null &&
                                                        (poly.Closed || poly.GetPoint2dAt(0).Equals(poly.GetPoint2dAt(poly.NumberOfVertices - 1))) &&//Полилиния замкнута
                                                        !Utils.PolylineIsSelfIntersecting(poly) &&//Не имеет самопересечений
                                                        poly.Visible == true &&//Учет многовидовых блоков
                                                        poly.Bounds != null
                                                        )
                                                    {
                                                        polylines.Add(id);
                                                    }
                                                }

                                                AcadDb.Entity ent = tr.GetObject(id, OpenMode.ForRead) as AcadDb.Entity;
                                                if (ent is Polyline)
                                                {
                                                    Polyline poly = ent as Polyline;
                                                }
                                            }


                                            if (polylines.Count > 0)
                                            {
                                                //Проверить все линии на пересечение друг с другом. Удалить из списка те, которые имеют пересечения
                                                HashSet <ObjectId> polylinesWithNoIntersections = new HashSet <ObjectId>(polylines);
                                                //Сделать RBush для всех полилиний
                                                RBush <SpatialEntity> polylinesTree   = new RBush <SpatialEntity>();
                                                List <SpatialEntity>  spatialEntities = new List <SpatialEntity>();
                                                foreach (ObjectId polyId in polylines)
                                                {
                                                    spatialEntities.Add(new SpatialEntity(polyId));
                                                }
                                                polylinesTree.BulkLoad(spatialEntities);

                                                foreach (SpatialEntity se in spatialEntities)
                                                {
                                                    //Нахождение всех объектов, расположенных в пределах BoundingBox для этой полилинии
                                                    IReadOnlyList <SpatialEntity> nearestNeighbors = polylinesTree.Search(se.Envelope);
                                                    if (nearestNeighbors.Count > 1)
                                                    {
                                                        Polyline thisPoly = tr.GetObject(se.ObjectId, OpenMode.ForRead) as Polyline;

                                                        foreach (SpatialEntity n in nearestNeighbors)
                                                        {
                                                            if (!n.Equals(se))//Всегда будет находиться та же самая полилиния
                                                            {
                                                                Polyline          otherPoly = tr.GetObject(n.ObjectId, OpenMode.ForRead) as Polyline;
                                                                Point3dCollection pts       = new Point3dCollection();
                                                                thisPoly.IntersectWith(otherPoly, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
                                                                if (pts.Count > 0)
                                                                {
                                                                    polylinesWithNoIntersections.Remove(thisPoly.Id);
                                                                    polylinesWithNoIntersections.Remove(otherPoly.Id);
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }

                                                //Аппроксимация всех полилиний, которые имеют кривизну
                                                List <Polyline> polylinesToProcess = new List <Polyline>();
                                                foreach (ObjectId polyId in polylinesWithNoIntersections)
                                                {
                                                    using (Polyline poly = tr.GetObject(polyId, OpenMode.ForRead) as Polyline)
                                                    {
                                                        polylinesToProcess.Add(ApproximatePolyBulges(poly, approxParam));//Какой допуск оптимален?
                                                    }
                                                }

                                                //Удалить все повторяющиеся подряд точки полилинии
                                                foreach (Polyline poly in polylinesToProcess)
                                                {
                                                    for (int i = 0; i < poly.NumberOfVertices;)
                                                    {
                                                        Point2d curr      = poly.GetPoint2dAt(i);
                                                        int     nextIndex = (i + 1) % poly.NumberOfVertices;
                                                        Point2d next      = poly.GetPoint2dAt(nextIndex);

                                                        if (next.IsEqualTo(curr, new Tolerance(0.001, 0.001)))//Прореживать точки, расположенные слишком близко//TODO: Учесть масштабирование блока
                                                        {
                                                            poly.RemoveVertexAt(nextIndex);
                                                        }
                                                        else
                                                        {
                                                            i++;
                                                        }
                                                    }
                                                }


                                                //Построение дерева вложенности полилиний
                                                using (TinSurface tinSurf = tr.GetObject(tinSurfId, OpenMode.ForRead) as TinSurface)
                                                {
                                                    using (PolylineNesting polylineNesting = new PolylineNesting(tinSurf))
                                                    {
                                                        foreach (Polyline poly in polylinesToProcess)
                                                        {
                                                            poly.TransformBy(transform);
                                                            polylineNesting.Insert(poly);
                                                        }

                                                        //Расчет полигонов
                                                        polylineNesting.CalculatePoligons();

                                                        //Построение сети
                                                        using (SubDMesh sdm = polylineNesting.CreateSubDMesh())
                                                        {
                                                            List <Line> lines = new List <Line>();
                                                            if (createBorders)
                                                            {
                                                                //Создание 3d линий по границе
                                                                lines = polylineNesting.CreateBorderLines();
                                                            }

                                                            //Объекты постоены в координатах пространства модели
                                                            if (sdm != null)
                                                            {
                                                                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite);
                                                                if (btr.GetBlockReferenceIds(true, false).Count > 1)
                                                                {
                                                                    //Если у блока несколько вхождений, то создавать объекты в пространстве модели
                                                                    BlockTable       bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
                                                                    BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                                                                    ms.AppendEntity(sdm);
                                                                    tr.AddNewlyCreatedDBObject(sdm, true);

                                                                    foreach (Line line in lines)
                                                                    {
                                                                        ms.AppendEntity(line);
                                                                        tr.AddNewlyCreatedDBObject(line, true);
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    //Если у блока только одно вхождение, то создавать сеть внутри блока
                                                                    sdm.TransformBy(transform.Inverse());
                                                                    btr.AppendEntity(sdm);
                                                                    tr.AddNewlyCreatedDBObject(sdm, true);

                                                                    foreach (Line line in lines)
                                                                    {
                                                                        line.TransformBy(transform.Inverse());
                                                                        btr.AppendEntity(line);
                                                                        tr.AddNewlyCreatedDBObject(line, true);
                                                                    }
                                                                }
                                                            }

                                                            foreach (Line line in lines)
                                                            {
                                                                line.Dispose();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        tr.Commit();
                                    }
                                }
                            }
                        }
                        catch (System.Exception ex)
                        {
                            string message = "Возникла ошибка при обработке одного из выбранных объектов";
                            if (!String.IsNullOrEmpty(blockName))
                            {
                                message = "Возникла ошибка при обработке вхождения блока " + blockName;
                            }
                            Utils.ErrorToCommandLine(ed, message, ex);
                        }
                        timer.TimeOutput(blockName);
                    }

                    ed.WriteMessage("\n" +
                                    timerMain.TimeOutput("Затрачено времени (параметр аппроксимации - " + approxParam + ")")
                                    );

                    ed.Regen();
                }
            }
            catch (System.Exception ex)
            {
                CommonException(ex, "Ошибка при создании сетей по участкам поверхности");
            }
            finally
            {
                HighlightTinSurf(false);
            }
        }
Example #12
0
        static public void MeshFromSolid()
        {
            Utils.Utils.Init();

            Document acDoc   = acApp.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            Editor   ed      = acDoc.Editor;

            while (true)
            {
                // Ask the user to select a solid
                PromptEntityOptions peo = new PromptEntityOptions("Select a 3D solid");
                peo.SetRejectMessage("\nA 3D solid must be selected.");
                peo.AddAllowedClass(typeof(Solid3d), true);
                PromptEntityResult per = ed.GetEntity(peo);

                if (per.Status == PromptStatus.Cancel || per.Status == PromptStatus.Error)
                {
                    Utils.Utils.End(); return;
                }

                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    // Open the Block table for read
                    BlockTable acBlkTbl;
                    acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    // Open the Block table record Model space for write
                    BlockTableRecord acBlkTblRec;
                    acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                    Solid3d sol = acTrans.GetObject(per.ObjectId, OpenMode.ForWrite) as Solid3d;

                    try
                    {
                        // Set mesh/faces properties
                        MeshFaceterData mfd = new MeshFaceterData();
                        mfd.FaceterMeshType      = 2;
                        mfd.FaceterDevNormal     = 40;
                        mfd.FaceterDevSurface    = 0.05;
                        mfd.FaceterGridRatio     = 0;
                        mfd.FaceterMaxEdgeLength = 0;

                        MeshDataCollection md = SubDMesh.GetObjectMesh(sol, mfd);

                        // Create mesh
                        SubDMesh mesh = new SubDMesh();
                        mesh.SetDatabaseDefaults();
                        mesh.SetSubDMesh(md.VertexArray, md.FaceArray, 0);
                        mesh.Layer = sol.Layer;

                        // Add mesh to DB
                        acBlkTblRec.AppendEntity(mesh);
                        acTrans.AddNewlyCreatedDBObject(mesh, true);

                        // Delete solid object
                        sol.Erase(true);

                        acTrans.Commit();
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("Exception: {0}", ex.Message);
                    }
                }
            }
        }
Example #13
0
        public void fgetpoints()
        {
            try
            {
                Document acDoc   = acApp.DocumentManager.MdiActiveDocument;
                Database acCurDb = acDoc.Database;
                Editor   ed      = acDoc.Editor;

                Utils.Utils.Init();

                PromptSelectionOptions peo = new PromptSelectionOptions();
                //PromptEntityOptions peo = new PromptEntityOptions("\nSelect mesh:");
                peo.AllowDuplicates = false;
                PromptSelectionResult per = ed.GetSelection(peo);
                if (per.Status != PromptStatus.OK || per.Status == PromptStatus.Cancel || per.Status == PromptStatus.Error || per.Status == PromptStatus.None)
                {
                    Utils.Utils.End();
                    return;
                }

                // Enter file name
                string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                var    psfo      = new PromptSaveFileOptions("Export complex geometry");
                psfo.Filter = "txt (*.txt)|*.txt";
                var pr = ed.GetFileNameForSave(psfo);

                if (pr.Status != PromptStatus.OK)
                {
                    return;
                }

                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    using (StreamWriter outputFile = new StreamWriter(pr.StringResult))
                    {
                        SelectionSet acSSet = per.Value;

                        // Step through the objects in the selection set
                        foreach (SelectedObject acSSObj in acSSet)
                        {
                            Entity entity = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as Entity;
                            if (entity.GetType() == typeof(SubDMesh))
                            {
                                SubDMesh mesh = acTrans.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as SubDMesh;
                                if (mesh != null)
                                {
                                    // Generate array that contains info about faces, i.e. [0] => number of edges, [1] => vert[0], [2] => vert[1], ...
                                    int[]             faceArr  = mesh.FaceArray.ToArray();
                                    Point3dCollection vertices = mesh.Vertices;
                                    int edges = 0;

                                    // Append text to selected file named.
                                    outputFile.WriteLine("&GEOM ID='COMPLEX_GEOM_1',");
                                    outputFile.WriteLine("SURF_ID = '" + Utils.Layers.GetSurfaceName(mesh.Layer.ToString()) + "',");
                                    outputFile.Write("VERTS =\t");
                                    foreach (Point3d vertice in vertices)
                                    {
                                        if (vertice == vertices[0])
                                        {
                                            outputFile.Write(String.Format("{0}, {1}, {2},\n", vertice.X, vertice.Y, vertice.Z));
                                        }
                                        else
                                        {
                                            outputFile.Write(String.Format("\t\t{0}, {1}, {2},\n", vertice.X, vertice.Y, vertice.Z));
                                        }
                                    }

                                    outputFile.Write(String.Format("FACES =\t"));
                                    // x = edges
                                    // x + 1 = vertice 1
                                    // x + 2 = vertice 2
                                    // x + 3 = vertice 3
                                    for (int x = 0; x < faceArr.Length; x = x + edges + 1) // Zacznij od 0; mniejsze od dlugosci; zrob skok co 3 (liczba krawedzi) + 1
                                    {
                                        if (x == 0)
                                        {
                                            outputFile.Write(String.Format("{0}, {1}, {2}, 1,\n", faceArr[x + 1] + 1, faceArr[x + 2] + 1, faceArr[x + 3] + 1));
                                        }
                                        else
                                        {
                                            outputFile.Write(String.Format("\t\t{0}, {1}, {2}, 1,\n", faceArr[x + 1] + 1, faceArr[x + 2] + 1, faceArr[x + 3] + 1));
                                        }

                                        edges = faceArr[x]; // face array na x posiada info ile jest krawedzi - dla nas zawsze 3
                                    }
                                    outputFile.WriteLine("/\n\n");
                                }
                            }
                        }
                    }
                    acTrans.Commit();
                }
                Utils.Utils.End();
                return;
            }
            catch (System.Exception e)
            {
                Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage("Program error: " + e.ToString());
                Utils.Utils.End();
                return;
            }
        }
Example #14
0
        public void ImportUit3ds()
        {
            // Verkrijg document en database
            Document acDoc   = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            acCurDb.Surfu = 0;
            acCurDb.Surfv = 0;

            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // Open de block-tabel
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;

                // Open de Model space om in te schrijven
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                //Bestand openen om binair te lezen
                binReader = new BinaryReader(File.Open(@"C:/3DGISBuffer.dat", FileMode.Open));

                //Loop door objecten
                int aantalobjecten = binReader.ReadInt32();
                for (int i = 0; i < aantalobjecten; i++)
                {
                    Point3dCollection vertarray = new Point3dCollection();
                    Int32Collection   facearray = new Int32Collection();

                    // Maak een subdivision-mesh aan
                    SubDMesh sdm = new SubDMesh();
                    sdm.SetDatabaseDefaults();

                    // Voeg het object toe aan de block-tabel
                    acBlkTblRec.AppendEntity(sdm);
                    acTrans.AddNewlyCreatedDBObject(sdm, true);

                    //objectkleur lezen
                    byte kleur_r = binReader.ReadByte();
                    byte kleur_g = binReader.ReadByte();
                    byte kleur_b = binReader.ReadByte();

                    //solidvlag lezen
                    Boolean solidvlag = LeesBoolean();

                    // Vertexarray vullen met vertices
                    Point3dCollection acPts3dPFMesh = new Point3dCollection();
                    Int32             nvts          = binReader.ReadInt32();

                    for (int j = 1; j <= nvts; j++)
                    {
                        Single nX = binReader.ReadSingle();
                        Single nY = binReader.ReadSingle();
                        Single nZ = binReader.ReadSingle();
                        vertarray.Add(new Point3d(nX, nY, nZ));
                    }

                    //Facearray vullen met faces
                    int nfcs = binReader.ReadInt32();
                    for (int j = 1; j <= nfcs; j++)
                    {
                        int fc1 = binReader.ReadInt32();
                        int fc2 = binReader.ReadInt32();
                        int fc3 = binReader.ReadInt32();

                        facearray.Add(3);
                        facearray.Add(fc1 - 1);
                        facearray.Add(fc2 - 1);
                        facearray.Add(fc3 - 1);
                    }

                    //Vertex- en facearray toevoegen aan mesh, smoothlevel 0
                    sdm.SetSubDMesh(vertarray, facearray, 0);

                    Entity pMijnObj = null;
                    if (solidvlag)
                    {
                        Autodesk.AutoCAD.DatabaseServices.Solid3d pSolid = sdm.ConvertToSolid(false, false);
                        pMijnObj = (Entity)pSolid;
                    }
                    else
                    {
                        Autodesk.AutoCAD.DatabaseServices.Surface pSurface = sdm.ConvertToSurface(false, false);
                        pMijnObj = (Entity)pSurface;
                    }
                    acBlkTblRec.AppendEntity(pMijnObj);
                    acTrans.AddNewlyCreatedDBObject(pMijnObj, true);

                    //Verwijder mesh
                    sdm.Erase();


                    // Schrijf objectnaam naar Xrecord in de entity-dictionary van de surface
                    SaveXRecord(pMijnObj, LeesAttributen(), "GISData", acTrans);

                    //kleur van het object updaten
                    pMijnObj.Color = Color.FromRgb(kleur_r, kleur_g, kleur_b);
                }//einde for-loop

                // Schrijf het object naar de AutoCAD-database en sluit binReader
                acTrans.Commit();
                binReader.Close();
            } //einde using transaction
        }     //einde method