Перейти к публикации

Open API. с++. Фильтры выбора.


torvald

Рекомендованные сообщения

Добрый день! Уже не один день ломаю голову над задачей отбора объектов(кривая, ребро, твердое тело) с заданным атрибутом.

Коротко введение:

Интерфейс Block Styler, в нем присутствует селектор типа "Select Object". Так вот, нужно задать условие наличия атрибута в любом выделенном объекте. Один из вариантов- пролистывать массив выделенных объектов, через try{}catch(...){} отлавливать все объекты в которых есть данный атрибут (пытаясь получить доступ к данному атрибуту в блоке try{}, если атрибут отсутствует, обрывается try и выкидывает в catch). Но это занимает много времени, т.к. три типа объектов, 3 раза отлавливаем ошибку, а граней, кривых и т.д. за тысячу.

Вот другое дело настройка фильтра по атрибутам в NX(например NX7.5). Edit->Selection->User Attributes. выбираю тип- string, ввожу наименование атрибута- weld, и никакого перебора... моментально выбрало все нужные объекты, независимо от их типа. Но организовать это у меня не получилось.

Максимум- фильтр выбора по типу объекта, да и там руки связаны. Пример фильтра граней в коллбэке filter_cb:

std::vector<NXOpen::Selection::MaskTriple> maskTriple1(1);

maskTriple1[0].Type=3;

maskTriple1[0].Subtype=0;

maskTriple1[0].SolidBodySubtype=0;

selection0->GetProperties()->SetSelectionFilter("SelectionFilter",Selection::SelectionActionClearAndEnableSpecific,maskTriple1);

Собственно к делу! Если кто-нибудь работал с похожими задачами, или же заинтересован проблемой, давайте общаться!

Ссылка на сообщение
Поделиться на других сайтах


Ну все правильно, вроде.

* Если тебе надо найти ВСЕ объекты (любого типа) с атрибутом MY_ATTR=MY_VALUE, то берем UF_OBJ_cycle_all и шпарим по всем объектам в части (неважно скрыты они или нет) и у каждого спрашиваем UF_ATTR_find_attribute и, если нашли - то UF_ATTR_read_value.

UF_ATTR_find_attribute/UF_ATTR_read_value можно смело заменить на :

NXOpen::NXObject * obj = dynamic_cast < NXOpen::NXObject * > ( NXOpen::NXObjectManager::Get (tag_t ) );

if (obj) {

obj->GetAttributeTitlesByType();

ну и т.д.

}

* Если же тебе надо найти ТОЛЬКО ВИДИМЫЕ объекты с атрибутом MY_ATTR=MY_VALUE, то берем UF_VIEW_ask_work_view и далее шпарим по объектам при помощи UF_VIEW_cycle_objects (собирая атрибуты ткаим же способом, как ив первом пункте).

UF_VIEW_cycle_objects можно смело заменить на NXOpen::View::AskVisibleObjects

* Для selection блока в blockstyler-e есть доп опция : фильтр (см. скриншот)

в этот фильтр будут приезжать объекты, поверх которых пользователь елозит мышкой (но НЕ выбирает). Соотвветственно в этом фильтре можно отсекать объекты, не имеющие атрибут/значение.

PS Чтобы не просаживалась производительность при stack unwinding (когда в catch попадаешь), рекомендую сначала проверить, есть ли атрибут у объекта, и правильного ли он (атрибут) типа, и только потом спрашивать значение.

Regardzzz ...

post-646-1317727963_thumb.png

Ссылка на сообщение
Поделиться на других сайтах

Ну все правильно, вроде.

* Если тебе надо найти ВСЕ объекты (любого типа) с атрибутом MY_ATTR=MY_VALUE, то берем UF_OBJ_cycle_all и шпарим по всем объектам в части (неважно скрыты они или нет) и у каждого спрашиваем UF_ATTR_find_attribute и, если нашли - то UF_ATTR_read_value.

UF_ATTR_find_attribute/UF_ATTR_read_value можно смело заменить на :

