基本思路

  1. 检索所有模型尺寸
  2. 按照位置对尺寸进行排序
  3. 检索球标模型
  4. 遍历尺寸,根据尺寸类型和占位宽度计算球标和尺寸的相对位置
  5. 创建顺序球标

程序实现

  1. 检索尺寸前先判断当前环境是否为绘图环境,如果不是则直接退出。下面函数可以判断当前环境。
int CheckEnv(int count, ...)
{pfcSession_ptr session = pfcGetProESession();pfcModels_ptr Models = session->ListModels();pfcModel_ptr Model = session->GetCurrentModel();pfcModelType ModelType;int EnvFlag = 0;if (Models->getarraysize() == 0 || Model == NULL){session->UIDisplayLocalizedMessage(MSGFILE, "Model is not found in current session!", NULL);}else if (count == 0){if (Model->GetType() == pfcMDL_DRAWING){EnvFlag = 1;}}else{va_list ap;va_start(ap, count);for (int i = 0; i < count; i++){if (Model->GetType() == va_arg(ap, pfcModelType)){EnvFlag = 1;break;}}va_end(ap);}if (EnvFlag == 0){LOG(LOG_WARNING) << "ModelType is error!";session->UIDisplayLocalizedMessage(MSGFILE, "ModelType is error!", NULL);}return EnvFlag;
}
  1. 当图纸为零件图时,可以直接检索尺寸。
    pfcModelItems_ptr mdlitems = mdl->ListItems(pfcITEM_DIMENSION);
    当图纸为组件图时,需要先获取当前图纸中的所有零件,再获取零件的相应尺寸
pfcModels_ptr Models = drawing->ListModels();
//获取组件图中的尺寸
for (xint i = 0; i < Models->getarraysize(); i++)
{Dimensions->insertseq(0, drawing->ListShownDimensions(Models->get(i), pfcModelItemType_nil));
}
  1. 检索到的尺寸可以存放在 pfcDimension2Ds_ptr 对象中,为方便后续计算,这里创建 DimensionStruct 类。检索到的尺寸初始化为 DimensionStruct 类的对象,并存放在 vector 中。该类中对尺寸的位置、视图中心的位置以及和尺寸和视图中心的相对角度和距离等数据进行计算,方便后续排序使用。
class DimensionStruct
{
private:pfcDimension2D_ptr dimension;pfcPoint3D_ptr location;double angle;double distance;pfcPoint3D_ptr viewcenter;xstring viewname;pfcView2D_ptr view2d;public:void Create(pfcDimension2D_ptr dim);pfcDimension2D_ptr GetDimension();pfcPoint3D_ptr GetViewCenter();double GetAngle();double GetDistance();
};
  1. 对尺寸进行排序
    基本排序逻辑为围绕视图中心逆时针方向,由内到外排序。不同视图则按从上到下、从左到右的顺序。利用 sort 函数排序,排序函数如下,顺序正确时排序函数返回 true,否则返回 false。
    下面排序算法只是简单的根据角度和位置排序,对于尺寸较为密集的位置,排序出来的效果可能不是很理想。
