【无标题】凸台类零件底面的识别

判断底面算法做了改进,通过遍历判断零件面和包容体面之间的关系,找到最接近的以实现唯一性。

/* Include files */
#include <stdarg.h>
#include <stdio.h>
#include <float.h>  // 定义 DBL_MAX
#include <math.h>   // 定义 fabs
#include <uf.h>
#include <uf_ui_types.h>
#include <uf_ui.h>
#include <uf_obj.h>
#include <uf_modl.h>
#include <stdlib.h>
#include <uf_part.h>

static void ECHO(const char *format, ...)
{
	char msg[UF_UI_MAX_STRING_BUFSIZE];
	va_list args;
	va_start(args, format);
	vsprintf_s(msg, sizeof(msg), format, args);
	va_end(args);
	UF_UI_open_listing_window();
	UF_UI_write_listing_window(msg);
	UF_print_syslog(msg, FALSE);
}

#define UF_CALL(X) (report_error(__FILE__, __LINE__, #X, (X)))

static int report_error(const char *file, int line, const char *call, int irc)
{
	if (irc)
	{
		char err[133];
		UF_get_fail_message(irc, err);
		ECHO("*** ERROR code %d at line %d in %s:\n", irc, line, file);
		ECHO("+++ %s\n", err);
		ECHO("%s;\n", call);
	}
	return(irc);
}

