Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Максим Маркевич от 19-09-2016, 00:55:47

Название: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 00:55:47
Всем привет. Суть задачи:
Выделяю множество элементов (блоки и штриховки), среди которых есть блок (который несет в себе определенную инфу) и ему соответствует определенная штриховка (см. скриншот ниже):
(https://s12.postimg.org/5jqp27auh/Screen_Shot.jpg) (https://postimg.org/image/5jqp27auh/)
Для того, чтобы упростить понимание задачи, допустим, что со штриховки я беру площадь, а с блока - высоту/толщину, далее высчитываю объем и записываю в таблицу - это упрощенный смысл плагина.
Если интересен неупрощенный смысл, то см. видео ниже:

(Александр Наумович, извиняюсь за видео с ютуба. Просто оно записано не для форума, а для других целей, но здесь уместно для полного понимания вопроса, а нет времени перезаписывать скринкаст.)
Так вот, до недавнего времени в плагине имелся один именно такой блок с высотой/толщиной и одна конкретная штриховка с площадью, поэтому задача решалась просто:
Я получал толщину с блока с конкретным именем и площадь штриховки с конкретным стилем:

Извините, вам запрещён просмотр содержимого спойлеров.


Я понимаю, что не совсем корректно 2 раза пробегаться по выделенным объектам, но до сегодняшнего дня меня это все устраивало и работало все тоже хорошо (очень буду признателен и за предложения насчет улучшения сего момента).
Так вот, что сегодня случилось? :)
Дело в том, что возникла необходимость иметь несколько блоков с высотами/толщинами и несколько штриховок с площадями. То есть пар может быть несколько, а не одна!
И я вот думаю, как связать конкретный блок с конкретной штриховкой.
За целый день, который я провел за рулем, у меня возникло 3 идеи:
1. Определять попадает ли блок на штриховку (данный блок находится на непечатном слое, его можно кинуть поверх штриховки и таким образом программно определить принадлежность)
Я только полагаю, что это можно сделать программно, но не совсем понимаю, как именно.
(https://s15.postimg.org/df7rbi2dz/Screen_Shot_002.jpg) (https://postimg.org/image/df7rbi2dz/)
2. Дать возможность пользователю создавать в каком-то атрибуте блока поле на площадь штриховки, потом программно доставать из блока значение атрибута.
Вроде как простой вариант, но нужно руками создавать поле, что не очень удобно.
(https://s13.postimg.org/50c8l7d0z/Screen_Shot_004.jpg) (https://postimg.org/image/50c8l7d0z/)
3. Создать кастомную штриховку, которая будет нести в себе и инфу о высоте/толщине. :)
Думаю, что такое возможно, но это совсем, пока что, недосягаемо для меня.
Так вот, прошу совета, как лучше всего поступить в данной ситуации (совета с учетом, что потом будет создана тема, как воплотить совет в жизнь;))?
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 01:11:44
И я вот думаю, как связать конкретный блок с конкретной штриховкой.
Например, через расширенные данные (XData).
1. Определять попадает ли блок на штриховку (данный блок находится на непечатном слое, его можно кинуть поверх штриховки и таким образом программно определить принадлежность)
Я только полагаю, что это можно сделать программно, но не совсем понимаю, как именно.
Что именно непонятно? Как вычислить габариты штриховки, найти её среднюю точку и поместить точку вставки блока в эту точку? Ты это не понимаешь?
3. Создать кастомную штриховку, которая будет нести в себе и инфу о высоте/толщине. :)
Можно в штриховку в расширенные данные вписать эту информацию. Но кое-что мне непонятно. Ты программно штрихуешь или это делает пользователь средствами AutoCAD? Если пользователь, то так сделать не получится.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 01:26:59
Например, через расширенные данные (XData).
Пошел читать. :)
Что именно непонятно? Как вычислить габариты штриховки, найти её среднюю точку и поместить точку вставки блока в эту точку? Ты это не понимаешь?
Сейчас мне уже не понятно, зачем находить среднюю точку штриховки и зачем именно туда помещать блок?
Я думал, что он будет лежать в любом месте, но поверх ее, возможно даже частично. И мне было не понятно, как определить, находится ли в полученных габаритах штриховки точка вставки блока?
Можно в штриховку в расширенные данные вписать эту информацию. Но кое-что мне непонятно. Ты программно штрихуешь или это делает пользователь средствами AutoCAD? Если пользователь, то так сделать не получится.
Я ничего не знал о возможности вписки в штриховку каких-либо данных. Поэтому, если там все удобно, то не составит труда создать командный метод (с небольшим интерактивом для пользователя), который бы вставлял штриховку в автокад.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 01:34:03
И мне было не понятно, как определить, находится ли в полученных габаритах штриховки точка вставки блока?
Ты не знаешь как определить находится ли точка внутри прямоугольника? ;)
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 01:36:32
Я ничего не знал о возможности вписки в штриховку каких-либо данных.
Эти данные можно вписать в любой объект/примитив AutoCAD. Структуру данных можешь определять сам.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 01:38:43
Про Xdata: http://adn-cis.org/ispolzovanie-.netapidlya-dobavleniya-i-udaleniya-rasshirennyix-dannyix.html
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 01:52:55
Ты не знаешь как определить находится ли точка внутри прямоугольника?
(https://s11.postimg.org/x654pcx1r/photo_2016_09_19_01_53_46.jpg) (https://postimg.org/image/x654pcx1r/)
Метод трассировки луча? :) Я надеялся, что есть какой-то крутейший метод типа
Код - C# [Выбрать]
  1. public bool ПринадлежитЛиТочкаКонтуру(контур, точка)
