找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫码登录

搜索
查看: 241|回复: 2

[求助] NXOpen如何实现自动范围选择

[复制链接]

1

主题

0

回帖

7

积分

列兵

积分
7
发表于 2026-4-2 16:22:45 | 显示全部楼层 |阅读模式
有个需求  要求无UI  根据一条曲线自动计算范围进行自动选择  目前没有什么头绪

0

主题

2

回帖

6

积分

列兵

积分
6
发表于 2026-4-15 14:26:17 | 显示全部楼层
  1. // AutoSelectByCurveSkeleton.cpp
  2. // NX Open C++ / UFUN skeleton: no UI, auto-select bodies by one curve range.

  3. #include <uf.h>
  4. #include <uf_obj.h>
  5. #include <uf_modl.h>
  6. #include <uf_part.h>
  7. #include <uf_ui.h>
  8. #include <uf_group.h>

  9. #include <algorithm>
  10. #include <array>
  11. #include <cmath>
  12. #include <cstdlib>
  13. #include <cstring>
  14. #include <limits>
  15. #include <string>
  16. #include <vector>

  17. namespace
  18. {
  19.     struct Config
  20.     {
  21.         double k = 0.02;
  22.         double rMin = 2.0;
  23.         double tol = 0.01;
  24.         std::string groupName = "AUTO_SELECT_BY_CURVE";
  25.     };

  26.     static void Log(const std::string &msg)
  27.     {
  28.         UF_UI_open_listing_window();
  29.         UF_UI_write_listing_window(msg.c_str());
  30.         UF_UI_write_listing_window("\n");
  31.     }

  32.     static bool ParseTagFromEnv(const char *key, tag_t &tag)
  33.     {
  34.         const char *v = std::getenv(key);
  35.         if (!v || std::strlen(v) == 0)
  36.             return false;

  37.         char *end = nullptr;
  38.         unsigned long long raw = std::strtoull(v, &end, 10);
  39.         if (end == v)
  40.             return false;

  41.         tag = static_cast<tag_t>(raw);
  42.         return (tag != NULL_TAG);
  43.     }

  44.     static bool AskBoundingBox(tag_t obj, std::array<double, 6> &bbox)
  45.     {
  46.         double b[6] = {0.0};
  47.         int rc = UF_MODL_ask_bounding_box(obj, b);
  48.         if (rc != 0)
  49.             return false;

  50.         for (int i = 0; i < 6; ++i)
  51.             bbox[i] = b[i];
  52.         return true;
  53.     }

  54.     static double BboxDiagonal(const std::array<double, 6> &bb)
  55.     {
  56.         const double dx = bb[3] - bb[0];
  57.         const double dy = bb[4] - bb[1];
  58.         const double dz = bb[5] - bb[2];
  59.         return std::sqrt(dx * dx + dy * dy + dz * dz);
  60.     }

  61.     static std::array<double, 6> ExpandBbox(const std::array<double, 6> &bb, double r)
  62.     {
  63.         return {bb[0] - r, bb[1] - r, bb[2] - r, bb[3] + r, bb[4] + r, bb[5] + r};
  64.     }

  65.     static bool BboxIntersects(const std::array<double, 6> &a, const std::array<double, 6> &b)
  66.     {
  67.         bool sep = a[3] < b[0] || a[0] > b[3] ||
  68.                    a[4] < b[1] || a[1] > b[4] ||
  69.                    a[5] < b[2] || a[2] > b[5];
  70.         return !sep;
  71.     }

  72.     static bool AskMinDistance(tag_t obj1, tag_t obj2, double &dist)
  73.     {
  74.         double pt1[3] = {0.0}, pt2[3] = {0.0};
  75.         int rc = UF_MODL_ask_minimum_dist(obj1, obj2, 0, nullptr, 0, nullptr, &dist, pt1, pt2);
  76.         return rc == 0;
  77.     }

  78.     static std::vector<tag_t> CollectSolidBodiesInWorkPart()
  79.     {
  80.         std::vector<tag_t> bodies;
  81.         tag_t part = UF_PART_ask_display_part();
  82.         if (part == NULL_TAG)
  83.             return bodies;

  84.         tag_t obj = NULL_TAG;
  85.         while (UF_OBJ_cycle_objs_in_part(part, UF_solid_type, &obj) == 0 && obj != NULL_TAG)
  86.         {
  87.             int type = 0;
  88.             int subtype = 0;
  89.             UF_OBJ_ask_type_and_subtype(obj, &type, &subtype);
  90.             if (subtype == UF_solid_body_subtype)
  91.                 bodies.push_back(obj);
  92.         }

  93.         return bodies;
  94.     }

  95.     static tag_t FindCurveFromEnvOrFail()
  96.     {
  97.         tag_t curve = NULL_TAG;
  98.         if (!ParseTagFromEnv("NX_CURVE_TAG", curve))
  99.         {
  100.             Log("[ERROR] Missing env NX_CURVE_TAG. Example: set NX_CURVE_TAG=123456");
  101.             return NULL_TAG;
  102.         }

  103.         int type = 0, subtype = 0;
  104.         if (UF_OBJ_ask_type_and_subtype(curve, &type, &subtype) != 0)
  105.         {
  106.             Log("[ERROR] Invalid curve tag.");
  107.             return NULL_TAG;
  108.         }

  109.         if (type != UF_line_type && type != UF_circle_type && type != UF_conic_type && type != UF_spline_type && type != UF_curve_type)
  110.         {
  111.             Log("[ERROR] Tag is not a supported curve object.");
  112.             return NULL_TAG;
  113.         }

  114.         return curve;
  115.     }

  116.     static tag_t CreateGroupWithMembers(const std::string &name, const std::vector<tag_t> &members)
  117.     {
  118.         if (members.empty())
  119.             return NULL_TAG;

  120.         tag_t groupTag = NULL_TAG;
  121.         int rc = UF_GROUP_create(name.c_str(), static_cast<int>(members.size()), const_cast<tag_t *>(members.data()), &groupTag);
  122.         if (rc != 0)
  123.             return NULL_TAG;

  124.         return groupTag;
  125.     }

  126.     static int Run(const Config &cfg)
  127.     {
  128.         tag_t curve = FindCurveFromEnvOrFail();
  129.         if (curve == NULL_TAG)
  130.             return 1;

  131.         std::array<double, 6> curveBb{};
  132.         if (!AskBoundingBox(curve, curveBb))
  133.         {
  134.             Log("[ERROR] Failed to query curve bounding box.");
  135.             return 2;
  136.         }

  137.         const double curveScale = BboxDiagonal(curveBb);
  138.         const double R = std::max(curveScale * cfg.k, cfg.rMin);
  139.         const auto expanded = ExpandBbox(curveBb, R);

  140.         auto allBodies = CollectSolidBodiesInWorkPart();
  141.         std::vector<tag_t> coarse;
  142.         coarse.reserve(allBodies.size());

  143.         for (tag_t b : allBodies)
  144.         {
  145.             std::array<double, 6> bb{};
  146.             if (!AskBoundingBox(b, bb))
  147.                 continue;
  148.             if (BboxIntersects(expanded, bb))
  149.                 coarse.push_back(b);
  150.         }

  151.         std::vector<tag_t> selected;
  152.         selected.reserve(coarse.size());

  153.         for (tag_t b : coarse)
  154.         {
  155.             double d = std::numeric_limits<double>::max();
  156.             if (!AskMinDistance(curve, b, d))
  157.                 continue;
  158.             if (d <= R + cfg.tol)
  159.                 selected.push_back(b);
  160.         }

  161.         tag_t group = CreateGroupWithMembers(cfg.groupName, selected);

  162.         Log("[INFO] Auto select by curve done.");
  163.         Log("  curve tag: " + std::to_string(static_cast<unsigned long long>(curve)));
  164.         Log("  curve scale (bbox diagonal): " + std::to_string(curveScale));
  165.         Log("  radius R: " + std::to_string(R));
  166.         Log("  total bodies: " + std::to_string(allBodies.size()));
  167.         Log("  coarse candidates: " + std::to_string(coarse.size()));
  168.         Log("  selected: " + std::to_string(selected.size()));
  169.         Log("  group tag: " + std::to_string(static_cast<unsigned long long>(group)));

  170.         return 0;
  171.     }
  172. }

  173. extern "C" DllExport void ufusr(char *param, int *returnCode, int rlen)
  174. {
  175.     UF_initialize();

  176.     Config cfg;
  177.     int rc = Run(cfg);
  178.     if (returnCode)
  179.         *returnCode = rc;

  180.     UF_terminate();
  181. }

  182. extern "C" DllExport int ufusr_ask_unload(void)
  183. {
  184.     return UF_UNLOAD_IMMEDIATELY;
  185. }
复制代码

0

主题

11

回帖

269

积分

二级士官

积分
269
发表于 2026-4-16 11:00:48 | 显示全部楼层

虽然看不懂   但666
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

咨询QQ:1359218528|发帖须知!|Archiver|手机版|小黑屋|UG爱好者论坛 ( 京ICP备10217105号-2 )

GMT+8, 2026-5-20 07:32

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表