Jump to content

C#. Пример проекта.


Recommended Posts

2042131452_UntitledProject.thumb.gif.2448990873b9af76f05f9ddb8765c432.gif

 

Хочу сразу сказать Я не программист , и образования профильного нет. Просто решил поделится, т.к информации и готовых примеров мало, может кому то понадобится. 

 

Возможно написано топорно, но зато работает. 

 

C# Начал изучать недели две назад. Моя цель был составить Граф [Матрица,теория графов ]электро сети. 

 

Ниже прикладываю код.Функцию которая именно составляет граф вырезал, кому надо, тот допишет ) 

 

Ниже прикладываю примеры создания классов, вставка текста, поиск объектов, функция explode, копирование объектов, выделение объектов. 

Пытался писать в общем виде, чтоб можно было скопировать и вставить. 

 

Возможно кто то предложит более рациональные методы реализации, пишите, возьмем себе на заметку )

Спойлер
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Teigha.DatabaseServices;
using Teigha.Runtime;
using Teigha.Geometry;
using HostMgd.ApplicationServices;
using HostMgd.EditorInput;
using Teigha.Colors;
using System.Reflection;
using System.Collections;
using System.Runtime.ConstrainedExecution;


namespace AeroHost

//Thread.Sleep(TimeSpan.FromSeconds(5)); Слиппер
{

    public class MyClass
    {
        [CommandMethod("фв", CommandFlags.UsePickSet |
                        CommandFlags.Redraw | CommandFlags.Modal)] // название команды, вызываемой в Autocad
        public void addEntity()
        {
            // Сначала получаем БД текущего чертежа
            Database dbCurrent = Application.DocumentManager.MdiActiveDocument.Database;
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Document doc = Application.DocumentManager.MdiActiveDocument;

            //Выбрать объект

            //Окно приглашения
            PromptEntityOptions peo = new PromptEntityOptions("\nВыберите объект: ");

            //Для функции результа 
            PromptEntityResult per = ed.GetEntity(peo);

            //Проверка что выбрано
            using (Transaction trAdding = dbCurrent.TransactionManager.StartTransaction())
            {

                CreatLayer("Узлы_Saidi_Saifi_AeroHost", 0, 127, 0, ed, dbCurrent, trAdding);
                CreatLayer("Граф_Saidi_Saifi_AeroHost", 76, 153, 133, ed, dbCurrent, trAdding);
                CreatLayer("НазванияЛиний_Saidi_Saifi_AeroHost", 0, 191, 255, ed, dbCurrent, trAdding);
                CreatLayer("Ребра_Saidi_Saifi_AeroHost", 255, 191, 0, ed, dbCurrent, trAdding);

                Entity btrCurrSpace = trAdding.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;

                //ID Выбранного объекта
                ed.WriteMessage("\n ID Выбранного объекта: " + per.ObjectId.ToString());

                //Создать магистраль
                PowerLine Magistral = new PowerLine { Name = "Магистраль", IDLine = per.ObjectId };

                //Ищем отпайки
                SearchPlyline(Magistral, ed, trAdding, Magistral);

                //Ищем ответвления от отпаек
                List<List<PowerLine>> LispAllLine = GenaratePowerLineClass(Magistral, ed, trAdding, Magistral);

                // Добавка в весь список магистраль
                LispAllLine[0].Insert(0, Magistral);

                //Создает наим линий
                CreatTextFromLine("НазванияЛиний_Saidi_Saifi_AeroHost", LispAllLine[0], ed, dbCurrent, trAdding); //Вставить надо лист классов

                //Создает наим узлов
                List<Point3d> listPointKnot=CreatTextFromKnot("Узлы_Saidi_Saifi_AeroHost", LispAllLine[0], dbCurrent, ed, trAdding); //Вставить надо лист классов

                //Выделение все полиллиний в LispAllLine[0]
                SelectObjectFromListClass(LispAllLine[0], ed, dbCurrent, trAdding);

                //Создать копию полиллинии, перенести на другой слой,
                CopySelect("Граф_Saidi_Saifi_AeroHost", ed, dbCurrent, trAdding);

                //Выделить все созданные полиллинии в слои	
                SelectObjectLayer("Граф_Saidi_Saifi_AeroHost", "LWPOLYLINE", ed);

                // Expload объектов
                ExploadSelectObject(dbCurrent, ed, trAdding);

                //Выделить все созданные линии в слои
                SelectObjectLayer("Граф_Saidi_Saifi_AeroHost", "LWPOLYLINE", ed);

                //Затереть
                ed.Command("ERASE");

                //Выделить все созданные линии в слои
                SelectObjectLayer("Граф_Saidi_Saifi_AeroHost", "LINE", ed);

                List<Edge> listLine=  CreatClassEdgeList(ed);

                CreatTextFromEdge("Ребра_Saidi_Saifi_AeroHost",listLine,ed,dbCurrent,trAdding);


                

                trAdding.Commit();
            }






        }

        public void Initialize()
        {
        }

        void SearchPlyline(PowerLine considerPowerLine, Editor ed, Transaction trAdding, PowerLine lineMagistral)
        {

            Polyline Plyline = trAdding.GetObject(considerPowerLine.IDLine, OpenMode.ForRead) as Polyline;
            for (int i = 0; i < Plyline.NumberOfVertices; i++)
            {
                // Информация о поинте
                Point2d vertex = Plyline.GetPoint2dAt(i);

                //Добавить в листпоинтов
                considerPowerLine.Point.Add(new Point2d(vertex.X, vertex.Y));

                // Поиск других полилиний вблизи текущей вершины
                Point3d searchPoint = new Point3d(vertex.X, vertex.Y, 0);
                SelectionFilter acSF = new SelectionFilter(new TypedValue[] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") });
                PromptSelectionResult acPSR = ed.SelectCrossingWindow(searchPoint, searchPoint + new Vector3d(1, 1, 0), acSF);

                // Проверьте, были ли найдены какие-либо другие полилинии
                if (acPSR.Status == PromptStatus.OK)
                {
                    // Пройдите по найденным объектам
                    foreach (SelectedObject acSObj in acPSR.Value)
                    {
                        //Отсечь магистраль
                        if (Plyline.ObjectId != acSObj.ObjectId)
                        {
                            if (acSObj.ObjectId != lineMagistral.IDLine)
                            {
                                considerPowerLine.TapsID.Add(acSObj.ObjectId);
                                // Получить найденный объект
                                Polyline foundPl = trAdding.GetObject(acSObj.ObjectId, OpenMode.ForRead) as Polyline;
                            }

                            // Выведите информацию о найденном объекте
                            // ed.WriteMessage("\n Другая ломаная линия, найденная в вершине " + (i + 1) + ": " + foundPl.ObjectId.ToString());
                        }
                    }
                }

            }


        }

        void InfoMessage(PowerLine considerPowerLine, Editor ed)
        {
            ed.WriteMessage("---------------------------------------------");
            ed.WriteMessage("|ID Линии:" + considerPowerLine.IDLine + "|");
            ed.WriteMessage("---------------------------------------------");
            ed.WriteMessage("Имя линии: " + considerPowerLine.Name);
            if (considerPowerLine.Parent != ObjectId.Null)
            {
                ed.WriteMessage("Родитель: " + considerPowerLine.Parent);

            }
            ed.WriteMessage("Количество вершин: " + considerPowerLine.Point.Count.ToString());

            if (considerPowerLine.TapsID.Count != 0)
            {
                ed.WriteMessage("Количество отпаек: " + considerPowerLine.TapsID.Count.ToString());

                string result = "";
                foreach (ObjectId ObjId in considerPowerLine.TapsID)
                {
                    result = result + ";" + ObjId.ToString();
                }

                ed.WriteMessage("ID отпаек" + result);
            }
        }

        public List<List<PowerLine>> GenaratePowerLineClass(PowerLine considerPowerLine, Editor ed, Transaction tran, PowerLine lineMagistral)
        {
            List<List<PowerLine>> lisiofListesLine = new List<List<PowerLine>>();
            List<PowerLine> listAllLines = new List<PowerLine>();
            List<PowerLine> listLines2 = new List<PowerLine>();
            List<PowerLine> listLines3 = new List<PowerLine>();
            List<PowerLine> listLines4 = new List<PowerLine>();
            List<PowerLine> listLines5 = new List<PowerLine>();
            //Поиск отпаек
            for (int i = 0; i < considerPowerLine.TapsID.Count; i++)
            {
                PowerLine TapsLines = new PowerLine();
                TapsLines.Name = "Отпайка № " + (i + 1); //тут добавил +1 дня номр нумерации
                TapsLines.IDLine = considerPowerLine.TapsID[i];
                TapsLines.Parent = considerPowerLine.IDLine;
                TapsLines.ParentName = considerPowerLine.ParentName;
                SearchPlyline(TapsLines, ed, tran, lineMagistral);
                listAllLines.Add(TapsLines);


                //Найти ответвления от отпаек
                if (TapsLines.TapsID.Count != 0)
                {
                    for (int j = 0; j < TapsLines.TapsID.Count; j++)
                    {
                        PowerLine TapsLines2 = new PowerLine();
                        TapsLines2.Name = "Ответвление № " + (j + 1) + " от Отпайки № " + (i + 1);

                        TapsLines2.IDLine = TapsLines.TapsID[j];
                        TapsLines2.Parent = TapsLines.IDLine;
                        TapsLines2.ParentName = TapsLines.ParentName;
                        SearchPlyline(TapsLines2, ed, tran, TapsLines);
                        listLines2.Add(TapsLines2);

                        // найти ответвления от ответвлений
                        if (TapsLines2.TapsID.Count != 0)
                        {

                            for (int k = 0; k < TapsLines2.TapsID.Count; k++)
                            {
                                PowerLine TapsLines3 = new PowerLine();
                                TapsLines3.Name = "Ответвление № " + (k + 1) + " от Ответвления №" + (j + 1) + " от Отпайки № " + (i + 1); //тут добавил +1 дня номр нумерации
                                TapsLines3.IDLine = TapsLines2.TapsID[k];
                                TapsLines3.Parent = TapsLines2.IDLine;
                                TapsLines3.ParentName = TapsLines2.ParentName;
                                SearchPlyline(TapsLines3, ed, tran, TapsLines2);
                                listLines3.Add(TapsLines3);

                                if (TapsLines3.TapsID.Count != 0)
                                {
                                    for (int l = 0; l < TapsLines3.TapsID.Count; l++)
                                    {
                                        /*ed.WriteMessage("\n TapsLines3.Name"+ TapsLines3.Name.ToString()
															+"\n l :"+l
											                +"\n TapsLines3.TapsID.Count: из "+TapsLines3.TapsID.Count);*/


                                        PowerLine TapsLines4 = new PowerLine();
                                        TapsLines4.Name = "Ответвление № " + (l + 1) + " от ответвления № " + (k + 1) + " от Ответвления №" + (j + 1) + " от Отпайки № " + (i + 1); //тут добавил +1 дня номр нумерации
                                        TapsLines4.IDLine = TapsLines3.TapsID[l];
                                        TapsLines4.Parent = TapsLines3.IDLine;
                                        TapsLines4.ParentName = TapsLines3.ParentName;
                                        SearchPlyline(TapsLines4, ed, tran, TapsLines3);
                                        listLines4.Add(TapsLines4);

                                        if (TapsLines4.TapsID.Count != 0)
                                        {
                                            for (int q = 0; q < TapsLines4.TapsID.Count; q++)
                                            {
                                                PowerLine TapsLines5 = new PowerLine();
                                                TapsLines5.Name = "Отв. № " + (q + 1) + " Отв. № " + (l + 1) + " от Отв. № " + (k + 1) + " от Отв. №" + (j + 1) + " от Отп. № " + (i + 1); //тут добавил +1 дня номр нумерации
                                                TapsLines5.IDLine = TapsLines4.TapsID[q];
                                                TapsLines5.Parent = TapsLines4.IDLine;
                                                TapsLines5.ParentName = TapsLines4.ParentName;
                                                SearchPlyline(TapsLines5, ed, tran, TapsLines4);
                                                listLines5.Add(TapsLines5);
                                            }
                                        }

                                    }
                                }
                            }


                        }
                    }

                }


            }


            listAllLines.AddRange(listLines2);
            listAllLines.AddRange(listLines3);
            listAllLines.AddRange(listLines4);
            listAllLines.AddRange(listLines5);

            lisiofListesLine.Add(listAllLines);
            lisiofListesLine.Add(listLines2);
            lisiofListesLine.Add(listLines3);
            lisiofListesLine.Add(listLines4);
            lisiofListesLine.Add(listLines5);
            return lisiofListesLine;
        }

        public void CreatLayer(string Name, byte ColorR, byte ColorG, byte ColorB, Editor ed, Database dbCurrent, Transaction trAdding)
        {

            LayerTable layerTable = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForWrite) as LayerTable;

            if (!layerTable.Has(Name))
            {
                // Создание слоя
                LayerTableRecord acLyrTblRec = new LayerTableRecord();
                acLyrTblRec.Name = Name;
                acLyrTblRec.Color = Teigha.Colors.Color.FromRgb(ColorR, ColorG, ColorB);
                layerTable.UpgradeOpen();
                ObjectId acObjId = layerTable.Add(acLyrTblRec);
                trAdding.AddNewlyCreatedDBObject(acLyrTblRec, true);
                ed.WriteMessage("\nСлой создан: " + Name + " !!!Не удаляйте данный слой!!");
            }
            else
            {
                // ed.WriteMessage("\nСлой уже существует: " + Name);
            }


        }

        public void SelectLayer(string Name, Editor ed, Database dbCurrent, Transaction trAdding)
        {

            LayerTable layerTable = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForWrite) as LayerTable;
            if (layerTable.Has(Name))
            {
                ObjectId acObjId = layerTable[Name];
                LayerTableRecord acLyrTblRec = trAdding.GetObject(acObjId, OpenMode.ForWrite) as LayerTableRecord;
                dbCurrent.Clayer = acObjId;

            }


        }

        public List<Point3d> CreatTextFromKnot(string nameSearchLayer, List<PowerLine> masterLine, Database dbCurrent, Editor ed, Transaction trAdding)
        {
            object[,] resultKnotPoint = new object[,] { };
            List<Point3d> resultKnotPoint2 = new List<Point3d>();


            // Ищу на какой слой закинуть
            LayerTable acLyrTbl = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForRead) as LayerTable;

            ObjectId acLyrId = ObjectId.Null;
            if (acLyrTbl.Has(nameSearchLayer))
            {
                acLyrId = acLyrTbl[nameSearchLayer];
            }

            // что б стащить цвет
            LayerTableRecord acLyrTblRec = trAdding.GetObject(acLyrId, OpenMode.ForRead) as LayerTableRecord;

            // Для того что бы закинуть текст
            BlockTable acBlkTbl = trAdding.GetObject(dbCurrent.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord acBlkTblRec = trAdding.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            foreach (PowerLine element in masterLine)
            {
                for (int i = 0; i < element.Point.Count; i++)
                {
                    resultKnotPoint2.Add(new Point3d(element.Point[i].X, element.Point[i].Y, 0));
                }
                resultKnotPoint2 = resultKnotPoint2.Distinct().ToList();
            }

            for (int i = 0; i < resultKnotPoint2.Count; i++)
            {// Характеристики текста
                MText acMText = new MText();
                acMText.Color = acLyrTblRec.Color; //Цвето по слою
                acMText.Location = resultKnotPoint2[i];
                acMText.Contents = (i + 1).ToString();// +1 для визуализации
                acMText.TextHeight = 5; //Размер шрифта
                acMText.Height = 5; //Высота  ?
                acMText.LayerId = acLyrId;
                //acMText.Layer = "MyLayer"; // Можно и так на слой
                //acMText.Attachment = AttachmentPoint.MiddleCenter; //Центровка текста

                acBlkTblRec.AppendEntity(acMText);
                trAdding.AddNewlyCreatedDBObject(acMText, true);

            }

            return resultKnotPoint2;
        }



        public void CreatTextFromLine(string nameSearchLayer, List<PowerLine> listPowerLineCrearTest, Editor ed, Database dbCurrent, Transaction trAdding)
        {


            // Ищу на какой слой закинуть
            LayerTable acLyrTbl = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForRead) as LayerTable;
            ObjectId acLyrId = ObjectId.Null;
            if (acLyrTbl.Has(nameSearchLayer))
            {
                acLyrId = acLyrTbl[nameSearchLayer];
            }

            // что б стащить цвет
            LayerTableRecord acLyrTblRec = trAdding.GetObject(acLyrId, OpenMode.ForRead) as LayerTableRecord;

            // Для того что бы закинуть текст
            BlockTable acBlkTbl = trAdding.GetObject(dbCurrent.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord acBlkTblRec = trAdding.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            foreach (PowerLine element in listPowerLineCrearTest)
            {
                // Характеристики текста
                MText acMText = new MText();
                acMText.Color = acLyrTblRec.Color; //Цвето по слою
                acMText.Location = new Point3d(element.Point[0].X, element.Point[0].Y, 0);
                acMText.Contents = element.Name.ToString();// +1 для визуализации
                acMText.TextHeight = 4; //Размер шрифта
                acMText.Height = 4; //Высота  ?
                acMText.LayerId = acLyrId;
                //acMText.Layer = "MyLayer"; // Можно и так на слой
                //acMText.Attachment = AttachmentPoint.MiddleCenter; //Центровка текста

                acBlkTblRec.AppendEntity(acMText);
                //trAdding.AddNewlyCreatedDBObject(acMText, true);

            }
        }


        public void SelectObjectFromListClass(List<PowerLine> selectPowerLine, Editor ed, Database dbCurrent, Transaction trAdding)
        {

            List<ObjectId> listObID = new List<ObjectId>();

            foreach (PowerLine element2 in selectPowerLine)
            {
                listObID.Add(element2.IDLine);
            }
            ed.SetImpliedSelection(listObID.ToArray());//Функция выделения


        }


        public class PowerLine
        {
            public string Name { get; set; }
            public List<Point2d> Point { get; set; }
            public ObjectId IDLine { get; set; }
            //public string SigmentLengt { get; set; }
            //public string LengtPowerLine { get; set; }
            public ObjectId Parent { get; set; }
            public string ParentName { get; set; }
            public List<ObjectId> TapsID { get; set; }
            public List<string> TapsName { get; set; }

            public PowerLine()
            {
                Name = null;
                Point = new List<Point2d>();
                IDLine = ObjectId.Null;
                Parent = ObjectId.Null;
                ParentName = null;
                TapsID = new List<ObjectId>();
                TapsName = new List<string>();
            }

        }


        public void SelectObjectFromListID(List<ObjectId> selectListID, Editor ed)
        {
            ed.SetImpliedSelection(selectListID.ToArray()); //Функция выделения
        }


        public void CopySelect(string NameLayer, Editor ed, Database dbCurrent, Transaction trAdding)
        {


            List<ObjectId> ListObjIDLine = new List<ObjectId>();
            PromptSelectionResult acSSPrompt = ed.GetSelection();

            if (acSSPrompt.Status == PromptStatus.OK)
            {
                SelectionSet acSSet = acSSPrompt.Value;
                BlockTable acBlkTbl = trAdding.GetObject(dbCurrent.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord acBlkTblRec = trAdding.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                foreach (SelectedObject acSSObj in acSSet)
                {
                    if (acSSObj != null)
                    {
                        Entity acEnt = trAdding.GetObject(acSSObj.ObjectId, OpenMode.ForRead) as Entity;
                        // Make a copy of the selected object

                        Entity acEntCopy = acEnt.Clone() as Entity;
                        // Change the layer of the copy                      	
                        acEntCopy.Layer = NameLayer;

                        ListObjIDLine.Add(acEntCopy.ObjectId);

                        // Add the new object to Model space
                        acBlkTblRec.AppendEntity(acEntCopy);
                    }
                }
            }


        }

        public void SelectObjectLayer(string nameLayer, string typeObject, Editor ed)
        {


            PromptSelectionResult res = ed.SelectAll(new SelectionFilter(new TypedValue[]
            {
                    new TypedValue((int)DxfCode.LayerName, nameLayer),
                    new TypedValue((int)DxfCode.Start, typeObject),
                // new TypedValue((int)DxfCode.LayerName, nameLayer)
            }
            ));
            if (res.Status == PromptStatus.OK)
            {
                ed.SetImpliedSelection(res.Value.GetObjectIds());
            }
        }

        public void ExploadSelectObject(Database dbCurrent, Editor ed, Transaction trAdding)
        {

            PromptSelectionResult ss = ed.GetSelection();


            if (ss.Status == PromptStatus.OK)
            {
                DBObjectCollection objectsToExplodeList = new DBObjectCollection();

                SelectionSet acSSet3 = ss.Value;

                foreach (SelectedObject so in acSSet3)
                {
                    Entity ent = (Entity)trAdding.GetObject(so.ObjectId, OpenMode.ForWrite);
                    ent.Explode(objectsToExplodeList);

                }

                BlockTableRecord btr = (BlockTableRecord)trAdding.GetObject(dbCurrent.CurrentSpaceId, OpenMode.ForWrite);
                foreach (DBObject obj in objectsToExplodeList)

                {
                    Entity ent = (Entity)obj;
                    btr.AppendEntity(ent);
                    trAdding.AddNewlyCreatedDBObject(ent, false); //flase Не оставлять оригинал, не работает !?


                }

            }
        }


        public class Edge
        {
            public string Name { get; set; }
            public Point3d StartPoint { get; set; }
            public Point3d CentrPoint { get; set; }
            public Point3d EndPoint { get; set; }

            public ObjectId IDLine { get; set; }



            public Edge()
            {
                Name = null;
                IDLine = ObjectId.Null;
                StartPoint = new Point3d();
                EndPoint = new Point3d();
                CentrPoint = new Point3d();

                }

        }

        public List<Edge>  CreatClassEdgeList(Editor ed)
        {
            List<Line> edgesList = new List<Line>();
            List<Edge> edgesList2 = new List<Edge>();
            PromptSelectionResult acSSPrompt = ed.GetSelection();

            if (acSSPrompt.Status == PromptStatus.OK)
            {
                foreach (SelectedObject acSObj in acSSPrompt.Value)
                {
                    Entity ent = (Entity)acSObj.ObjectId.GetObject(OpenMode.ForWrite) as Line;
                    
                    edgesList.Add((Line)ent);
                    
                }

                for (int i= 0; i<edgesList.Count();i++)
                    {
                    Edge line = new Edge();
                    line.Name= (i+1).ToString();
                    line.IDLine = edgesList[i].ObjectId;
                    line.StartPoint = edgesList[i].StartPoint;
                    line.EndPoint = edgesList[i].EndPoint;
                    line.CentrPoint = new Point3d((edgesList[i].StartPoint.X + edgesList[i].EndPoint.X)/2, (edgesList[i].StartPoint.Y + edgesList[i].EndPoint.Y) /2, (edgesList[i].StartPoint.Z + edgesList[i].EndPoint.Z) /2);
                    edgesList2.Add(line);

                    }


            }
            return edgesList2;
        }

        public void CreatTextFromEdge(string nameSearchLayer, List<Edge> listineCrearTest, Editor ed, Database dbCurrent, Transaction trAdding)
        {


            // Ищу на какой слой закинуть
            LayerTable acLyrTbl = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForRead) as LayerTable;
            ObjectId acLyrId = ObjectId.Null;
            if (acLyrTbl.Has(nameSearchLayer))
            {
                acLyrId = acLyrTbl[nameSearchLayer];
            }

            // что б стащить цвет
            LayerTableRecord acLyrTblRec = trAdding.GetObject(acLyrId, OpenMode.ForRead) as LayerTableRecord;

            // Для того что бы закинуть текст
            BlockTable acBlkTbl = trAdding.GetObject(dbCurrent.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord acBlkTblRec = trAdding.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            foreach (Edge element in listineCrearTest)
            {
                // Характеристики текста
                MText acMText = new MText();
                acMText.Color = acLyrTblRec.Color; //Цвето по слою
                acMText.Location = element.CentrPoint;
                acMText.Contents = element.Name.ToString();// +1 для визуализации
                acMText.TextHeight = 4; //Размер шрифта
                acMText.Height = 4; //Высота 
                acMText.LayerId = acLyrId;
                //acMText.Layer = "MyLayer"; // Можно и так на слой
                acMText.Attachment = AttachmentPoint.MiddleCenter; //Центровка текста

                acBlkTblRec.AppendEntity(acMText);
                //trAdding.AddNewlyCreatedDBObject(acMText, true);

            }
        }

        
    }
}

 

 