В общем, я понял, что данный метод мне не подходит.
Эти данные можно вписать в любой объект/примитив AutoCAD. Структуру данных можешь определять сам.
Вот с этим обязательно поиграюсь. Раз структура формируемая, то это очень круто и удобно!! Спасибо!
Про Xdata: http://adn-cis.org/ispolzovanie-.netapidlya-dobavleniya-i-udaleniya-rasshirennyix-dannyix.html
Спасибо!! :)

Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Владимир Шу от 19-09-2016, 11:15:55
ИМХО, самый простой и наглядный способ соотнести блок и штриховку - цвет.
Назначить штриховке и блоку одинаковый цвет, так и соотносить.
Как альтернативу можно использовать группы, т.е. попарно объединять в группы.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 11:39:38
Я надеялся, что есть какой-то крутейший метод типа
Как средствами AutoCAD определить расположение точки относительно контура. (http://adn-cis.org/kak-sredstvami-opredelit-raspolozhenie-tochki-otnositelno-kontura.html)
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 11:42:15
Как альтернативу можно использовать группы, т.е. попарно объединять в группы.
Кстати, очень неплохая идея. Есть только одна проблема - при копировании в другой чертеж (если в этом может возникнуть необходимость) группы "разваливаются", так как они softpointer и не копируются между чертежами.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 11:47:17
ИМХО, самый простой и наглядный способ соотнести блок и штриховку - цвет.
Есть во мне стереотипы и предрассудки насчет выделения цветом, но согласен, работать все будет, как-то даже очень просто!
Как альтернативу можно использовать группы, т.е. попарно объединять в группы.
Вот это мне уже совсем нравится!!! Просто я никогда программно с группами не работал. Может, есть какая заготовочка по обращению с группами (буду признателен)?
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 11:56:45
Как средствами AutoCAD определить расположение точки относительно контура.
Спасибо.:) Что-то я поиском не добрался до этой темы.
Есть только одна проблема - при копировании в другой чертеж (если в этом может возникнуть необходимость) группы "разваливаются", так как они softpointer и не копируются между чертежами.
В принципе, если концепция использования исключает копирование в другой чертеж (как в моей ситуации), то вариант шикарнейший.
Буду разбираться!!
Александр Ривилис, Boxa.Shu уже огромное спасибо за мнение, ссылки и идеи!!
Поработаю с предложенным вариантами, доложу о результатах. Возможно, кому-то когда-то пригодится.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 13:03:26
Несколько статей на эту тему:
Доступ к группам AutoCAD при помощи .NET (http://adn-cis.org/dostup-k-gruppam-autocad-pri-pomoshhi-net.html)
Перебор всех групп в чертеже (http://adn-cis.org/perebor-vsex-grupp-v-chertezhe.html)
Как найти группы, которым принадлежит примитив (http://adn-cis.org/kak-najti-gruppyi-kotoryim-prinadlezhit-primitiv.html)
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 20:47:48
Хотел создать новую тему, но тут есть за что зацепиться.:)
Эти данные можно вписать в любой объект/примитив AutoCAD.
Если говорить о штриховке, то в ней изначально есть кое-какие данные:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs17.postimg.org%2Ftv0510cpn%2FScreen_Shot.png&hash=026ca4f95e9af456a726cd497d2beafa) (http://postimg.org/image/tv0510cpn/)
Как я понял, их лучше не трогать?
Структуру данных можешь определять сам.
Сильно тут не разгонишься, как я понял:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs21.postimg.org%2Fqir02ndar%2FScreen_Shot_001.png&hash=b6622cc02523324409538f3fd3189a1c) (http://postimg.org/image/qir02ndar/)
Как раз-таки, приходится подстраиваться под структуру:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs15.postimg.org%2F7muvcxo4n%2FScreen_Shot_002.png&hash=48ca13d798f1bd6b338ed1c937d1e014) (http://postimg.org/image/7muvcxo4n/)
То есть доставать, например, потом строку, с ней работать. Конечно, все не так удобно, как я представлял. Но, в целом, если организовать окошко пользовательское добавления/проверки/удаления данных, то это все очень-очень круто!!!!!!
Решил, что буду пользоваться именно XData, так как это лучший способ из рассмотренных в теме. Ну ведь, реально, нет смысла использовать паровоз из штриховки и блока, если можно обойтись только штриховкой.
Вариант, который предложил Boxa.Shu с группами мне тоже очень понравился, но мне кажется, что он не будет таким удобным в обращении.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 19-09-2016, 23:33:37
Как я понял, их лучше не трогать?
Правильно понял.
Сильно тут не разгонишься, как я понял:
Какой-то дурацкий перевод (это я не про тебя, а про картинку). Да еще и с ошибками.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 19-09-2016, 23:44:28
Какой-то дурацкий перевод (это я не про тебя, а про картинку). Да еще и с ошибками.
Со справки AutoCAD скрин сделал.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 20-09-2016, 00:04:04
Со справки AutoCAD скрин сделал.
Вот здесь: http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf начиная со страницы 246 (Extended Data) правильнее. Единственная разница DXF по сравнению с TypedValue, что точки передаются как массив из трех double, а не по отдельности каждая из координат в своей группе. Т.е. в 1010 содержится все три координаты, а не в 1010 - X, в 1020 - Y, и в 1030 - Z.
В переводе написана глупость в том, что код 1000 - это в действительно просто строка, а код 1001 - это имя приложения (тоже строка, но имеющая радикально другой смысл).
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 20-09-2016, 12:16:31
Вот здесь: http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf (http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf) начиная со страницы 246 (Extended Data) правильнее. Единственная разница DXF по сравнению с TypedValue, что точки передаются как массив из трех double, а не по отдельности каждая из координат в своей группе. Т.е. в 1010 содержится все три координаты, а не в 1010 - X, в 1020 - Y, и в 1030 - Z.
В переводе написана глупость в том, что код 1000 - это в действительно просто строка, а код 1001 - это имя приложения (тоже строка, но имеющая радикально другой смысл).
Согласен, если читать только справку AutoCAD, то не совсем ясен тот факт, что код 1001 соответствует началу приложения/группы, которое/которая включает в себя все остальные коды и информацию. В принципе, для себя я решил, что мне достаточно всего лишь 2х кодов (1001 и 1000). 1001 - я начинаю группу, затем я формирую n-ое количество строк с кодом 1000 с абсолютно любым содержимым.
Например,
1001 - Перекрытие (appname/string)
1000 - Класс бетона_С16/20
1000 - Толщина перекрытия_200
1000 - Диаметр фона_12
и т.д.
Вот такая получается "вынужденная" структура, к которой не сложно привыкнуть.
В принципе, для того, чтобы все это понять (не читая русскоязычную справку:)), достаточно использовать утилиту MgdDbg (http://adn-cis.org/forum/index.php?topic=7274.msg21888#msg21888) или утилиту из ExpressTools(XDLIST) и немного поэкспериментировать с программным кодом (http://adn-cis.org/ispolzovanie-.netapidlya-dobavleniya-i-udaleniya-rasshirennyix-dannyix.html).

Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 20-09-2016, 13:27:29
В принципе, для себя я решил, что мне достаточно всего лишь 2х кодов (1001 и 1000). 1001 - я начинаю группу, затем я формирую n-ое количество строк с кодом 1000 с абсолютно любым содержимым.
Например,
1001 - Перекрытие (appname/string)
1000 - Класс бетона_С16/20
1000 - Толщина перекрытия_200
1000 - Диаметр фона_12
и т.д.
Можно и так, если в тексте никогда не может встретится подчеркивание. Я так понял, что подчеркивание - это твой символ разделитель. Я бы выбрал бы какой-то более экзотический. Например, \ или | (можно парные).
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 20-09-2016, 13:46:04
Я так понял, что подчеркивание - это твой символ разделитель.
Да, именно так. На него я буду опираться при "извлечении" информации.
Я бы выбрал бы какой-то более экзотический. Например, \ или | (можно парные).
Кстати, да. Вы правы. Спасибо за совет.
Интересно получается, что, если работать с адним и тем же 1001, то его даже удалять не нужно - я так понял, что группа перезаписывается целиком каждый раз.
Например, я записал что-то типа:
Код - C# [Выбрать]
  1. RegAppTable regTable = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
  2.                 if (!regTable.Has("Перекрытие"))
  3.                 {
  4.                     regTable.UpgradeOpen();
  5.                     RegAppTableRecord app = new RegAppTableRecord();
  6.                     app.Name = "Перекрытие";
  7.                     regTable.Add(app);
  8.                     tr.AddNewlyCreatedDBObject(app, true);
  9.                 }
  10.                 ent.XData = new ResultBuffer(new TypedValue(1001, "Перекрытие"),
  11.                     new TypedValue(1000, "Класс бетона||С16/20"));
Получил:
Код - INI [Выбрать]
  1. 1001 - Перекрытие (appname/string)
  2. 1000 - Класс бетона||С16/20
А потом ничего не удаляя добавил следующую инфу:
Код - C# [Выбрать]
  1. ent.XData = new ResultBuffer(new TypedValue(1001, "Перекрытие"),
  2.                     new TypedValue(1000, "Класс бетона||С20/25"));
[/code]
И группа целиком перезаписалась:
Код - INI [Выбрать]
  1. 1001 - Перекрытие (appname/string)
  2. 1000 - Класс бетона||С20/25
Это меня удивило потому, что я ожидал другой результат, такой, например:
Код - INI [Выбрать]
  1. 1001 - Перекрытие (appname/string)
  2. 1000 - Класс бетона||С16/20
  3. 1000 - Класс бетона||С20/25
Но существующий вариант меня, вообще, целиком устраивает. Вопрос только, не происходит ли там какого "захламления", которым часто тут пугают ;) ?
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 20-09-2016, 13:48:21
Это меня удивило потому, что я ожидал другой результат, такой, например:
Код - INI [Выбрать]

    1001 - Перекрытие (appname/string)
    1000 - Класс бетона||С16/20
    1000 - Класс бетона||С20/25

Но существующий вариант меня, вообще, целиком устраивает. Вопрос только, не происходит ли там какого "захламления", которым часто тут пугают ;) ?
Ты абсолютно прав о том, что происходит полная замена. Это как замена по ключу. Захламления нет.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 20-09-2016, 14:04:14
Захламления нет.
Отлично :)
В общем, xData мне пришлась по душе. В данный момент запиливаю окошка типа:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs13.postimg.org%2Fc5svfz4pv%2FScreen_Shot.png&hash=17c65e29e73cbc23035045002f82f93c) (http://postimg.org/image/c5svfz4pv/)
Установить создает группу 1001 Перекрытие и записывает туда строки 1000 (правда их будет порядка 10).
Проверить выводит всю группу 1001 Перекрытие, чтобы убедиться, что все ок.
В общем, считаю данный вариант оптимальным решением вопроса, который после появления самого решения, стал неактуальным :) - то есть мне больше не нужен блок. Конечно с обработкой информации придется чутка больше провозиться, но мне нравится, все устраивает.
Решением данной темы, для себя, считаю первое сообщение от Александра Ривилиса(спасибо!), а также спасибо Владимиру Шу за интересные предложения.
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Максим Маркевич от 23-09-2016, 01:15:16
Вот что вышло в итоге (самым сложным было сделать окошки WPF, с XData все просто и приятно):
Название: Re: Как программно выбрать штриховку "соответствующую" конкретному блоку?
Отправлено: Александр Ривилис от 23-09-2016, 01:18:40
IMHO достаточно симпатично и удобно для пользователя.