NXOpen::NXObject * obj = dynamic_cast < NXOpen::NXObject * > ( NXOpen::NXObjectManager::Get (tag_t ) );

if (obj) {

obj->GetAttributeTitlesByType();

ну и т.д.

}

* Если же тебе надо найти ТОЛЬКО ВИДИМЫЕ объекты с атрибутом MY_ATTR=MY_VALUE, то берем UF_VIEW_ask_work_view и далее шпарим по объектам при помощи UF_VIEW_cycle_objects (собирая атрибуты ткаим же способом, как ив первом пункте).

UF_VIEW_cycle_objects можно смело заменить на NXOpen::View::AskVisibleObjects

* Для selection блока в blockstyler-e есть доп опция : фильтр (см. скриншот)

в этот фильтр будут приезжать объекты, поверх которых пользователь елозит мышкой (но НЕ выбирает). Соотвветственно в этом фильтре можно отсекать объекты, не имеющие атрибут/значение.

PS Чтобы не просаживалась производительность при stack unwinding (когда в catch попадаешь), рекомендую сначала проверить, есть ли атрибут у объекта, и правильного ли он (атрибут) типа, и только потом спрашивать значение.

Regardzzz ...

Огромное спасибо за быстрый и полезный ответ! Я что то и не подумал, что вместо перебора массива в селекторе можно в калбэк фильтра засунуть проверку =).

и еще вопросик... Подскажите плз как организовать "выделить все". Еще раз спасибо!

Ссылка на сообщение
Поделиться на других сайтах

Ну все правильно, вроде.

* Если тебе надо найти ВСЕ объекты (любого типа) с атрибутом MY_ATTR=MY_VALUE, то берем UF_OBJ_cycle_all и шпарим по всем объектам в части (неважно скрыты они или нет) и у каждого спрашиваем UF_ATTR_find_attribute и, если нашли - то UF_ATTR_read_value.

UF_ATTR_find_attribute/UF_ATTR_read_value можно смело заменить на :

NXOpen::NXObject * obj = dynamic_cast < NXOpen::NXObject * > ( NXOpen::NXObjectManager::Get (tag_t ) );

if (obj) {

obj->GetAttributeTitlesByType();

ну и т.д.

}

* Если же тебе надо найти ТОЛЬКО ВИДИМЫЕ объекты с атрибутом MY_ATTR=MY_VALUE, то берем UF_VIEW_ask_work_view и далее шпарим по объектам при помощи UF_VIEW_cycle_objects (собирая атрибуты ткаим же способом, как ив первом пункте).

UF_VIEW_cycle_objects можно смело заменить на NXOpen::View::AskVisibleObjects

* Для selection блока в blockstyler-e есть доп опция : фильтр (см. скриншот)

в этот фильтр будут приезжать объекты, поверх которых пользователь елозит мышкой (но НЕ выбирает). Соотвветственно в этом фильтре можно отсекать объекты, не имеющие атрибут/значение.

PS Чтобы не просаживалась производительность при stack unwinding (когда в catch попадаешь), рекомендую сначала проверить, есть ли атрибут у объекта, и правильного ли он (атрибут) типа, и только потом спрашивать значение.

Regardzzz ...

Огромное спасибо за быстрый и полезный ответ! Я что то и не подумал, что вместо перебора массива в селекторе можно в калбэк фильтра засунуть проверку =).

Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте еще раз! Снова понадобилась помощь:

Пытаюсь пройтись по всем элементам партов, но почему то переход object_tag не осуществляется. Нашел несколько примеров, в которых функцию UF_OBJ_cycle_all используют так, как написано ниже.

int i=0;

tag_t object_tag= NULL_TAG;

tag_t part_tag = UF_PART_ask_nth_part(y);

while((object_tag = UF_OBJ_cycle_all(part_tag, object_tag)) != NULL_TAG)

{

object_list = object_tag;

i++;

}

Пробовал мониторить object_tag прямо в цикле- значение не изменяется.

Может ли это быть вызвано различием в версиях NX (примеры я нашел для NX4, тестирую на NX6, NX7.5). Спасибо!