Edited by aerohost
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

ИМХО пара моментов (на шарпах я вообще как известное животное в известных фруктах).
CreatTextFromEdge потенциально опасна - если слоя с указанным именем нет, метод поползет дальше, и вывалит ошибку.

В ExploadSelectObject я бы передавал сразу коллекцию ObjectId. А выбор выполнял бы "снаружи".  Да, кстати, не каждый примитив можно разбить (по крайней мере в ACAD).

Вообще, все выборы и взаимодействие с пользователем - снаружи, в вызывающем методе.

А насколько почти все методы и классы (ну, кроме самого командного метода) надо делать публичными?

<offtop>Блин, надо будет себе подпись сделать...</offtop>

Edited by kpblc
  • Like 2
Link to comment
Share on other sites

В ту же степь - я бы отказался от "магических" строк / чисел и т.п. Значительно проще будет ввести константы уровня приложения / класса и работать с ними. Допустить опечатку будет значительно сложнее.

И еще. Я понимаю, что это у меня тянется с лиспа, но тем не менее - я бы по возможности не делал void-методы. К примеру, CreatLayer я бы заменил на нечто типа:

        public ObjectId CreateLayer(Database dbCurrent, string Name, byte ColorR, byte ColorG, byte ColorB)
        {
            using (Transaction trAdding = dbCurrent.TransactionManager.StartTransaction())
            {
                LayerTable layerTable = trAdding.GetObject(dbCurrent.LayerTableId, OpenMode.ForRead) as LayerTable;

                if (!layerTable.Has(Name))
                {
                    layerTable.UpgradeOpen();
                    LayerTableRecord acLyrTblRec = new LayerTableRecord();
                    acLyrTblRec.Name = Name;
                    acLyrTblRec.Color = Color.FromRgb(ColorR, ColorG, ColorB);
                    ObjectId acObjId = layerTable.Add(acLyrTblRec);
                    trAdding.AddNewlyCreatedDBObject(acLyrTblRec, true);
                    trAdding.Commit();
                    return acObjId;
                }
                LayerTableRecord layerTableRec = trAdding.GetObject(layerTable[Name], OpenMode.ForRead) as LayerTableRecord;
                return layerTableRec.ObjectId;
            }
        }

