每當提起UDO總是會讓我想起大專畢業那會失業找工作,后來有個寶貴機會去了軟件公司上班,拿到了我人生中的第一個NX二次開發項目,一個關於測量汽車前后左右攝像頭的項目。當時那個項目就用到了UDO,對於只看了兩個月唐康林工程師二次開發視頻教程就跑出來找工作的我,顯然是不會UDO的,后來采用了將handle值寫到部件屬性里,然后每次打開工具對話框前先去部件屬性里讀,在給到對話框里。在然后項目沒做完我就特么滾蛋了。
時隔差不多兩年,以前技術底子太差,好多東西都不懂,直到最近我對UDO才有了一些認知了解,會用了一點點。但是依然很多東西搞不懂。技術這玩意就這樣,也許我現在看不懂,可能兩年后我就能看懂了。考驗的是一個人對熱愛的堅持程度!所以這個UDO內容我會持續完善的。做一個綜合例子,等把UFUN得UDO搞明白了,后面我回去再研究一下NXOPEN的UDO,萬變不離其宗,基本功能應該都是一樣的。
下面這個本對UDO有一些介紹,另外可以去UGOPEN文件夾里看這三個文件。
也可以去UGOPEN\SampleNXOpenApplications里看西門子官方的一個UDO例子,但那個是用NXOPEN寫得。
1 /***************************************************************************** 2 ** 3 ** UDOtest.cpp 4 ** 5 ** Description: 6 ** Contains Unigraphics entry points for the application. 7 ** 8 *****************************************************************************/ 9 /* Include files */ 10 #include <stdarg.h> 11 #include <strstream> 12 #include <iostream> 13 using std::ostrstream; 14 using std::endl; 15 using std::ends; 16 using std::cerr; 17 #include <uf.h> 18 #include <uf_ui_types.h> 19 #include <uf_ui.h> 20 #include <uf_exit.h> 21 22 23 //頭文件 24 #include <uf.h> 25 #include <uf_ui.h> 26 #include <uf_modl.h> 27 #include <uf_udobj.h> 28 #include <uf_disp.h> 29 #include <uf_obj.h> 30 31 32 static void ECHO(char *format, ...) 33 { 34 char msg[UF_UI_MAX_STRING_BUFSIZE]; 35 va_list args; 36 va_start(args, format); 37 vsnprintf_s(msg, sizeof(msg), _TRUNCATE, format, args); 38 va_end(args); 39 UF_UI_open_listing_window(); 40 UF_UI_write_listing_window(msg); 41 UF_print_syslog(msg, FALSE); 42 } 43 44 #define UF_CALL(X) (report_error( __FILE__, __LINE__, #X, (X))) 45 46 static int report_error(char *file, int line, char *call, int irc) 47 { 48 if (irc) 49 { 50 char err[133]; 51 UF_get_fail_message(irc, err); 52 ECHO("*** ERROR code %d at line %d in %s:\n", 53 irc, line, file); 54 ECHO("+++ %s\n", err); 55 ECHO("%s;\n", call); 56 } 57 return(irc); 58 } 59 60 61 //顯示事件的回調函數 62 void registed_display_fun(tag_t udo, void* display_context) 63 { 64 uc1601("這是顯示事件的回調", 1); 65 } 66 67 //選擇事件的回調函數 68 void registed_select_fun(tag_t udo, void* select_context) 69 { 70 uc1601("這是選擇事件的回調", 1); 71 } 72 73 //適合窗口事件的回調函數 74 void registed_fit_fun(tag_t udo, void* select_context) 75 { 76 uc1601("這是適合窗口的回調", 1); 77 //UF_UDOBJ_all_data_t all_data; 78 ////查詢UDO對象數據 79 //UF_UDOBJ_ask_udo_data(udo, &all_data); 80 ////查詢UDO類的名稱 81 //char* class_name, *friendly_name; 82 //UF_UDOBJ_ask_class_data(all_data.class_id, &class_name, &friendly_name);//注意事項:friendly_name不能是中文,否則獲取不到. 83 ////釋放 84 //UF_UDOBJ_free_udo_data(&all_data); 85 //uc1601(class_name, 1); 86 //uc1601(friendly_name, 1); 87 //UF_free(class_name); 88 //UF_free(friendly_name); 89 } 90 91 //編輯事件的回調函數 92 void registed_edit_fun(tag_t udo) 93 { 94 uc1601("這是編輯的回調", 1); 95 } 96 97 // 信息事件的回調函數 98 void registed_info_fun(tag_t udo) 99 { 100 uc1601("這是信息事件的回調", 1); 101 } 102 103 // 刪除事件的回調函數 104 void registed_delete_fun(tag_t udo, UF_UDOBJ_link_p_t deleted_obj) 105 { 106 uc1601("這是刪除事件的回調", 1); 107 } 108 109 // 更新事件的回調函數 110 void registed_update_fun(tag_t udo, UF_UDOBJ_link_p_t update_cause) 111 { 112 uc1601("這是更新事件的回調", 1); 113 } 114 115 //當具有輸入類標識符的UDO通過注意點計算事件時,注冊注意點函數(方法)以進行調用 116 void registed_attn_fun(tag_t udo, void * display_context) 117 { 118 uc1601("這是注冊注意點事件的回調", 1); 119 } 120 121 //確定此UDO是否可出現的事件回調函數 122 void registed_occurrenceable_fun(tag_t udo, logical * is_occurrenceable) 123 { 124 uc1601("這是確定此UDO是否可出現的事件回調函數", 1); 125 } 126 127 /***************************************************************************** 128 ** Activation Methods 129 *****************************************************************************/ 130 /* Explicit Activation 131 ** This entry point is used to activate the application explicitly, as in 132 ** "File->Execute UG/Open->User Function..." */ 133 extern DllExport void ufusr(char *parm, int *returnCode, int rlen) 134 { 135 /* Initialize the API environment */ 136 if (UF_CALL(UF_initialize())) 137 { 138 /* Failed to initialize */ 139 return; 140 } 141 142 /* TODO: Add your application code here */ 143 144 UF_initialize(); 145 146 uc1601("創建UDO", 1); 147 148 //創建UDOTestClass類 149 UF_UDOBJ_class_t class_id; 150 UF_UDOBJ_create_class("UDOTestClass", "MyUDOTest", &class_id); 151 152 //將UDOTestClass類的顯示名稱加入到類選擇對話框的類列表中 153 UF_UI_add_to_class_sel(class_id); 154 155 //創建UDOTestClass類的對象 156 tag_t udo_tag = NULL_TAG; 157 UF_UDOBJ_create_udo(class_id, &udo_tag); 158 159 //點構造器 160 char sCue[] = "點構造器"; 161 UF_UI_POINT_base_method_t base_method = UF_UI_POINT_INFERRED; 162 tag_t tPoint = NULL_TAG; 163 double sBasePoint[] = { 0, 0, 0 }; 164 int iResponse; 165 UF_UI_point_construct(sCue, &base_method, &tPoint, sBasePoint, &iResponse); 166 //UFUN創建直線 167 UF_CURVE_line_t Line_coords; 168 Line_coords.start_point[0] = sBasePoint[0]; 169 Line_coords.start_point[1] = sBasePoint[1]; 170 Line_coords.start_point[2] = sBasePoint[2]; 171 Line_coords.end_point[0] = 100.0; 172 Line_coords.end_point[1] = 100.0; 173 Line_coords.end_point[2] = 100.0; 174 tag_t Line = NULL_TAG; 175 UF_CURVE_create_line(&Line_coords, &Line); 176 177 //創建UDO特征 178 tag_t udo_feature_tag = NULL_TAG; 179 UF_UDOBJ_create_udo_feature_from_udo(udo_tag, &udo_feature_tag); 180 181 //創建鏈接 182 //UF_UDOBJ_link_t link_defs[2]; 183 //link_defs[0].link_type = 1; 184 //link_defs[0].assoc_ug_tag = Line; 185 //link_defs[0].object_status = 0; 186 //將UDOTestClass類對象和直線特征鏈接 187 //UF_UDOBJ_add_links(udo_tag, 1, link_defs); 188 189 //創建自有鏈接 190 //將UDOTestClass類和對象以自有鏈接方式鏈接 191 UF_UDOBJ_add_owning_links(udo_tag, 1, &Line); 192 193 //注冊顯示事件 194 UF_UDOBJ_register_display_cb(class_id, registed_display_fun); 195 196 //注冊選擇事件 197 UF_UDOBJ_register_select_cb(class_id, registed_select_fun); 198 199 //注冊fit事件 200 UF_UDOBJ_register_fit_cb(class_id, registed_fit_fun); 201 202 //注冊編輯事件 203 UF_UDOBJ_register_edit_cb(class_id, registed_edit_fun); 204 205 //注冊信息事件 206 UF_UDOBJ_register_info_obj_cb(class_id, registed_info_fun); 207 208 //注冊刪除事件 209 UF_UDOBJ_register_delete_cb(class_id, registed_delete_fun); 210 211 //注冊更新事件 212 UF_UDOBJ_register_update_cb(class_id, registed_update_fun); 213 214 //當具有輸入類標識符的UDO通過注意點計算事件時,注冊注意點函數(方法)以進行調用 215 //UF_UDOBJ_register_attn_pt_cb(class_id, registed_attn_fun); 216 217 //注冊確定此UDO是否可出現的事件回調函數 218 //UF_UDOBJ_register_is_occurrenceable_cb(class_id, registed_occurrenceable_fun); 219 220 /* 221 //查詢功能是否為UDO功能 222 logical is_udo_feature; 223 UF_UDOBJ_is_udo_feature(udo_feature_tag, &is_udo_feature); 224 225 //查詢NX對象是否具有UDO擁有的鏈接 226 logical owned; 227 UF_UDOBJ_is_owned(Line, &owned); 228 229 //查詢NX對象是否具有UDO擁有的鏈接 230 logical owned1; 231 UF_UDOBJ_is_owned(Line, &owned1); 232 233 //查詢UDO是否引用指定的NX對象 234 logical linked; 235 UF_UDOBJ_is_obj_linked_to_udo(Line, &linked); 236 237 //顯式記錄UDO功能以進行更新 238 UF_UDOBJ_log_udo_feature_for_update(udo_feature_tag); 239 240 //將指定的UDO版本化為新類 241 UF_UDOBJ_version_udo(udo_tag, class_id); 242 243 //如果在部件中找到給定類的UDO,則設置警告用戶的行為,但未加載實現UDO方法的代碼 244 UF_UDOBJ_set_user_warn_flag(class_id, true); //TRUE - 將警告用戶,FALSE - 不會警告用戶。請注意,如果未調用此例程,則默認值為FALSE。 245 246 //設置在給定類名的情況下查詢類id的行為 247 //默認 模式為UF_UDOBJ_DONT_ALLOW_QUERY_CLASS_ID。這意味着如果使用UDO的類名調用 UF_UDOBJ_ask_class_id_of_name,將返回錯誤代碼, 返回的類ID將為0.此機制用於幫助保護專有UDO的完整性。 248 //將查詢設置為UF_UDOBJ_ALLOW_QUERY_CLASS_ID意味着給定一個類名, 您可以找到類ID。此機制用於跨多個共享庫傳遞類ID 249 UF_UDOBJ_set_query_class_id(class_id, UF_UDOBJ_ALLOW_QUERY_CLASS_ID); 250 251 //設置UDO類的擁有對象選擇的行為 252 //在 默認的選擇模式是UF_UDOBJ_DONT_ALLOW_SELECTION。這意味着無法單獨選擇擁有的對象。 253 //將擁有對象的選擇設置為UF_UDOBJ_ALLOW_SELECTION意味着 如果擁有的對象和UDO都是可選擇的,則選擇擁有的對象將導致選擇 擁有的NX對象並在交互式選擇中激活Up One Level按鈕 。如果UDO不可選擇,則仍然可以選擇 擁有的對象。 254 UF_UDOBJ_set_owned_object_selection(class_id, UF_UDOBJ_ALLOW_SELECTION); 255 256 257 //通過使用UDO對象的輸入標記替換UDO對象的現有標記來編輯UDO功能 258 UF_UDOBJ_edit_udo_of_udo_feature(udo_feature_tag, udo_tag); 259 260 //編輯UDO的卷可轉換數據區域 261 double volumes[] = { 1}; 262 UF_UDOBJ_edit_volumes(udo_tag, volumes); 263 264 //編輯UDO的自由格式字符串區域 265 char * strings[] = { "123" }; 266 UF_UDOBJ_edit_strings(udo_tag, strings); 267 268 //編輯UDO的鏈接記錄 269 //UF_UDOBJ_edit_links 270 271 //使用以下編輯功能編輯UDO的鏈接 272 UF_UDOBJ_edit_link(udo_tag, link_defs, Line); 273 274 //編輯UDO的長度可轉換數據區域 275 double length[] = { 1 }; 276 UF_UDOBJ_edit_lengths(udo_tag, length); 277 278 //編輯UDO的自由格式整數區域 279 int integers[] = { 1 }; 280 UF_UDOBJ_edit_integers(udo_tag, integers); 281 282 //編輯UDO的自由格式double型區域 283 double double1[] = { 1 }; 284 UF_UDOBJ_edit_doubles(udo_tag, double1); 285 286 //編輯UDO的可轉換數據面積 287 double area[] = { 1 }; 288 UF_UDOBJ_edit_areas(udo_tag, area); 289 290 //從指定位置開始刪除UDO的可轉換卷區域, 並以要刪除的指定卷數結束 。 291 //UF_UDOBJ_delete_volumes 292 293 //從指定位置開始刪除UDO的自由格式字符串區域, 並以要刪除的指定數量的字符串結束 。 294 //UF_UDOBJ_delete_strings 295 296 //刪除UDO及其關聯的NX 對象之間的擁有鏈接 297 UF_UDOBJ_delete_owning_link(udo_tag, Line); 298 299 //刪除UDO的鏈接 300 UF_UDOBJ_delete_link(udo_tag, link_defs); 301 302 //從指定位置開始刪除UDO的可轉換長度區域, 並以指定的要刪除長度數結束 303 //UF_UDOBJ_delete_lengths 304 305 //從指定位置開始刪除UDO的自由格式整數區域, 並以指定的要刪除的整數數結束 306 //UF_UDOBJ_delete_integers 307 308 //刪除從指定位置開始的UDO的自由格式double型區域, 並以指定的double型要刪除的數量結束 。 309 //UF_UDOBJ_delete_doubles 310 311 //從指定位置刪除UDO的可轉換區域區域, 並以指定的要刪除區域數結束 312 //UF_UDOBJ_delete_areas 313 314 */ 315 316 317 318 319 UF_terminate(); 320 /* Terminate the API environment */ 321 UF_CALL(UF_terminate()); 322 } 323 /***************************************************************************** 324 ** Utilities 325 *****************************************************************************/ 326 /* Unload Handler 327 ** This function specifies when to unload your application from Unigraphics. 328 ** If your application registers a callback (from a MenuScript item or a 329 ** User Defined Object for example), this function MUST return 330 ** "UF_UNLOAD_UG_TERMINATE". */ 331 extern int ufusr_ask_unload(void) 332 { 333 return(UF_UNLOAD_IMMEDIATELY); 334 } 335 336 Caesar盧尚宇 337 2019年11月22日