Ссылка на сообщение
Поделиться на других сайтах

Разобрался в чем дело. Ниже код функции, которая возвращает тэги всех объектов у которых есть атрибут "weld_length". h- переменная выделения. При 1- объекты выделены, при 0- снятие выделения. n- количество объектов.

tag_t *selection(int *n,int h){

tag_t *object_list=(tag_t *) malloc(sizeof(tag_t));

int y=0;int i;

int attr_type;UF_ATTR_value_p_t atr_value;

int num_parts = UF_PART_ask_num_parts ( );

for (y=0; y<num_parts; y++)

{

i=0;

tag_t object_tag= NULL_TAG;

tag_t part_tag = UF_PART_ask_nth_part(y);

while((object_tag = UF_OBJ_cycle_all(part_tag, object_tag)) != NULL_TAG)

{

UF_ATTR_find_attribute(object_tag,UF_ATTR_string,"Weld_length",&attr_type);

if (attr_type == 5){

UF_DISP_set_highlight(object_tag,h);

object_list = object_tag;

i++;

object_list = (tag_t *) realloc(object_list, sizeof(tag_t)*(i+1));

}

}

}

*n=i-1;

return object_list;

}

Спасибо! Считаю тему закрытой =)

Ссылка на сообщение
Поделиться на других сайтах

Считаю тему не закрытой, ибо код изобилует косяками (несколько косяков - смертельные, несколько - в виде "warning").

tag_t *selection(int *n,int h) {



  //вспоминаем, ЧЕМ инициализируются значения при malloc

  //HINT: значения будут undetermined - т.е. мусор.

  //вот теперь представь, что ты НЕ НАШЕЛ ни одного атриба Weld_length в частях. И возвращаешь указатель на один (или не один  ... см. косяк с int i ) tag_t

  //и теперь представь, что ты обрабатываешь возвращенный массив в вызывающей ф-ции :) 

  //+++ начало бага +++

  tag_t *object_list=(tag_t *) malloc(sizeof(tag_t));

  //+++ конец бага +++

  

  //ok

  int y=0;

	

  //а кто будет нулем тут инициализировать переменную, а?

  //вот попробуй распечатай значение i после его объявления (на *nix может и прокатит, но для Win* - НЕТ )

  //БОЛЕЕ ТОГО. ты получишь мощщщщнейший выстрел при попытке обратиться в вызывающей ф-ции к элементу массива (который "возвращаешь") при условиях:

  //1. ты не иниицализировал i нулем

  //2. количество загруженных частей y == 0;

  //3. ты в вызывающей ф-ции побежал по object_list (возврату) *n раз :) 

  //+++ начало бага +++

  int i;  

  //+++ конец бага +++

  

  //в данном контексте - не страшно (не определенная переменная), но я бы занулил :) 

  int attr_type;



  //а напуркуа оно здесь, если ниже по коду не используется ...	

  UF_ATTR_value_p_t atr_value;

  

  //ok

  int num_parts = UF_PART_ask_num_parts ( );



  //ok

  for (y=0; y<num_parts; y++) {

	

	//ай-ай-ай! 

	//вот представь, что у нас 5 загруженных частей и в данный момент y==0 

	//вот мы нашли 10 объектов (в цикле ниже), у которых есть атриб Weld_length

	//и вот мы перешли на y=1

	//угадай, поверх чего мы сейчас будем писать новые значения, при условии нахождения в части "y" объектов с атрибом Weld_length ??? 

	//HINT: правильный ответ - поверх УЖЕ НАЙДЕННЫХ тегов объектов в части "y-1" 

	//+++ начало бага +++	 

	i=0;

	//+++ конец бага +++

	

	//ok

	tag_t object_tag= NULL_TAG;

	

	//ok

	tag_t part_tag = UF_PART_ask_nth_part(y);

	

	//ok

	while((object_tag = UF_OBJ_cycle_all(part_tag, object_tag)) != NULL_TAG) {

	  

	  //а кто ошибку (код возврата) будет проверять, а? в данном случае не смертельно, но надо себя приучать к надежному коду ... 

	  //+++ начало бага +++  

	  UF_ATTR_find_attribute(object_tag,UF_ATTR_string,"Weld_length",&attr_type);

	  //+++ конец бага +++

	  

	  //тоже достаточно спорное решение, я бы заменил сравнение attr_type с 5 на UF_ATTR_string

	  //+++ начало бага +++

	  if (attr_type == 5) {

	  //+++ конец бага +++

	  

		//а кто ошибку (код возврата) будет проверять, а? в данном случае не смертельно, но надо себя приучать к надежному коду ...

		//+ я бы не стал уповать на разумное поведение ф-ции при значениях второго аргумента отличных от 0 или 1 (в твоем коде нет проверки на 0/1 значения входного параметра 'h' ) 

		//+++ начало бага +++		

		UF_DISP_set_highlight(object_tag,h);

		//+++ конец бага +++

		

		//ok

		object_list[i] = object_tag;

		//ok (в данном случае), но преинкремент, т.е. ++i в общем случае "правильнее". гуглить по слову "преинкремент/постинкремент"

		i++;

		//ok (с оговорками про int i :) )

		object_list = (tag_t *) realloc(object_list, sizeof(tag_t)*(i+1));

	  }

	}

  }



  //а кто будет проверять значение указателя, который нам передали на NULL ?

  //я могу вызавать ф-цию вот так :  tag_t some_tags = selection (NULL, 1);

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

  *n=i-1;

	

  //ok

  return object_list;

}