И вызовы соответственно вместо

                CreateLayer(dbCurrent"Узлы_Saidi_Saifi_AeroHost", 0, 127, 0, ed, dbCurrent, trAdding);
                CreateLayer("Граф_Saidi_Saifi_AeroHost", 76, 153, 133, ed, dbCurrent, trAdding);
                CreateLayer("НазванияЛиний_Saidi_Saifi_AeroHost", 0, 191, 255, ed, dbCurrent, trAdding);
                CreateLayer("Ребра_Saidi_Saifi_AeroHost", 255, 191, 0, ed, dbCurrent, trAdding);

Становятся наподобие:

        private class LayerRecord
        {
            public string Name { get; set; }
            public byte Red { get; set; }
            public byte Green { get; set; }
            public byte Blue { get; set; }
        }

// ...
                List<LayerRecord> layersToCreate = new List<LayerRecord>()
                {
                    new LayerRecord(){Name="Узлы_Saidi_Saifi_AeroHost", Red=0, Green = 127, Blue = 0},
                    new LayerRecord(){Name = "Граф_Saidi_Saifi_AeroHost",Red= 76,Green = 153,Blue = 133},
                    new LayerRecord(){Name ="НазванияЛиний_Saidi_Saifi_AeroHost",Red= 0,Green = 191,Blue = 255},
                    new LayerRecord(){Name= "Ребра_Saidi_Saifi_AeroHost",Red = 255,Green = 191,Blue = 0 }
                };

                foreach (LayerRecord entity in layersToCreate)
                {
                    ObjectId layerId = CreateLayer(dbCurrent, entity.Name, entity.Red, entity.Green, entity.Blue);
                    if (layerId == ObjectId.Null)
                    {
                        ed.WriteMessage($"\nНе удалось создать слой {entity.Name}");
                        return;
                    }
                }