//尺寸位置排序函数
bool SortDimensions(const DimensionStruct &td1, const DimensionStruct &td2)
{DimensionStruct d1, d2;d1 = td1;d2 = td2;float vcx1, vcx2, vcy1, vcy2;vcx1 = d1.GetViewCenter()->get(0);vcx2 = d2.GetViewCenter()->get(0);vcy1 = d1.GetViewCenter()->get(1);vcy2 = d2.GetViewCenter()->get(1);if (vcx1 > vcx2){return false; //视图中心:d1在d2的右侧}else if (IsEqual(vcx1, vcx2) && (vcy1 < vcy2)){return false; //试图中心:d1在d2的下方}else if (IsEqual(vcx1, vcx2) && IsEqual(vcy1, vcy2)){double angle1, angle2;double dist1, dist2;angle1 = d1.GetAngle();angle2 = d2.GetAngle();dist1 = d1.GetDistance();dist2 = d2.GetDistance();if (angle1 > angle2){return false; //d1在d2顺时针的前方}else if (IsEqual(angle1, angle2) && dist1 > dist2){return false; //d1比d2靠近视图中心}}return true;
}
  1. 检索球标模型
pfcDetailSymbolDefItem_ptr symdef = ((pfcDetailItemOwner_ptr)mdl2D)->RetrieveSymbolDefinition("boolean", SymbolDir, NULL, true);
pfcDetailSymbolInstInstructions_ptr symins = pfcDetailSymbolInstInstructions::Create(symdef);

先检索模型到工作区,然后创建 SymbolInstInstructions,后面创建球标要用到
6. 遍历尺寸
遍历排序后的模型,根据尺寸类型计算球标和尺寸的相对位置

//计算尺寸字符占位宽度
int CalDimensionValueWideth(pfcDimension2D_ptr dimension)
{int tpad = 0;smatch result;regex pattern("\\d+:");xstringsequence_ptr texts = dimension->GetTexts();//判断是否有公差xbool TolIsDisplay = dimension->GetIsToleranceDisplayed();if (TolIsDisplay){tpad = 2 * pad;}//判断是否存在符号for (xint j = 0; j < texts->getarraysize(); j++){string text = texts->get(j); //{0:⌀}{1:@D}string::const_iterator iterStart = text.begin();string::const_iterator iterEnd = text.end();int temp = 0;//正则匹配\d+:的数量while (regex_search(iterStart, iterEnd, result, pattern)){temp += 1;iterStart = result[0].second;}if (temp > 1)tpad += (temp - 1) * pad;}xreal DimValue = dimension->GetDimValue();if (DimValue < 1.0)DimValue += 1.0;int int_dimvalue = round(DimValue * 100); //保留两位小数//判断数值占位宽度for (int t = 0; t < 2; t++) //处理小数部分{if (int_dimvalue % 10 != 0){tpad += 0.5 * pad; //小数点占位break;}int_dimvalue /= 10;}while (int_dimvalue != 0) //处理整数部分{int_dimvalue /= 10;tpad += 0.5 * pad;}return tpad;
}
//计算球标位置
pfcPoint3D_ptr CalSymbolLoc(pfcDimension2D_ptr dimension)
{pfcPoint3D_ptr loc;int DimWidth = CalDimensionValueWideth(dimension);//偏移位置补偿 计算的字符宽度加1.5pad间隙/2即为球标到尺寸中心距离int tpad = ceil((DimWidth + 1.5 * pad) / 2);loc = dimension->GetLocation();if ((dimension->GetDimType() == pfcDIM_LINEAR)){pfcPoint3Ds_ptr Points = pfcPoint3Ds::create();pfcView2D_ptr view = dimension->GetView();xreal viewscal = view->GetScale();SetDimensionMid(dimension, Points); //线性尺寸居中xreal dimvalue, dx, dy;dimvalue = dimension->GetDimValue();dx = abs(Points->get(0)->get(0) - Points->get(1)->get(0));dy = abs(Points->get(0)->get(1) - Points->get(1)->get(1));loc = dimension->GetLocation();if (IsEqual(dimvalue * viewscal, dy)) //连接点纵坐标差值与尺寸数值相等,为竖直尺寸{loc->set(0, loc->get(0) - 2);loc->set(1, loc->get(1) + tpad);}else if (IsEqual(dimvalue * viewscal, dx)) //连接点横坐标差值与尺寸数值相等,为水平尺寸{loc->set(1, loc->get(1) + 2);loc->set(0, loc->get(0) + tpad);}else //斜向尺寸 目前没有方法计算尺寸方向 球标放置在尺寸左上角{loc->set(0, loc->get(0) - pad);loc->set(1, loc->get(1) + pad);}}else if (dimension->GetDimType() == pfcDIM_DIAMETER) //直径尺寸标注文本为水平方向{loc->set(1, loc->get(1) + 2);loc->set(0, loc->get(0) + tpad);}else //其余尺寸球标放置在左上角{loc->set(0, loc->get(0) - pad);loc->set(1, loc->get(1) + pad);}return loc;
}
  1. 创建球标
//创建球标
void CreateSymbolIndex(pfcDrawing_ptr drawing,pfcDimension2D_ptr dimension,pfcDetailSymbolInstInstructions_ptr symins,xint index)
{try{pfcPoint3D_ptr symloc = CalSymbolLoc(dimension);stringstream symindex;symindex << index + 1;pfcDetailVariantText_ptr textvalue = pfcDetailVariantText::Create("index", symindex);pfcDetailVariantTexts_ptr textvalues = pfcDetailVariantTexts::create();textvalues->append(textvalue);symins->SetTextValues(textvalues);pfcSelection_ptr selection = pfcCreateModelItemSelection((pfcModelItem_ptr)dimension);pfcOffsetAttachment_ptr attachment = pfcOffsetAttachment::Create(selection, symloc); //与当前尺寸关联pfcDetailLeaders_ptr leaders = pfcDetailLeaders::Create();leaders->SetItemAttachment((pfcAttachment_ptr)attachment);symins->SetInstAttachment(leaders);symins->SetIsDisplayed(true);symins->SetScaledHeight(3);((pfcDetailItemOwner_ptr)drawing)->CreateDetailItem((pfcDetailCreateInstructions_ptr)symins);textvalues->clear(); //不清空会有异常}OTK_EXCEPTION_PRINT_LOGcatch (...){LOG(LOG_ERROR) << "Create Symbol Index Error!";}
}

注意问题

  1. 修改尺寸位置
    直接修改尺寸位置的时候,SetLocation 函数设置尺寸位置产生偏移,具体偏移原因未找到,使用下面函数进行修正
//修改尺寸位置 纠正SetLocation函数设置尺寸位置时产生偏移
void ChangeDimensionLocation(pfcDimension2D_ptr dimension, pfcPoint3D_ptr dimloc)
{dimension->SetLocation(dimloc);//纠正更改尺寸时产生的偏差pfcPoint3D_ptr dimlocnew = dimension->GetLocation();double dx = dimloc->get(0) - dimlocnew->get(0); //计算x偏移值double dy = dimloc->get(1) - dimlocnew->get(1); //计算y偏移值dimloc->set(0, dimloc->get(0) + dx);            //修正x偏移dimloc->set(1, dimloc->get(1) + dy);            //修正y偏移dimension->SetLocation(dimloc);
}

源代码

2.1AutoIndex

Creo 二次开发-自动标注球标相关推荐

  1. Revit二次开发——自动标注轴网

    引言:在自动标注大主题下,自动标注轴网:利弊等望读者自行改进(仅限平面视图) 开始: using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; ...

  2. Revit二次开发——自动标注钢筋思路(3)

    仍然是接上一篇 本篇分析标注钢筋的思路 (另:构件图思路分享系列的阅读顺序是2-3-1) 测试环境visual studio2017 + revit2016 demo: 实现思路: 测试时,首先想到的 ...

  3. cad通过钢筋大样生成钢筋明细表插件_Revit二次开发——自动生成构件图(总结)...

    之前测试导出构件图的功能实现,拆分了各模块分布进行测试:Revit二次开发--一键导出构件图(1) Revit二次开发--叠合板自动配筋(2) Revit二次开发--自动标注钢筋思路(3) 本篇为这个 ...

  4. Revit二次开发——自动生成构件图(总结)

    之前测试导出构件图的功能实现,拆分了各模块分布进行测试: Revit二次开发--一键导出构件图(1) Revit二次开发--叠合板自动配筋(2) Revit二次开发--自动标注钢筋思路(3) 本篇为这 ...

  5. creo二次开发python_使用C#/.net语言进行ProE/Creo二次开发

    随便哪个版本的Visual studio 设置系统环境变量 通常这个环境变量在安装ProE的时候如果选择安装VBAPI就会自动设置 注意32位和64位操作系统路径是不同的.我的是64位操作系统. 然后 ...

  6. 陈伯雄lisp_基于AutoLisp的AutoCAD二次开发自动生成系统图

    龙源期刊网 http://www.qikan.com.cn 基于 AutoLisp 的 AutoCAD 二次开发自动 生成系统图 作者:郎建山 金江 来源:<科技视界> 2013 年第 2 ...

  7. CAD自控lisp_基于AutoLisp的AutoCAD二次开发自动生成系统图

    基于 AutoLisp 的 AutoCAD 二次开发自动生成系统图 [摘 要]本文主要阐述了应用 autolisp 语言二次开发 autocad 自动生成系统图的实现方案. [关键词] autocad ...

  8. Creo二次开发异步模式配置

    异步模式是Creo二次开发的另外一种形式,被广泛应用于一些外部调用中.其配置过程如下: (1)      创建MFC程序(对话框程序都可以了) (2)      配置工程常规选项 (3)      配 ...

  9. ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985

    ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985 转载于:https://www.cnblogs.com/esdtech/p/4199884.html

最新文章

  1. Elasticsearch使用优化之拙见
  2. Direct2D教程(三)简单几何图形
  3. 滴滴行程单用的什么字体_打车就送冰淇淋!滴滴出行放大招,限时19天
  4. Document Builder: 如何启用rule 分析的trace mode
  5. mysql bin oct_python 讲解进制转换 int、bin、oct、hex
  6. 10 行代码构建常见目标检测应用
  7. Linux平台音频测试程序
  8. 机器学习面试--决策树
  9. JAVA经典集合框架学习笔记——HashMap的底层实现原理
  10. 数值计算详细笔记(一):基础数学知识回顾
  11. 解决idea中http://java.sun.com/jsp/jstl/core“红色异常
  12. Java配置Path
  13. 01 牛刀小试【PAT B1012】数字分类
  14. 实践:服务器编写/系统架构/cache
  15. 建造者模式实现汽车组装工厂功能(Java代码实例)
  16. 心有猛虎,细嗅蔷薇。—第二十六天
  17. 联想笔记本G400使用VS2013时,笔记本快捷键与软件快捷键冲突解决方案
  18. JAVA对象布局之对象头(Object Header)
  19. HTML5 JavaScript CSS 表单实现购物优惠打折
  20. PHP商城缺点,多用户商城系统php语言开发的优劣?

热门文章

  1. MySQL 实现 Split 方法
  2. ES6结构赋值,一篇就够
  3. 次世代游戏建模师,一个极受追捧的高薪职业!
  4. htb-shocker
  5. 推广域名被微信拦截怎么办 被拦截的域名怎么做跳转
  6. Python爬取boss直聘关于python招聘数据,高薪总是让人那么羡慕
  7. #1001. 求梯形的面积
  8. 边缘计算 ai_什么是边缘AI计算?
  9. 文件传输协议(FTP)
  10. kali linux 入门(1) 基于win10和docker的环境搭建