NX二次开发 控件RGB颜色选择器值转成[1,256]

环境:VS2017,NX12

目标:RGB颜色选择器控件的返回值是一个RGB数值,如何将其转成NX中颜色区间[1,256]

涉及内容:十六进制,UF函数颜色转换

原理:首先将RGB数值转换成十六进制文本,然后将文本拆分赋值给红、绿、蓝三个子字符串(注意十六进制文本长度),每个子字符串的十六进制文本转成十进制整数,然后十进制整数除以255.0,再调用UF_DISP_ask_closest_color得到结果。

注意:RGB的数值范围很大,但只能得到256个数字,即多对一。反向,256个数字只能得到256个RGB值,即一对一。由此可以总结得到:RGB1->NX->RGB2 如此转换 RGB1不一定等于RGB2。 NX1->RGB->NX2 如此转换NX1 一定等于NX2 。

代码:

#include <map>
#include <vector>
#include <array>
#include <sstream>
#include <string>
#include <iomanip>

#include <NXOpen/Session.hxx>

#include <uf_disp.h>
#include <uf.h>
#include <uf_obj.h>
using namespace std;
using namespace NXOpen;

namespace
{
    std::string Dec2Hex(const int &i) //将int转成16进制字符串
    {
        stringstream ioss; //定义字符串流
        string sTemp; //存放转化后字符
        ioss << setiosflags(ios::uppercase) << hex << i; //以十六制(大写)形式输出
        ioss >> sTemp;
        return sTemp;
    }

    int Hec2Dex(const std::string &value) //将int转成16进制字符串
    {
        if (value.empty())
        {
            return 0;
        }

        return stoi(value, NULL, 16);
    }

    void SplitHex(const std::string &hex, std::vector<std::string> &rgbColorList)
    {
        rgbColorList.clear();

        std::string redString;
        std::string greenString;
        std::string blueString;
        if (!hex.empty())
        {
            int size = hex.size();
            //可能是一位长度或多位长度,需要区分截断
            switch (size)
            {
            case 1:
            {
                blueString = hex;
                break;
            }
            case 2:
            {
                blueString = hex;
                break;
            }
            case 3:
            {
                greenString = hex.substr(0, 1);
                blueString = hex.substr(1);
                break;
            }
            case 4:
            {
                greenString = hex.substr(0, 2);
                blueString = hex.substr(2);
                break;
            }
            case 5:
            {
                redString = hex.substr(0, 1);
                greenString = hex.substr(1, 2);
                blueString = hex.substr(3);
                break;
            }
            case 6:
            {
                redString = hex.substr(0, 2);
                greenString = hex.substr(2, 2);
                blueString = hex.substr(4);
                break;
            }
            default:
            {
                std::string postValue = hex.substr(size - 6);
                redString = postValue.substr(0, 2);
                greenString = postValue.substr(2, 2);
                blueString = postValue.substr(4);
                break;
            }
            }
        }

        rgbColorList.push_back(redString);
        rgbColorList.push_back(greenString);
        rgbColorList.push_back(blueString);
    }

    int CalNXColor(const std::vector<std::string>&rgbHexList)
    {
        if (3 != rgbHexList.size())
        {
            return 1;
        }

        double num = 255.0;
        double clrValue[3] = { 0.0 };
        for (int i = 0; i < rgbHexList.size(); ++i)
        {
            clrValue[i] = Hec2Dex(rgbHexList[i]) / num;
        }

        int nxColor = 1;
        UF_DISP_ask_closest_color(UF_DISP_rgb_model, clrValue, UF_DISP_CCM_EUCLIDEAN_DISTANCE, &nxColor);

        return nxColor;
    }


    void CompleteTwoLen(std::string &value)
    {
        if (value.empty())
        {
            value = "00";
        }
        else if (1 == value.size())
        {
            value = "0" + value;
        }
        else if (2 == value.size())
        {

        }
        else
        {
            value = value.substr(value.size() - 2);
        }
    }

    //1~256 转长整型 4227200
    int ColorToRGBColor(const int &color)
    {
        char *clrName = NULL;
        double clrValues[3] = { 0.0 };
        UF_DISP_ask_color(color, UF_DISP_rgb_model, &clrName, clrValues);
        UF_free(clrName);

        double num = 255.0;
        int clrIntValues[3] = { clrValues[0] * num, clrValues[1] * num, clrValues[2] * num };

        //整型转16进制,这里需要注意,必须保证是六位长度
        std::string hex0 = Dec2Hex(clrIntValues[0]);
        std::string hex1 = Dec2Hex(clrIntValues[1]);
        std::string hex2 = Dec2Hex(clrIntValues[2]);
        CompleteTwoLen(hex0);
        CompleteTwoLen(hex1);
        CompleteTwoLen(hex2);
        std::string hexString = hex0 + hex1 + hex2;
        return Hec2Dex(hexString);
    }

    //长整型 4227200 转 1~256
    int RGBColorToColor(const int &rgbColor)
    {
        std::string hex = Dec2Hex(rgbColor);
        std::vector<std::string> rgbList;
        SplitHex(hex, rgbList);
        int res = CalNXColor(rgbList);
        if (res < 1 || res > 256)
        {
            res = 1;
        }

        return res;
    }
}

extern "C" DllExport void  ufusr(char *param, int *retcod, int param_len)
{
    UF_initialize();

    //nxColor = 1~256
    int nxColor = 135;

    //rgbColor = 3498129
    int rgbColor = ColorToRGBColor(nxColor);

    //nxColorNext = 135
    int nxColorNext = RGBColorToColor(rgbColor);

    UF_terminate();
}

extern "C" DllExport int ufusr_ask_unload()
{
    return (int)Session::LibraryUnloadOptionImmediately;
}

extern "C" DllExport void ufusr_cleanup(void)
{

}

   

<think>好的,我现在需要解决的问题是,在NX8.5中,通过二次开发如何从代码中获取对象颜色拾取器控件显示的颜色ID。用户已经提供了一些信息,我需要仔细分析这些信息,并尝试找到正确的解决方法。 首先,用户提到使用NX Open API进行二次开发,这可能涉及C#或VB.NET。颜色拾取器控件可能是一个UI控件,比如ColorTool或某种自定义控件。用户需要的是当用户在界面上选择颜色后,通过代码获取所选颜色的ID。 根据用户提供的步骤,首先需要获取颜色拾取器控件的引用,这可能通过UI.GetUI()方法获取UI对象,然后使用Find方法或FindByName找到控件。然后,获取控件的Value属性,这可能返回颜色ID或者RGB。需要注意返回的是整数还是其他类型,可能需要转换。 接下来,用户提供的示例代码是C#,使用了UI.GetUI()、FindBlock和GetProperties(),然后通过GetInteger("Value")获取颜色ID。这可能是一个正确的方法,但需要验证是否正确对应到颜色拾取器控件。 我需要考虑几个关键点: 1. 如何正确获取颜色拾取器控件的引用。可能需要知道控件的名称或块名称,这在界面设计时确定。如果控件在某个Block中,可能需要使用FindBlock方法。 2. 获取到控件后,确定其Value属性的数据类型。是否是直接的整数颜色ID,或者是否是RGB。例如,NX中的颜色ID通常是从1到216的整数,或者0表示无颜色。如果控件返回的是RGB,可能需要转换到颜色ID。 3. 如何处理可能的异常或错误。例如,控件未找到,或者属性不存在,或者类型转换问题。 可能的疑问点: - 用户提供的示例中使用GetProperties().GetInteger("Value")是否正确?是否"Value"属性确实对应颜色ID? - 是否需要考虑不同版本的NX API之间的差异?例如,NX8.5可能和后续版本的API有所不同,是否有特定于该版本的方法? - 是否有其他方式获取颜色信息?例如,通过事件处理程序,在颜色改变时触发事件获取。 可能需要查阅NX8.5的API文档,特别是关于UI控件属性部分,查看ColorTool控件是否有Value属性,以及该属性的类型和返回。如果文档中说明ColorTool的Value属性返回的是颜色ID,那么示例代码是正确的。否则可能需要调整。 另外,用户可能需要确保在正确的会话中获取UI,例如在对话框打开的情况下,否则FindBlock可能找不到控件。因此,代码应该在对话框的回调函数中执行,或者在对话框显示之后调用。 总结步骤: 1. 确定颜色拾取器控件Block名称和控件名称,例如在创建对话框时定义的名称。 2. 使用UI.GetUI()获取当前UI会话。 3. 使用FindBlock方法定位到控件所在的Block。 4. 使用GetProperties()获取控件属性,并从中提取Value属性作为整数,即颜色ID。 5. 处理可能的异常,例如控件未找到或属性类型错误。 可能的测试方法:创建一个简单的测试对话框,添加颜色拾取控件,并在按钮点击事件中运行上述代码,输出颜色ID,观察是否与实际选择的颜色匹配。 如果用户遇到问题,可能需要检查控件名称是否正确,或者是否有其他方法获取颜色信息。例如,某些情况下可能需要使用特定的方法如GetColor()而不是直接读取Value属性。</think>在NX8.5中,通过二次开发获取对象颜色拾取器控件颜色ID,可以按照以下步骤实现: --- ### **1. 关键思路** - **控件类型**:颜色拾取器通常是 `UF_UI_color_t` 或 `.ColorTool` 类型控件。 - **属性获取**:通过NX Open API访问控件的 `Value` 属性,该属性直接返回NX预定义的颜色ID(1-216,0表示无颜色)。 --- ### **2. 实现代码(C#示例)** ```csharp using NXOpen; using NXOpen.UI; public int GetSelectedColorID() { // 获取当前UI会话 NXOpen.UI theUI = UI.GetUI(); // 定位颜色拾取器控件所在的Block(假设块名为"MyBlock",控件名为"ColorPicker") NXOpen.BlockStyler.BlockDialog dialog = theUI.FindBlock("MyBlock"); if (dialog != null) { // 获取控件属性 PropertyList props = dialog.GetProperties(); int colorID = props.GetInteger("Value"); // 关键属性 // 释放资源 props.Dispose(); return colorID; } return -1; // 未找到控件时返回-1 } ``` --- ### **3. 关键点说明** - **控件名称**:需替换`MyBlock`和`ColorPicker`为实际对话框设计时的块名和控件名。 - **颜色ID范围**:NX颜色ID为0(无颜色)或1-216的标准色,可通过`NXOpen.UF.UFUi.AskColorRgb`转换ID为RGB。 - **异常处理**:建议添加`try-catch`块处理控件未找到或属性错误。 --- ### **4. 验证方法** - 在对话框的`OK`或回调函数中调用上述方法,输出颜色ID。 - 使用`NXOpen.UF.UFUi.AskColorName(colorID)`确认颜色名称是否匹配选择。 --- ### **5. 注意事项** - **版本兼容性**:NX8.5与后续版本API可能存在差异,建议查阅对应版本的`NXOpen.chm`文档。 - **实时更新**:若需实时获取颜色变化,可在控件事件回调中绑定处理函数。 通过以上步骤,可准确获取用户通过颜色拾取器选择的颜色ID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值