А при таком подходе можно вообще в CreateLayer передавать прямо экземпляр класса, не заморачиваясь с лишними параметрами.

Edited by kpblc
Link to comment
Share on other sites

Код не проверял и не тестировал, все написано практически на коленке.

---

Добавлю. Только сейчас обратил внимание, что все слои имеют один и тот же "постфикс". Ну и че б не сделать нечто типа:

        private class LayerRecord
        {
            public string Name
            {
                get => _name;
                set => _name = value + _postFix;
            }
            public byte Red { get; set; }
            public byte Green { get; set; }
            public byte Blue { get; set; }

            private string _name;
            private string _postFix = "_Saidi_Saifi_AeroHost";
        }
// ...
                List<LayerRecord> layersToCreate = new List<LayerRecord>()
                {
                    new LayerRecord() { Name="Узлы", Red=0, Green = 127, Blue = 0 },
                    new LayerRecord() { Name = "Граф",Red= 76,Green = 153,Blue = 133 },
                    new LayerRecord() { Name ="НазванияЛиний", Red= 0,Green = 191, Blue = 255},
                    new LayerRecord() { Name= "Ребра",Red = 255,Green = 191, Blue = 0 },
                };

                foreach (LayerRecord entity in layersToCreate)
                {
                    ObjectId layerId = CreateLayer(dbCurrent, entity.Name, entity.Red, entity.Green, entity.Blue);
                    if (layerId == ObjectId.Null)
                    {
                        ed.WriteMessage($"\nНе удалось создать слой {entity.Name}");
                        return;
                    }
                }

 

