В продолжении темы, начатой тут: 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;
}
Как результат, получился вот такой работающий прототип:
Это интересный проект, в котором еще масса мест для улучшений и настройки, чем собственно с интересом и продолжаю заниматься.
Давно вынашивал желание написать подобный объект для выполнения армирования, но все как то не складывалось...
а тут, на 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;
}
Как результат, получился вот такой работающий прототип:
Это интересный проект, в котором еще масса мест для улучшений и настройки, чем собственно с интересом и продолжаю заниматься.
Комментариев нет:
Отправить комментарий