在NX中没有截图功能,为了方便加工工艺人员制定工艺是制作缩略图,本文介绍三种方法,也许会有第四种,参考【NX二次开发】视图对象截图。但是个人认为适合自己的才是最好。因为要制作一个案例,参考知网论文:一种自动输出数控程序清单的NX二次开发方法中用到该功能,因此提前进行实验功能是否可以使用。本人做过Creo二次开发,sw二次开法,NX二次开发,截至目前最感兴趣的是NX二次开发,作为新生真的有太多的无奈了,程序有太多的BUG了,能坚持到现在,其中要感谢各位博客博主,也要感谢王牌飞行员_里海,以及其他大佬,自学这个已经一年有余,每次遇到BUG是总会有人伸出援手,对此万分感谢。因此博主会分享给各位自己在学习中的一些问题以及解决方案。当然也有自己的小专题,有时需要一瓶饮料,内容可能不是那么完美,但是足够给新手提供思路。
第一种方法,使用单选函数进行截图。个人评价代码太多,哈哈哈,好像之高清截图。
//用户定义
#include <uf_ui.h>
#include <uf_part.h>
#include <uf_csys.h>
#include <uf_disp.h>
#include <uf_modl.h>
#include <uf_trns.h>
#include <uf_ui.h>
#include <uf_vec.h>
#include <uf_view.h>
#include <afx.h>
//用户定义
// 获取输入体相对于NX视图的左上角与右下角坐标
static void GetTwoPoints(tag_t body, double leftT[3], double rightB[3])
{
// 创建临时坐标系
UF_initialize();
double temp = 0.0;
double csys[12] = { 0.0 };
tag_t mtxId = NULL_TAG, csysId = NULL_TAG;
uc6430("", &csys[0], &temp);
uc6433("", &csys[3]);
UF_CSYS_create_matrix(&csys[3], &mtxId);
UF_CSYS_create_temp_csys(&csys[0], mtxId, &csysId);
// 计算包围盒并求得左上角与右下角的坐标
double min[3] = { 0.0 };
double dists[3] = { 0.0 };
double dirs[3][3] = { { 0.0 },{ 0.0 },{ 0.0 } };
UF_MODL_ask_bounding_box_aligned(body, csysId, 0, min, dirs, dists);
UF_VEC3_affine_comb(min, dists[1], &dirs[1][0], leftT);
UF_VEC3_affine_comb(min, dists[0], &dirs[0][0], rightB);
// 将绝对坐标系的点转换为NX视图坐标
int status = 0;
double matrix[12] = { 0.0 };
double abs[9] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
uf5940(abs, &csys[0], matrix, &status);
uf5941(leftT, matrix);
uf5941(rightB, matrix);
UF_terminate();
}
// NX视图坐标转屏幕像素坐标
static bool GetScreenPt(double p1[3], double p2[3], POINT pts[2])
{
UF_initialize();
HWND nxHwnd = (HWND)UF_UI_get_default_parent();
HWND drawZone = FindWindowEx(nxHwnd, NULL, L"NX_SURFACE_WND", NULL);
drawZone = FindWindowEx(nxHwnd, drawZone, L"NX_SURFACE_WND", NULL);
drawZone = GetWindow(drawZone, GW_CHILD);
if (drawZone == NULL)
{
return false;
}
double clip[4] = { 0.0, 1.0, 0.0, 1.0 };
tag_t workView = NULL_TAG;
UF_VIEW_ask_work_view(&workView);
UF_VIEW_ask_current_xy_clip(workView, clip);
RECT draw = { 0 };
GetWindowRect(drawZone, &draw); // 获取绘图区在屏幕的大小
long length = draw.right - draw.left;
long width = draw.bottom - draw.top;
double xSizeView = clip[1] - clip[0];
double ySizeView = clip[3] - clip[2];
double x1 = draw.left + (p1[0] - clip[0]) / xSizeView * length;
double x2 = draw.left + (p2[0] - clip[0]) / xSizeView * length;
double y1 = draw.bottom - (p1[1] - clip[2]) / ySizeView * width;
double y2 = draw.bottom - (p2[1] - clip[2]) / ySizeView * width;
pts[0].x = (long)floor(x1);
pts[0].y = (long)ceil(y1);
pts[1].x = (long)ceil(x2);
pts[1].y = (long)floor(y2);
// 计算机屏幕坐标转换为Client
ScreenToClient(drawZone, &pts[0]);
ScreenToClient(drawZone, &pts[1]);
UF_terminate();
return true;
}
static int init_proc(
UF_UI_selection_p_t select,
void* user_data)
{
int num_triples = 1;
UF_UI_mask_t mask_triples = { UF_solid_type, 0, UF_UI_SEL_FEATURE_BODY };
/* enable only lines and edges */
if (UF_UI_set_sel_mask(select,
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
num_triples, &mask_triples) == 0)
{
return (UF_UI_SEL_SUCCESS);
}
else
{
return (UF_UI_SEL_FAILURE);
}
}
void MyClass::do_it()
{
// TODO: add your code here
UF_initialize();
// 0.使用NXOpen C用户界面
/*char* msg = "Select Object";
UF_UI_mask_t mask = { UF_solid_type, 0, UF_UI_SEL_FEATURE_BODY };
UF_UI_selection_options_t opts = { 0 };
opts.other_options = 0;
opts.reserved = NULL;
opts.num_mask_triples = 1;
opts.mask_triples = &mask;
opts.scope = UF_UI_SEL_SCOPE_WORK_PART;
int response = 0;
tag_t body = NULL_TAG, view = NULL_TAG;
double cursor[3] = { 0.0 };
UF_UI_select_single(msg, &opts, &response, &body, cursor, &view);*/
char cue[] = "cue message";
char title[] = "截图工具包围盒";
int response;
tag_t body, view;
double cursor[3];
UF_UI_select_with_single_dialog(cue, title,UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, NULL,&response, &body, cursor, &view);
char partname[MAX_FSPEC_BUFSIZE + 1];
//查找部件名字
UF_PART_ask_part_name(UF_PART_ask_display_part(), partname);
string name = partname;
int pos = name.find_last_of('\\');
string s1(name.substr(pos + 1));
//分割字符串(只读取part名)
string s2(s1.substr(0, s1.find(".")));
// 1.将选择的对象导出成图片
if (body != NULL_TAG)
{
UF_DISP_set_highlight(body, 0);
// 1.1获取输入体相对于NX视图的左上角与右下角坐标
double leftTop[3] = { 0.0 }, rightBottom[3] = { 0.0 };
GetTwoPoints(body, leftTop, rightBottom);
// 1.2NX视图坐标转屏幕像素坐标
POINT pts[2] = { { 0 },{ 0 } };
bool status = GetScreenPt(leftTop, rightBottom, pts);
// 1.3创建截图
string panthqian = "D:\\nxopen_demo\\";
string panthhou = ".png";
string panth = panthqian+s2+ panthhou;
char* filename = (char*)panth.c_str();
if (status)
{
int corner[2] = { pts[0].x, pts[0].y };
int width = pts[1].x - pts[0].x;
int height = pts[1].y - pts[0].y;
UF_DISP_create_framed_image(filename,UF_DISP_PNG, UF_DISP_WHITE, corner, width, height);
}
}
UF_terminate();
}
第二种方法,巧妙用运函数PVT_create_preview,进行视图截取
//用户定义
#include <uf.h>
#include <UF_DISP.h>
#include <uf_view.h>
#include <uf_assem.h>
#include <uf_part.h>
UF_initialize();
//创建预览对话框
//libugutilsint.dll
//调内部函数PVT_create_preview创建预览对话框
typedef void(*load_ufusr_f_p_t)(unsigned int v1, char const * v2, int v3, unsigned int const * v4, int v5, unsigned int const * v6, bool v7, bool v8, class PVT_view_prefs_s * const v9, enum PVT_cancel_type v10, bool v11, int * v12);//定义传参
load_ufusr_f_p_t PVT_create_preview = NULL;
UF_load_library("D:\\ug\\NXBIN\\libugutilsint.dll", "?PVT_create_preview@@YAPEAUPVT_view_info_s@@IPEBDHPEBIH1_N2QEAUPVT_view_prefs_s@@W4PVT_cancel_type@@2PEAH@Z", (UF_load_f_p_t *)&PVT_create_preview);
//调内部函数PVT_init_view_preferences初始化预览参数
typedef void(*load_ufusr_f_p_t1)(class PVT_view_prefs_s * v1);//定义传参
load_ufusr_f_p_t1 PVT_init_view_preferences = NULL;
UF_load_library("D:\\ug\\NXBIN\\libugutilsint.dll", "?PVT_init_view_preferences@@YAXPEAUPVT_view_prefs_s@@@Z", (UF_load_f_p_t *)&PVT_init_view_preferences);
if (PVT_create_preview != NULL)
{
//获得当前工作部件tag
tag_t work_part = UF_ASSEM_ask_work_part();
//由模型视图名字得到tag
tag_t view_tag = NULL_TAG;
int err = UF_VIEW_ask_tag_of_view_name("TFR_ISO", &view_tag);
err = sizeof(PVT_view_prefs_s*);
PVT_view_prefs_s* view_pref = (PVT_view_prefs_s*)malloc(1000);//
memset(view_pref, 0, 1000);
if (PVT_init_view_preferences != NULL)
{
//初始化预览参数
PVT_init_view_preferences(view_pref);
int errorCode = 0;
PVT_create_preview(view_tag, "", 1, &work_part, 0, NULL, false, true, view_pref, PVT_cancel_type(1), true, &errorCode);
}
}
//查找部件名字
char partname[MAX_FSPEC_BUFSIZE + 1];
UF_PART_ask_part_name(UF_PART_ask_display_part(), partname);
string name = partname;
int pos = name.find_last_of('\\');
string s1(name.substr(pos + 1));
//分割字符串(只读取part名)
string s2(s1.substr(0, s1.find(".")));
string panthqian = "D:\\nxopen_demo\\";
string panthhou = ".png";
string panth = panthqian + s2 + panthhou;
char* filename = (char*)panth.c_str();
//char *filename = "D:\\part1\\ugapi.png";//输出图片的路径名字
UF_DISP_create_image(filename, UF_DISP_PNG, UF_DISP_WHITE);
UF_terminate();
第三种方法:因为我不想让弹出现对话框,所以以上方法不太好,因此我想到应用UF_DISP_create_image函数配合视图进行截屏,反正我感觉还凑合。最起码在导出数控编程程序清单时不用弹对话框。
清单内容,如下:我想要达到一下图片中插入图片的内容
//用户定义
#include <uf.h>
#include <UF_DISP.h>
#include <uf_view.h>
#include <uf_assem.h>
#include <uf_part.h>
#include <uf_defs.h>
#include <NXOpen/NXException.hxx>
#include <NXOpen/Session.hxx>
#include <NXOpen/ModelingView.hxx>
#include <NXOpen/ModelingViewCollection.hxx>
#include <NXOpen/Part.hxx>
#include <NXOpen/PartCollection.hxx>
#include <NXOpen/View.hxx>
UF_initialize();
//初始化
NXOpen::Session *theSession = NXOpen::Session::GetSession();
NXOpen::Part *workPart(theSession->Parts()->Work());
NXOpen::Part *displayPart(theSession->Parts()->Display());
//调整大小为适合窗口的0.7
tag_t tagView;
UF_VIEW_ask_work_view(&tagView);
UF_VIEW_fit_view(tagView, 0.7);//if NULL_TAG, work view is used
// Menu: 定向视图(R)->正三轴测图(T)
workPart->ModelingViews()->WorkView()->Orient(NXOpen::View::CannedTrimetric, NXOpen::View::ScaleAdjustmentFit);
//查找部件名字
char partname[MAX_FSPEC_BUFSIZE + 1];
UF_PART_ask_part_name(UF_PART_ask_display_part(), partname);
string name = partname;
int pos = name.find_last_of('\\');
string s1(name.substr(pos + 1));
//分割字符串(只读取part名)
string s2(s1.substr(0, s1.find(".")));
string panthqian = "D:\\nxopen_demo\\";
string panthhou = "正三轴测图.png";
string panth = panthqian + s2 + panthhou;
char* filename = (char*)panth.c_str();
//判断图片是否已经创建,若创建直接替换
int partNewFullNametatus = 0;//0文件存在,1文件不存在
UF_CFI_ask_file_exist(filename, &partNewFullNametatus); //partNewFullNametatus 检测文件是否存在,0为存在,1为不存在
//partNewFullNametatus 检测文件是否存在,0为存在,1为不存在IsDelectValue
if (partNewFullNametatus == 0)
{
int DeleteFile = remove(filename);
}
UF_DISP_create_image(filename, UF_DISP_PNG, UF_DISP_WHITE);
// Menu: 定向视图(R)->俯视图(O)
workPart->ModelingViews()->WorkView()->Orient(NXOpen::View::CannedTop, NXOpen::View::ScaleAdjustmentFit);
string panthhou2 = "O_XY.png";
string panth2 = panthqian + s2 + panthhou2;
char* filename2 = (char*)panth2.c_str();
//判断图片是否已经创建,若创建直接替换
int partNewFullNametatus2 = 0;//0文件存在,1文件不存在
UF_CFI_ask_file_exist(filename2, &partNewFullNametatus2); //partNewFullNametatus 检测文件是否存在,0为存在,1为不存在
//partNewFullNametatus 检测文件是否存在,0为存在,1为不存在IsDelectValue
if (partNewFullNametatus2 == 0)
{
int DeleteFile = remove(filename2);
}
UF_DISP_create_image(filename2, UF_DISP_PNG, UF_DISP_WHITE);
// Menu: 定向视图(R)->左视图(L)
workPart->ModelingViews()->WorkView()->Orient(NXOpen::View::CannedLeft, NXOpen::View::ScaleAdjustmentFit);
string panthhou3 = "O_YZ.png";
string panth3 = panthqian + s2 + panthhou3;
char* filename3 = (char*)panth3.c_str();
//判断图片是否已经创建,若创建直接替换
int partNewFullNametatus3 = 0;//0文件存在,1文件不存在
UF_CFI_ask_file_exist(filename3, &partNewFullNametatus3); //partNewFullNametatus 检测文件是否存在,0为存在,1为不存在
//partNewFullNametatus 检测文件是否存在,0为存在,1为不存在IsDelectValue
if (partNewFullNametatus3 == 0)
{
int DeleteFile = remove(filename3);
}
UF_DISP_create_image(filename3, UF_DISP_PNG, UF_DISP_WHITE);
UF_terminate();
以上是截图后的图片