Edited by kpblc
  • Like 1
Link to comment
Share on other sites

57 минут назад, kpblc сказал:

я бы по возможности не делал void-методы

Как минимум будет один.. котрый их всех вызвал))

Согласен, даже если метод ничего не возвращает делаю его bool))

  • Like 2
Link to comment
Share on other sites

48 минут назад, doctorraz сказал:

делаю его bool)

 А зачем возвращать значение булевое значение там, где ничего и не должно возвращать? Типо выполнилось или нет? Тру/фолс?

Edited by aerohost
Link to comment
Share on other sites

Ага, чтоб "снаружи" проверить - вообще оно хоть что-то сделало или нет. Потому как Exception'ы кидать направо и налево - не всегда хорошая идея

  • Thanks 1
Link to comment
Share on other sites

1 час назад, kpblc сказал:

Код не проверял и не тестировал, все написано практически на коленке.

---

Добавлю. Только сейчас обратил внимание, что все слои имеют один и тот же "постфикс". Ну и че б не сделать нечто типа:

private class LayerRecord { public string Name { get => _name; set => _name = value + _postFix; } public byte Red { get; set; } public byte Green { get; set; } public byte Blue { get; set; } private string _name; private string _postFix = "_Saidi_Saifi_AeroHost"; } // ... List<LayerRecord> layersToCreate = new List<LayerRecord>() { new LayerRecord() { Name="Узлы", Red=0, Green = 127, Blue = 0 }, new LayerRecord() { Name = "Граф",Red= 76,Green = 153,Blue = 133 }, new LayerRecord() { Name ="НазванияЛиний", Red= 0,Green = 191, Blue = 255}, new LayerRecord() { Name= "Ребра",Red = 255,Green = 191, Blue = 0 }, }; foreach (LayerRecord entity in layersToCreate) { ObjectId layerId = CreateLayer(dbCurrent, entity.Name, entity.Red, entity.Green, entity.Blue); if (layerId == ObjectId.Null) { ed.WriteMessage($"\nНе удалось создать слой {entity.Name}"); return; } }

        private class LayerRecord
        {
            public string Name
            {
                get => _name;
                set => _name = value + _postFix;
            }
            public byte Red { get; set; }
            public byte Green { get; set; }
            public byte Blue { get; set; }

            private string _name;
            private string _postFix = "_Saidi_Saifi_AeroHost";
        }
// ...
                List<LayerRecord> layersToCreate = new List<LayerRecord>()
                {
                    new LayerRecord() { Name="Узлы", Red=0, Green = 127, Blue = 0 },
                    new LayerRecord() { Name = "Граф",Red= 76,Green = 153,Blue = 133 },
                    new LayerRecord() { Name ="НазванияЛиний", Red= 0,Green = 191, Blue = 255},
                    new LayerRecord() { Name= "Ребра",Red = 255,Green = 191, Blue = 0 },
                };

                foreach (LayerRecord entity in layersToCreate)
                {
                    ObjectId layerId = CreateLayer(dbCurrent, entity.Name, entity.Red, entity.Green, entity.Blue);
                    if (layerId == ObjectId.Null)
                    {
                        ed.WriteMessage($"\nНе удалось создать слой {entity.Name}");
                        return;
                    }
                }

 

Я немного не понимаю, зачем надувать столько кода ? Этим кодом мы создаем класс чтоб потом его вызвать в основном теле кода ? И тем самым мы сокращаем количеств вызовом для создания слоя ?

Edited by aerohost
Link to comment
Share on other sites

23 минуты назад, aerohost сказал:

зачем возвращать значение булевое значение там, где ничего и не должно возвращать?

Крыс тебе ответил

20 минут назад, kpblc сказал:

Потому как Exception'ы кидать направо и налево - не всегда хорошая идея

Именно и отлавливать их желательно в месте возникновения

 

  • Like 1
Link to comment
Share on other sites

Дальше тупо в порядке оффтопа. Профи если подключатся ох и навешают мне! :)

Ок, оставляем "как было". Что будет, если в какой-то момент понадобится создавать слои не с RGB-цветом, а с индексным? Причем, если ничего не задано - слой должен получить цвет 1 (красный). Ну вот так вот потребовалось. А потом туда же добавится тип линии, из какого файла этот тип линии грузить, печатать или нет слой и еще овердофига всяких настроек. В моем подходе понадобится подправить описание класса и метод его создания - куда я передаю экземпляр класса. Конечный код, который собственно и будет вызывать создание слоя, менять не понадобится от слова совсем.

У нас все цвета (индекс, Red, Green, Blue) null? Отлично, ставим индексный цвет в 1 и не паримся. У нас не задан тип линии (кстати, я не в курсе насчет Teigha, но в ACAD есть нечто типа SetDatabaseDefault, которого здесь я не увидел)? Отлично, ставим в методе создания Continuous и не мучаемся. Ну и тому подобное.

По хорошему я бы и все выводы в ed заменил на интерфейс / делегат. Надо выводить в ком.строку? Одна реализация. В MessageBox? Другая. В лог-файл? Третья. Совместить ужа и ежа? Делегат, сложение и далее по тексту :) Ну и так далее.

добавлено через 0 минут
1 минуту назад, doctorraz сказал:

Именно и отлавливать их желательно в месте возникновения

Ну, с исключениями у меня пока что странные взаимоотношения :)

Edited by kpblc
  • Like 2
Link to comment
Share on other sites

3 минуты назад, kpblc сказал:

Дальше тупо в порядке оффтопа

Блииин такая жэж фобия если юзер нажмет когда нельзя.. блокируем и т.д.

Защита от юзера не мене увлекательна)))

5 минут назад, kpblc сказал:

с исключениями у меня пока что странные взаимоотношения

Че так? 

