Цитата

«Качество надо производить, а не обеспечивать в результате контроля»(с)nmivan

пятница, 8 июня 2018 г.

CustomEntity на .Net без использования ObjectARX

В продолжении темы, начатой тут: http://adn-cis.org/forum/index.php?topic=7771.0 , а еще ранее (в 2012 году) тут: https://habr.com/post/154591/
Давно вынашивал желание написать подобный объект для выполнения армирования, но все как то не складывалось...
а тут, на https://www.upwork.com , предложили написать именно то, что я хотел. При таких условиях отказываться было сложно...

Стал более подробно прорабатывать вопрос и рыться по интернету и тут тупик, оказалось, что открытых примеров подобных объектов просто нет, кодов нет, пояснений нет. А закрытых... единственный рабочий объект такого рода удалось найти тут: http://the-void.ru/?p=214 .
Я не сторонник лезть в чужой код, но в данном случае, скачал и принялся изучать... это очень большая и сложная программа, она чрезмерно сложна и избыточна для меня, но она дала понимание, откуда начинать и куда идти.

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

Я не стал повторять чужой подход, мне не понравилась идея хранить полные описания своих объектов в расширенных словарях и при выделении блока в редакторе, прорисовывать Gips на основе этих описаний, это порождает кучу проблем с хранением этих описаний, с отменой действий пользователя, с копированием и вставкой из буфера... да с простым изменением, масса проблем.
В моей реализации, местом хранения описания и самим описанием сделан непосредственно сам блок и объекты внутри блока. Это сделать очень просто, если на начальном этапе создания вставки блока соответствующим образом просто пометить все объекты внутри блока и при выделении просто прочитать нужные данные с помеченных объектов. Такой подход позволил отказаться от всяческих реакторов и синхронизации... просто Db.GripOverrule и все работает.

Пример конструктора объекта:
         public RebarObj(Db.BlockReference blRef)
        {
            Db.BlockTableRecord btr = blRef.BlockTableRecord.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord;
            foreach (Db.ObjectId id in btr)
            {
                if (id.ObjectClass.IsDerivedFrom(Rtm.RXObject.GetClass(typeof(Db.Line))))
                {
                    Db.Line l = id.Open(Db.OpenMode.ForRead) as Db.Line;
                    string leter = l.GetXData();
                    if (leter == "V")
                    {
                        this.lineV = new RebarLine(l.StartPoint * blRef.ScaleFactors.Y, l.EndPoint * blRef.ScaleFactors.Y);
                        this.lineV.ColorIndex = l.ColorIndex;
                        this.lineV.LineWeight = l.LineWeight;
                        this.lineV.strXData = leter;
                    }
                    if (leter == "H")
                    {
                        this.lineH = new RebarLine(l.StartPoint * blRef.ScaleFactors.X, l.EndPoint * blRef.ScaleFactors.X);
                        this.lineH.ColorIndex = l.ColorIndex;
                        this.lineH.LineWeight = l.LineWeight;
                        this.lineH.strXData = leter;
                    }
                    l.Close();
                    l.Dispose();
                }
            }
            btr.Close();
            btr.Dispose();
            this.InsertionPoint = blRef.Position;

            Gem.Vector3d V1 = Gem.Point3d.Origin.GetVectorTo(this.lineH.StartPoint);
            Gem.Vector3d V2 = Gem.Point3d.Origin.GetVectorTo(this.LineH.StartPoint);
            this.TernPoint = Gem.Point3d.Origin + V1.GetNormal() * V2.Length + V2.GetNormal() * gap;
        }



Как результат, получился вот такой работающий прототип:


Это интересный проект, в котором еще масса мест для улучшений и настройки, чем собственно с интересом и продолжаю заниматься.



Комментариев нет: