В Delphi получить информацию по примитивам в блоках AutoCAD
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > В Delphi получить информацию по примитивам в блоках AutoCAD

В Delphi получить информацию по примитивам в блоках AutoCAD

Ответ
Поиск в этой теме
Непрочитано 01.03.2013, 06:51 #1
В Delphi получить информацию по примитивам в блоках AutoCAD
gumel
 
Регистрация: 20.04.2011
Сообщений: 481

Доброго времени суток!

Программирую в Delphi (хобби), других языков не знаю...
Передо мной стоит задача: получение информации с активного документа AutoCAD'а, ее обработка, анализ, и т.д.

В общем, я научился считывать информацию по следующим примитивам: линия, полилиния (в т.ч. дуговые сегменты), окружности и дуги.
Теперь же, желательно, читать тоже самое только в блоках. Причем блоки могут быть динамическими.
Уважаемые специалисты подскажите как это сделать.

Вот исходники (Delphi 7) и скомпилированный exe-шник моей программы.

Сейчас эта программа здорово выручает. Может кому пригодится:

Программа составляет спецификации по габаритам объектов, делает вывод в Excel, текстовый файл Cutting'а. Я работаю технологом по светопрозрачным конструкциям (алюминиевые витражи), в результате проектирования я получаю огромное количество заполнений (стеклопакеты, сэндвич-панели). Вручную составить спецификацию по этим заполнениям, конечно можно, но я немного знаю Delphi )) поэтому и наваял эту прогу. А вообще программе по-барабану что там нарисовано в AutoCAD'е, она просто читает графические объекты, получает их габариты (ширина х высота) и сводит эти данные в таблицу.

вот пример работы:


Теперь хочу дальше автоматизировать свою работу и работу своих коллег по проектированию и расчету алюминиевых конструкций.
Просмотров: 6851
 
Непрочитано 01.03.2013, 07:08
1 | #2
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


Я вот тоже люблю Delphi, но в связи с политикой партии AutoDESK, перехожу на VB.NET. К чему это я?
Delphi работает с AcAd'ом через COM, как и VBA, поэтому кстати удобно писать код сначала на VBA, а потом портировать его в Delphi.
Потому что у VBA в AcAd'е, очень хорошая справка и отладка. Но политика партии Microsoft, говорит фиг вам, а не VBA, идите на... dotNET.
Поэтому COM у AcAd'а развиваться не будет, а dotNET активно развивается...


ThisDrawing.Blocks("Имя блока").Item а дальше как с моделью, ибо модель тоже блок
Миниатюры
Нажмите на изображение для увеличения
Название: scr1.JPG
Просмотров: 327
Размер:	104.5 Кб
ID:	97818  

Последний раз редактировалось trir, 01.03.2013 в 07:16.
trir вне форума  
 
Автор темы   Непрочитано 01.03.2013, 07:33
#3
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


х.з. насчет хорошей отладки в VBA. Меня вообще жутко "колбасило" когда пытался что нибудь сделать на этом бейсике. Синтаксис непривычный, отладка не такая как в Delphi. Хотя, может я во многом и не разобрался. Но то что я бы сделал на своем "родном" языке за 5 минут, на VBA я делаю наверно где то за час. И это я говорю о элементарных вещах.
Учить другой язык, для меня, это не вариант, т.к. времени на это нету... Старый добрый Delphi рулит. Возможностей 2006 AutoCAD'а для решения моих задач хватает с лихвой. Поэтому останусь на своем (пока). Конечно непривычно писать "вслепую" на Delphi, когда речь идет о связке с AutoCAD'ом, начинаешь лезть в VBA, искать как это может называться на другом языке. Ладно когда все получается, но когда не можешь понять куда "рыть"... В общем прошу совета.

Цитата:
ThisDrawing.Blocks("Имя блока").Item а дальше как с моделью, ибо модель тоже блок
О спасибо, я примерно так и думал, буду пробовать!
gumel вне форума  
 
Непрочитано 01.03.2013, 07:43
#4
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


gumel
Ну если тебе хочется с помощью Delphi работать с чертежом напрямую, то вот есть zcad
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Автор темы   Непрочитано 01.03.2013, 07:53
#5
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


В принципе я и так работаю напрямую, в чем фишка этого zcad'а?
gumel вне форума  
 
Непрочитано 01.03.2013, 07:57
#6
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


работа dxf без AcAd'а
trir вне форума  
 
Автор темы   Непрочитано 01.03.2013, 08:20
#7
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


Ну да я могу читать dxf, только я не пойму зачем мне zcad...

А вообще если рассуждать о связи между AutoCAD'ом и Delphi, то реализация через COM технологию выглядит намного "гибче" что ли. Т.е. я могу не только получать нужную мне информацию с модели чертежа, но я также могу ее изменять и добавлять что то свое, меняя тем самым чертеж. Конечно можно и в dxf вносить какие то изменения, НО это просто не удобно с точки зрения работы пользователя с твоей программой.

Например у меня (в том примере, ссылка в самом верху), программа читает информацию по объектам, составляет спецификацию, и, нажав кнопку с изображением "123", в модели AutoCAD создаются новые объекты в виде текста, которые характеризуют индексы из таблицы спецификаций. Как то сложно объяснил.. Короче, на объектах автокада проставляются индексы (и метки) согласно составленной спецификации.
gumel вне форума  
 
Непрочитано 01.03.2013, 08:33
#8
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


2 gumel
Пара уточняющих вопросов:
1. Тебе нужно работать именно с чертежом, уже открытым в AutoCAD, или же устроил бы вариант работы с чертежом без его открытия в какой-либо программе (если бы такой вариант был возможен)?
2. Если по первому вопросу ответ "устроил бы и без открытия в AutoCAD", то есть ли в Delphi возможность пользоваться библиотеками, написанными на C++?
3. Если по 2-му вопросу ответ "да", то возможно стоит обратить внимание на это.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Автор темы   Непрочитано 01.03.2013, 08:37
#9
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


Вообще то ответ на первый вопрос: "нужно работать именно с чертежом, уже открытым в AutoCAD"

----------------------------------------

чет не могу понять где ошибка, сделал такую процедуру:

Код:
[Выделить все]
   
procedure TryAddAcadItem(Item: OleVariant);
  var
    AcLine: OleVariant;
    AcCircle: OleVariant;
    AcArc: OleVariant;
    AcPolyLine: OleVariant;
    AcBlock: OleVariant;
    Coords: OleVariant;
    BlockSpace: OleVariant;
    Pnts: array of Double;
    x,y,x1,y1,x2,y2,R: Double;
    MinP,MaxP: OleVariant;
    LBnd, HBnd, N, i: Longint;
  begin
    Pnts := nil;
    if Item.ObjectName = 'AcDbLine' then // если попалась линия
      begin
        AcLine := Item;
        Pnts := AcLine.StartPoint;
        x1 := Pnts[High(Pnts) - 2];
        y1 := Pnts[High(Pnts) - 1];
        Pnts := AcLine.EndPoint;
        x2 := Pnts[High(Pnts) - 2];
        y2 := Pnts[High(Pnts) - 1];
        AcLine.GetBoundingBox(MinP,MaxP);
        Drawing.AddLine(x1,y1,x2,y2, GetRealRect(MinP, MaxP), AcLine);
      end;
.....
.....  
.....
    if Item.ObjectName = 'AcDbBlockReference' then // если попался блок
      begin
        AcBlock := Item;
        Memo1.Lines.Add(AcBlock.Name); // это для проверки
        BlockSpace := Acad.ActiveDocument.Blocks(AcBlock.Name); // область модели блока. ТУТ RUNTIME ОШИБКА "Член группы не найден"....
        //BlockSpace := Acad.ThisDrawing.Blocks(AcBlock.Name); // ошибка "метод thisdriwing не поддерживается....
        N := BlockSpace.Count; // количество объектов в блоке
        for i := 0 to N - 1 do  // поковырямся в нем
          TryAddAcadItem(BlockSpace.Item(i)); // пробуем добавить объект (рекурсия), по идее этот объект надо добавлять с учетом точки вставки, угла поворота и т.п. для текщего блока
      end;
  end;
в основной процедуре вызываю так:
Код:
[Выделить все]
 
      MSpace := Acad.ActiveDocument.ModelSpace; // область модели
      cnt := MSpace.Count; // кол-во объектов
.........
      for i := 0 to cnt - 1 do TryAddAcadItem(MSpace.Item(i)); // пытаемся добавить объект

Не могу понять чем в VBA отличается ActiveDocument от ThisDrawing.

Последний раз редактировалось gumel, 01.03.2013 в 10:28.
gumel вне форума  
 
Непрочитано 01.03.2013, 10:27
#10
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Конечно непривычно писать "вслепую" на Delphi, когда речь идет о связке с AutoCAD'ом, начинаешь лезть в VBA
Чтобы не писать вслепую, можно для начала (и только для начала) сделать ранне связывание и положить "компонент" AutoCAD. Т.е. будут в инспекторе доступны свойства. Но для настоящей работы - только позднее связывание.

Цитата:
ThisDrawing.Blocks
...
О спасибо, я примерно так и думал
Только никаких "This..." в Delphi не будет. Незачем на VBA оглядываться. Надо просто модель смотреть по acad_auto.chm. Или по хххTLB.pas.

А вообще-то допускается самая распространенная ошибка Delphi-программистов. Вы пытаетесь из своего приложения, "через задний проход" в виде COM лезть в кишочки Автокада. Да ещё "вслепую". Это примерно как марсоходом с Земли управлять. То, что будете с трудом делать в Delphi, легко и просто решается внутри AutoCAD на Lisp.

В Delphi надо делать то, что она лучше делает. Например, всё визуальное оформление, формы, гриды и прочее. При этом основное приложение должно работать внутри AutoCAD и, при необходимости, вызывать дельфийское. Данными обмениваться и прочее. Надо Delphi-часть делать в виде COM-сервера, а не к COM Автокада обращаться.

Но если даже и обращаться из Delphi, то тоже лучше сделать обработку примитивов внутри AutoCAD. Хотите спецификации? Ну сделайте в Delphi всё оформление, базу данных, работу с ней, вывод спецификации в виде отчета. А когда надо будет "кол" заполнить, можно и к LISP-функции обратиться - она это сделает в сто раз проще.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 01.03.2013, 10:43
#11
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


Конечно, вам легко рассуждать, имея огромный багаж знаний. И мне сложно с вами спорить. То что LISP крутой язык это тоже понятно. Возможно вы так же правы насчет "заднего прохода" в виде COM технологии.. ))

Поймите меня правильно, и отнеситесь с пониманием. Я немного знаю Delphi, других языков не знаю. Есть задача, и мне нужно ее решить, не хватает немного знаний. Я прошу дельного совета. Вы же мне предлагаете отказаться от моего решения и выучить другие языки...

------------------------

Тут меня посетили сомнения, опишу ход мыслей:

Я просматриваю по порядку все объекты в области модели текущего документа.
Пытаюсь их добавить в свой список, различаю эти объект по свойству ObjectName, и, соответственно для 'AcDbLine', 'AcDbCircle', и т.д. использую разные способы.
Если мне попадается 'AcDbBlockReference', т.е. блок, то я определяю его область модели (как бы) и уже внутри этой модели организую такой же цикл. (это пока правда не удалось еще реализовать )))

И тут я засомневался по поводу правильности своего решения, поскольку область модели блока определяется через его имя ActiveDocument.Blocks("имя блока"). Ладно если речь идет об обыкновенных блоках. А если блоки динамические..? (имена то у них одинаковые) А мне как раз надо расковырять динамический блок. Думаю ну все капец, приехали. Но тут обнаружил обнадеживающую штуку. При определении имени динамического блока программным образом я получаю какое то уникальное имя, которое совершенно не совпадает с именем (как называет его пользователь). При этом если свойства динамических блоков одинаковы, то их "программные" имена совпадают, а если свойства разные то и имена отличаются. Я предполагаю, что этот факт поможет достать правильную геометрию динамического блока.

Поправьте меня, если я не прав.


----------------------------------

Перефразирую свой вопрос: как получить область модели блока?

я пытаюсь сделать так (Delphi):
Код:
[Выделить все]
 BlockSpace := Acad.ActiveDocument.Blocks(AcBlock.Name); // получим область модели блока. ОШИБКА: Член группы не найден
не работает...., причем AcBlock.Name - правильно определяется

хотя на VBA такая проверочная штука работает:
Код:
[Выделить все]
 Caption = ActiveDocument.Blocks("SS16").Count
SS16 - это имя блока в чертеже. В итоге в заголовке VBA формы получаем количество примитивов этого блока

Блин, что я не так делаю?

Последний раз редактировалось gumel, 01.03.2013 в 12:45.
gumel вне форума  
 
Непрочитано 01.03.2013, 19:17
1 | #12
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


ThisDrawing есть, только если использовать VBA в AcAd - это объект host-приложения
.Blocks("Имя блока") - тоже VBA фишка, на Delphi кажется будет .Blocks.items(i)

http://www.cadhouse.narod.ru/article...cad_blocks.htm

P.S. Давно не писал, уже всё забыл...
trir вне форума  
 
Непрочитано 02.03.2013, 12:25
#13
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 811


Цитата:
Сообщение от gumel Посмотреть сообщение
BlockSpace := Acad.ActiveDocument.Blocks(AcBlock.Name); // получим область модели блока. ОШИБКА: Член группы не найден
Может раздельно определять
Код:
[Выделить все]
blkname=AcBlock.Name
затем идёшь дальше

Последний раз редактировалось Олег (jr.), 02.03.2013 в 13:24.
Олег (jr.) вне форума  
 
Автор темы   Непрочитано 04.03.2013, 07:33
#14
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


Цитата:
Сообщение от trir Посмотреть сообщение
ThisDrawing есть, только если использовать VBA в AcAd - это объект host-приложения
.Blocks("Имя блока") - тоже VBA фишка, на Delphi кажется будет .Blocks.items(i)

http://www.cadhouse.narod.ru/article...cad_blocks.htm

P.S. Давно не писал, уже всё забыл...
Спасибо огромное!

Код:
[Выделить все]
 
...
    if Item.ObjectName = 'AcDbBlockReference' then // если попался блок
      begin
        AcBlock := Item;
        // тут нужно еще понять точку вставки блока, масштаб и угол поворота. хотя в моей задаче достаточно точки вставки
        ind := ListOfBlocks.IndexOf(AcBlock.Name); // определим индекс блока для доступа к его области модели
        BlockSpace := Acad.ActiveDocument.Blocks.Item(ind); // область модели блока
        N := BlockSpace.Count; // количество объектов в блоке
        for i := 0 to N - 1 do  // поковырямся внутри блока
          TryAddAcadItem(BlockSpace.Item(i)); // пытаемся добавить внутренний объект блока, рекурсия ля
      end;
...
где ListOfBlocks - список загруженных блоков, который заполняется так:
Код:
[Выделить все]
 
 for i := 0 to Acad.ActiveDocument.Blocks.Count - 1 do ListOfBlocks.Add(Acad.ActiveDocument.Blocks.Item(i).Name); // создадим список загруженных блоков
Осталось учесть точку вставки блока (масштаб и угол поворота), для перевода координат вложенных примитивов в мировые.
Все просто )))
gumel вне форума  
 
Непрочитано 04.03.2013, 07:50
#15
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


ListOfBlocks - список имён загруженных блоков

Цитата:
тут нужно еще понять точку вставки блока, масштаб и угол поворота
Не путай Block и BlockRef, то есть блок и вхождение блока. Точка вставки, масштаб и угол поворота - свойства BlockRef,
а он находится в ModelSpace, с другими примтивами
trir вне форума  
 
Автор темы   Непрочитано 04.03.2013, 07:57
#16
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


Ну да, в моем случае AcBlock - это и есть ссылка на конкретный блок (по идее тут нужно искать точку вставки, угол поворота, масштаб)
...
чет не могу найти свойства отвечающие за точку вставки и т.п.
gumel вне форума  
 
Непрочитано 04.03.2013, 08:38
1 | #17
trir


 
Регистрация: 18.12.2010
Сообщений: 5,107


Изучай VBA-справку
AcadBlockReference.InsertionPoint As Variant
Property Rotation As ACAD_ANGLE
Property XScaleFactor As ACAD_NOUNITS
Миниатюры
Нажмите на изображение для увеличения
Название: scr2.JPG
Просмотров: 60
Размер:	48.7 Кб
ID:	97996  
trir вне форума  
 
Автор темы   Непрочитано 04.03.2013, 08:41
#18
gumel


 
Регистрация: 20.04.2011
Сообщений: 481


ага, спасибо еще раз, уже нашел.
Думаю как это все приладить

---------------

В принципе, задачу решил.
Но не совсем идеально. Так, для блоков с искаженными значениями масштаба, некорректно отображаются дуговые сегменты. Плюс сама Delphi не умеет стандартными средствами рисовать повернутый эллипс. Решение конечно есть, но это надо переделывать всю графическую часть проги...

Всем спасибо!

Последний раз редактировалось gumel, 04.03.2013 в 11:49.
gumel вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > В Delphi получить информацию по примитивам в блоках AutoCAD



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Возможно ли получить результат выполнения SendCommand в Delphi? daemonatrix Программирование 10 19.04.2012 19:59
AutoCad Civil 3D 2010. Как получить отчет по координатам точек характерной линии в формате Excel rassom Вертикальные решения на базе AutoCAD 2 16.10.2011 02:30
Как из отрезков в AutoCAD 2009 получить объект meola AutoCAD 9 24.04.2011 20:15
Как получить информацию о переопределённых слоях в ВЭ? Makswell Программирование 4 30.09.2009 15:02
AUTOCAD 2006 Aragorn AutoCAD 14 01.04.2005 00:55