/*****************************************************************************
**  Activation Methods
*****************************************************************************/
extern DllExport void ufusr(char *parm, int *returnCode, int rlen)
{
	/* Initialize the API environment */
	if (UF_CALL(UF_initialize()))
	{
		/* Failed to initialize */
		return;
	}

	tag_t bodyofwork_tag = NULL_TAG;
	tag_t object = NULL_TAG;
	tag_t DisplayTag_body = UF_PART_ask_display_part(); // 获取当前显示部件

	// 获取当前显示部件的对象tag
	object = UF_OBJ_cycle_all(DisplayTag_body, object);
	while (object != NULL_TAG)
	{
		int type = 0, subtype = 0;
		UF_OBJ_ask_type_and_subtype(object, &type, &subtype); // 获得对象类型
		if (type == UF_solid_type && 0 == subtype)
		{ // 实体
			UF_OBJ_set_color(object, 1); // 设置颜色
			bodyofwork_tag = object;
		}
		object = UF_OBJ_cycle_all(DisplayTag_body, object);
	}

	// 获取零件的极限尺寸并创建包容块
	double corner_point1[3] = { 0.0, 0.0, 0.0 };
	char edge_12[3][256]; // Use a 2D array
	double box1[6];

	UF_MODL_ask_bounding_box(bodyofwork_tag, box1);

	sprintf_s(edge_12[0], sizeof(edge_12[0]), "%f", box1[3] - box1[0]);
	sprintf_s(edge_12[1], sizeof(edge_12[1]), "%f", box1[4] - box1[1]);
	sprintf_s(edge_12[2], sizeof(edge_12[2]), "%f", box1[5] - box1[2]);

	tag_t blk_tag12 = NULL_TAG;
	tag_t body_tag1 = NULL_TAG;
	char *edge_len12[3] = { edge_12[0], edge_12[1], edge_12[2] };

	UF_MODL_create_block(UF_NULLSIGN, NULL_TAG, corner_point1, edge_len12, &blk_tag12); // 创建包容块

	UF_MODL_ask_feat_body(blk_tag12, &body_tag1); // 获得包容块的实体标签

	// 获取包容块和零件的面列表
	uf_list_p_t face_list;
	UF_MODL_create_list(&face_list); // 初始化链表
	UF_MODL_ask_body_faces(bodyofwork_tag, &face_list); // 通过体特征获得面的链表

	uf_list_p_t face_list1;
	UF_MODL_create_list(&face_list1); // 初始化链表
	UF_MODL_ask_body_faces(body_tag1, &face_list1);

	int i = 0, k = 0; // 面链表的序号值
	tag_t current_face = NULL_TAG;
	tag_t current_face1 = NULL_TAG;
	UF_MODL_ask_list_count(face_list, &i); // 获得面组的总数量
	UF_MODL_ask_list_count(face_list1, &k);

	// 新逻辑:全局找到面积比例最接近1的平面面(方向匹配),只标记一个零件面为红色(186)
	tag_t best_part_face_tag = NULL_TAG;
	double min_diff = DBL_MAX; // 全局最小差异
	const double epsilon = 1e-6; // 浮点容差,用于方向比较

	for (int h = 0; h < k; h++) // 遍历包容块面
	{
		UF_MODL_ask_list_item(face_list1, h, &current_face1);
		tag_t face_tag1 = current_face1;

		double acc_val1[11] = { 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		double mass_props1[47];
		double statistics1[13];
		tag_t sheet_body1 = NULL_TAG;
		UF_MODL_extract_face(face_tag1, 0, &sheet_body1); // 提取面为独立体
		UF_MODL_ask_mass_props_3d(&sheet_body1, 1, 2, 3, 1.0, 1, acc_val1, mass_props1, statistics1);
		double block_area = mass_props1[0]; // 包容块面面积
		if (block_area == 0.0) {
			UF_OBJ_delete_object(sheet_body1); // 删除无效片体
			continue;
		}

		int Type1;
		double Point1[3];
		double Dir1[3];
		double Box1[6];
		double Radius1[3];
		double RadData1[3];
		int NormDir1;
		UF_MODL_ask_face_data(face_tag1, &Type1, Point1, Dir1, Box1, Radius1, RadData1, &NormDir1);

		if (Type1 != 22) {
			UF_OBJ_delete_object(sheet_body1); // 删除非平面片体
			continue;
		}

		for (int j = 0; j < i; j++) // 遍历零件面
		{
			UF_MODL_ask_list_item(face_list, j, &current_face);
			tag_t face_tag = current_face;

			double acc_val[11] = { 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
			double mass_props[47];
			double statistics[13];
			tag_t sheet_body = NULL_TAG;
			UF_MODL_extract_face(face_tag, 0, &sheet_body); // 提取面为独立体
			UF_MODL_ask_mass_props_3d(&sheet_body, 1, 2, 3, 1.0, 1, acc_val, mass_props, statistics);
			double part_area = mass_props[0];
			if (part_area == 0.0) {
				UF_OBJ_delete_object(sheet_body); // 删除无效片体
				continue;
			}

			int Type;
			double Point[3];
			double Dir[3];
			double Box[6];
			double Radius[3];
			double RadData[3];
			int NormDir;
			UF_MODL_ask_face_data(face_tag, &Type, Point, Dir, Box, Radius, RadData, &NormDir);

			if (Type != 22) {
				UF_OBJ_delete_object(sheet_body); // 删除非平面片体
				continue;
			}

			// 方向比较,使用容差
			bool dir_match = (fabs(Dir[0] - Dir1[0]) < epsilon) &&
				(fabs(Dir[1] - Dir1[1]) < epsilon) &&
				(fabs(Dir[2] - Dir1[2]) < epsilon);

			if (dir_match) {
				double s = block_area / part_area;
				double diff = fabs(s - 1.0);
				if (diff < min_diff) {
					min_diff = diff;
					best_part_face_tag = face_tag;
				}
			}

			// 删除片体
			UF_OBJ_delete_object(sheet_body);
		}

		// 删除包容块片体
		UF_OBJ_delete_object(sheet_body1);
	}

	// 只标记全局最接近的面(如果找到)为红色
	if (best_part_face_tag != NULL_TAG) {
		UF_OBJ_set_color(best_part_face_tag, 186); // 红色
	}

	// 释放内存
	UF_MODL_delete_list(&face_list);
	UF_MODL_delete_list(&face_list1);

	/* Terminate the API environment */
	UF_CALL(UF_terminate());
}

/*****************************************************************************
**  Utilities
*****************************************************************************/
extern int ufusr_ask_unload(void)
{
	return(UF_UNLOAD_IMMEDIATELY);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值