Regardzzz ...

PS Итого:

0. Сорри длинные объяснения и КАПСЫ.

1. За стремление кодить для NX - пять.

2. За реализацию алгоритма - кол (хотел поставить два с минусом).

PPS - ВНИМАТЕЛЬНО следить за логикой ф-ции.

PPPS - НАСТОЯТЕЛЬНО рекомендую изучить возможности STL (ассоциативных контейнеров типа std::vector / std::set и т.д. для того, чтобы не мучаться с памятью (malloc/calloc/realloc) )

PPPPS - Анализ проводился без проверок на тестовом коде, так что в этом анализе тоже могут быть "недочеты" :)

Regardzzz ещё раз...

Ссылка на сообщение
Поделиться на других сайтах

Спасибо! Учел ваши советы. Код после компиляции в "накосяченом виде" работал, но спустя некоторое время я снова запустил приложение и огорчился. Программа работает до момента for (y=0; y<num_parts; ++y).

проверил num_parts:

num_parts = UF_PART_ask_num_parts ( );

char tmp[10];

itoa(num_parts,tmp,10);

weld_calc::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, tmp);

num_parts=0, но я так и не понял почему... соответственно выполнение прерывается. Я что то не учел при использовании UF_PART_ask_num_parts ( )?

Ссылка на сообщение
Поделиться на других сайтах

Спасибо! Учел ваши советы. Код после компиляции в "накосяченом виде" работал, но спустя некоторое время я снова запустил приложение и огорчился. Программа работает до момента for (y=0; y<num_parts; ++y).

проверил num_parts:

num_parts = UF_PART_ask_num_parts ( );

char tmp[10];

itoa(num_parts,tmp,10);

weld_calc::theUI->NXMessageBox()->Show("Block Styler", NXOpen::NXMessageBox::DialogTypeError, tmp);

num_parts=0, но я так и не понял почему... соответственно выполнение прерывается. Я что то не учел при использовании UF_PART_ask_num_parts ( )?

Массив char tmp[10]; проинициализируй (хотябы первый элемент)

Если бы Ты читал внимательно стандары "c" - то знал бы что практически все с-шные

функции которые работают со строками требуют завершающего 0

Где он у Тебя - по стандарту то что находится в обласи памяти tmp[10]

никак не определено - на усмотрение разработкика компилятора

соответственно так же не определено будет работать Твоя программа

Посмотри хотя бы

<noindex>itoa</noindex>

- где написано что на c рекомендуется пользоваться sprintf

На c++ есть еще более безопасный вариант

#include <strstream>

#include <iostream>

#include <sstream>

#include <iomanip>



std::string pse_component::str(int n)

{ std::string ret;

  std::ostrstream os; 

	os<<n<<'\0';

	ret=os.str();

return ret;

}
Ссылка на сообщение
Поделиться на других сайтах

мм... первое что пришло на ум для конвертации. это недоразумение не влияет на выполнение функции UF_PART_ask_num_parts ( ). Я учел ваш, nut888, совет, спасибо.

Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.




  • Сообщения

    • maxx2000
      @soulnuun я не говорю про абразив, я говорю про пильный диск.  
    • Говорящий Огурец
      Прекрасно это понимаю. И, как и любую другую проблему, ее можно решить разными способами. Но хочется с помощью более опытных коллег выбрать оптимальный. Прикрепляю фото:  
    • soulnuun
      Изначально резали болгаркой и не имели никаких проблем, но нашли вариант покупать у другого поставщика, приехала какая то бронебойная резина, которая съедает круги от болгарки на глазах, сейчас на одну пластину уходит 4 круга, столб белого дыма, вонь и все в радиусе полутора метров покрыто кусками этой резины   
    • DuS
    • Snake 60
      @Dimetil Gidrozin Dnepr  Для общего развития глянь :)  
    • k.sema
      Добрый день! Подскажите, пожалуйста, как восстановиться из бэкап файла .ARC ? На производстве пластиковых окон имеется станок для очистки профилей  Siemens CN-770. Там села батарейка и все настройки слетели, но благо есть файл бэкапа. Но как из него восстановиться? В руководстве пользователя есть инструкция о том, как создать этот бэкап, но нету как восстановиться.  На Ютубе нашёл видео как это делается на на станке SINUMERIK 840d.  Получится ли сделать подобным образом здесь? Похожий ли принцип будет? Т.е. мне нужно поместить этот файл  .ARC в определённую папку и инициировать процесс восстановления? Если у кого-то есть опыт с этим, буду очень признателен за помощь.     
    • mactepnew
      Да, это то, что надо. Причем подгружать обратно в ТС не нужно, работа будет вестись на локальном диске.  К сожалению, да, таковы реалии. Спасибо сами знаете кому...  Да, попробую это сформулировать для руководства, может с их стороны получится надавить на айтишников. В меню такой команды нет, но через поиск нашлась. Сделал пробный экспорт пары деталей - получаю связку из двух .prt, при изменении детали чертеж обновляется. По факту это то, что нужно.  Немножко муторно через поиск выбирать файлы, но сам факт результата уже говорит о том, что задача выполнима. Направление известно, буду ковырять дальше. Благодарю за помощь!
    • vanek77777
      Здравствуйте! Выберите стандарт GB193. Там есть все основные шаги резьбы. В том числе М18х1.
    • maxx2000
      @Kelny ты сейчас бьёшься головой об стену. На той стороне спец которых земля не видела Брылиант, спаситель, светоч    
    • Kelny
      Потому, что вы посещаете темы про макросы.   Очень даже зря. Неплохо бы изучить, в то числе что это такое.   Потому что об этом написано в справке: https://help.solidworks.com/   Без макросов быстроты и эффективности не получишь.   Простой пример: руки или лопата, как бы вы не вертелись быстрее и эффективнее ну ни как не получится, без привлечения более серьёзной техники. Так же и спроектированием, базовая программа позволяет работать быстрее, но для большего ускорения нужны специализированные модули или макросы, ускоряющие или исключающие повторяющийся рутинный труд - ваш труд подменяет программа и делает работу за вас.   А зря, макросы позволяют приложив немного усилий в последствии могут исключить рутинный труд. А линукс уже давно в вашей жизни, если вы обзавелись смартфоном, то там наверняка линукс названный маркетологами андройдом, да и многие устройства вроде смарт-тв, банкоматы и т.п. тоже крутятся на линускосподобных системах.
×
×
  • Создать...