Link to comment
Share on other sites

Ну, на данный момент я сделал грубо говоря алярмы, куда передается тип ошибки и имя вызывающего метода через [CallerMemberName]. Их и вываливаю "на самом верху", а не где они нарисовались.

Насколько это правильный подход, пока не знаю.

добавлено через 1 минуту
13 минут назад, doctorraz сказал:

Защита от юзера не мене увлекательна)))

Самое главное не переборщить, а то я как-то в лиспе нашел недокументированное ограничение на vl-catch-all-apply :)

Link to comment
Share on other sites

Только что, kpblc сказал:

сайт немножко тово

В курсе и это печалька(

 

Link to comment
Share on other sites

В общем, я свое видение кода показал, жду разгрома от профи :) Пиво взял, попкорн взял, воблы бы взял, да где ж ее взять (с).

  • Haha 1
Link to comment
Share on other sites

52 минуты назад, kpblc сказал:

а с индексным? Причем, если ничего не задано - слой должен получить цвет 1 (красный).

Ну шо то по мне так себе. 

По мне это уже совсем другой метод. И он должен быть отдельный. Или вновь созданный. 

Такими темпами лучше создать класс лаяут или лейэр  и в нем уж создавать отдельные методы криетлайэрrgb  и отдельно криеилайэриндекс

по мне какое то действие, создание выделение и т.д должно быть явно выражено в коде 

И названием класс, явно показать на какой объект воздействует

 

 

 

Edited by aerohost
Link to comment
Share on other sites

39 минут назад, kpblc сказал:

Их и вываливаю "на самом верху", а не где они нарисовались.

Насколько это правильный подход, пока не знаю.

Имха исключения разные бывают и обрабатывать их надо по разному.

Блин не мне тебя учить..

добавлено через 8 минут
16 минут назад, kpblc сказал:

жду разгрома от профи

Ривилис уже здесь?

Edited by doctorraz
Link to comment
Share on other sites

15 минут назад, kpblc сказал:

я свое видение кода показал

Дык это случаем не твои авторские лиспы летают по интернету ?)

Link to comment
Share on other sites

8 минут назад, aerohost сказал:

По мне это уже совсем другой метод. И он должен быть отдельный. Или вновь созданный. 

Такими темпами лучше создать класс лаяут или лейэр  и в нем уж создавать отдельные методы криетлайэрrgb  и отдельно криеилайэриндекс

по мне какое то действие, создание выделение и т.д должно быть явно выражено в коде 

И названием класс, явно показать на какой объект воздействует

Я бы не сказал. "Вотпрямщас" у меня (в одном из проектов) есть настройки слоев, приходящие через xml-файл (привет, сериализация / десериализация!). И там могут быть самые разные параметры слоев. Лично мне сейчас будет значительно проще написать универсальный код, который на входе получит десериализованный объект с назначенными полями и создаст слой, не задавая лишних вопросов. Что у него там будет под капотом - мне со стороны клиентского кода абсолютно параллельно. Слой создал? ObjecId (или что-то еще) получил? Ма-ла-дэц! Работаем дальше. Нет? Кидаем Exception / Alert / Msgbox / форматируем винт / ...

10 минут назад, doctorraz сказал:

Имха исключения разные бывают и обрабатывать их надо по разному.

В шарпе - да. В лиспе ситуация сильно другая.

добавлено через 0 минут
Только что, aerohost сказал:

Дык это случаем не твои авторские лиспы летают по интернету ?)

А я знаю, какие там лиспы и где летают? :) Я уже достаточно давно ничего особо не публикую.

  • Like 3
Link to comment
Share on other sites

38 минут назад, doctorraz сказал:

Ривилис уже здесь?

Вряд ли. Там ситуация аховая, предлагаю не педалировать эту тематику. Забанят нафих.

Link to comment
Share on other sites

Раз уж тут умные товарищи собрались , воспользуюсь моментом. Почему два dll файла не могу работать вместе? Первый начинает не работать, как это обойти? 😃

Link to comment
Share on other sites

"Товарищи ученые, у меня который год стук в подвале. Объясните, от чего он" (с)

Информации аднака маловато будет. Версия nanoCAD, версия NET, платформа NET, наличие реализации IExtensionApplication, методика загрузки - это только то, что в голову приходит навскидку (при этом, прошу обратить внимание - я в nanoCAD в разработке всего лишь второй день ;) ).

Я бы искал разницу в загрузке, а потом уже и разницу в проектах. Может, первая вообще сделана на FrameWork 3.5 :)

  • Like 2
Link to comment
Share on other sites

2 часа назад, aerohost сказал:

Дык это случаем не твои авторские лиспы летают по интернету ?)

:offtopic: А чей я (и мы все) код натырил, думаешь? Направо пойдёшь - на LeeMac попадёшь, налево пойдёшь - крЫса найдёшь :D

  • Haha 2
Link to comment
Share on other sites

Вы как  тут оффтоп делаете? :)

Тогда уж и библиотеку мою с гитхаба забирайте. Она, правда, потребует некоторого усилия, чтоб загрузить - но разрабатывать лиспы, надеюсь, станет проще.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Tell a friend

    Love Официальный форум компании Нанософт Разработка? Tell a friend!
×
×
  • Create New...