在工程图中插入二维码可以方便机器扫描读取,易于将图纸与MES、ERP等系统结合。添加二维码一般可以考虑以下方式:
在工程图中插入图片等OLE内容。可以在Creo中导入外部程序生成的诸如jpg、png等图片格式的二维码文件。经测试,插入OLE内容暂时不仅未提供Toolkit接口,并且录制宏发现插入图片的操作也无法通过宏的方式实现,所以该方法只能由设计人员手动添加,无法进行二次开发。
在工程图中插入dxf。可以在Creo中导入外部程序生成的dxf格式的二维码文件。经测试,导入的dxf文件会转换为草绘对象,而且Toolkit提供了Pro2dImportAppend函数用于导入dxf文件,所以该方法不仅可以手动操作,也适合于二次开发。但该方法导入dxf后添加了一系列草绘图元,当需要修改时难以确定那些草绘时导入的dxf文件转换得到导致难以对二维码相关的草绘删除修改,故该方法仅适用于一次性导入二维码的操作。
生成包含二维码信息的符号。可以在绘图中添加一个符号,在符号中绘制对应的二维码图案,之后插入该符号。该方法手工操作较复杂,主要需要手动绘制对应的二维码符号,但易于插入修改及替换,而Toolkit也提供了绘制符号的方式。
本文主要采用第三种方法在绘图中添加二维码。
1.添加二维码的基本流程 如上分析,通过添加符号的方式为工程图添加二维码主要包含以下几个步骤:
遍历工程图所有符号实例,删除之前添加的二维码符号实例;
遍历工程图所有符号定义,删除之前添加的二维码符号定义;
对输入进行转码,生成二维码信息;
创建新的符号定义,根据二维码信息对该符号定义进行修改,生成包含二维码信息的符号定义;
根据实际,生成符号定义的实例并将其摆放到正确的位置。
2. 遍历并删除符号定义 Toolkit提供了ProDrawingDtlsymdefsCollect函数收集绘图所包含的所有符号对象定义。获取所有符号定义后对即可其遍历,使用ProDtlsymdefdataNameGet函数获取符号的名称,通过名称进行比对,如果名称与我们定义的二维码符号名称一致则调用ProDtlsymdefDelete删除符号定义。遍历并删除符号定义示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 CString DtlsymdefName (ProDtlsymdef *p_sym_def) { ProDtlsymdefdata data; ProError status; ProName name; if (p_sym_def == NULL || p_sym_def->type != PRO_SYMBOL_DEFINITION) return "" ; status = ProDtlsymdefDataGet (p_sym_def, &data); status = ProDtlsymdefdataNameGet (data, name); return CString (name); } void DeletePreQrCodeDef () { ProError status; ProDrawing drawing; ProDtlsymdef *p_symdefs; int size; CString SymName; if (CurrentMdlType () != PRO_DRAWING) return ; status = ProMdlCurrentGet ((ProMdl *)&drawing); status = ProDrawingDtlsymdefsCollect (drawing, &p_symdefs); status = ProArraySizeGet ((ProArray)p_symdefs, &size); for (int i = 0 ; i < size; i++) { if (DtlsymdefName (&p_symdefs[i]) == QRCODESYMNAME) { status = ProDtlsymdefDelete (&p_symdefs[i]); } } status = ProArrayFree ((ProArray *)&p_symdefs); }
经测试,如果直接删除符号定义,则符号定义生成的对象实例也同时一并删除,故无需进行删除符号实例的操作。
3.字符串转二维码[1] 生成QRCODE的数据我们直接使用了Github.com上MFCQRcode项目提供的LibQRCode库 。使用该库只需添加LibQRCode.lib以及对应头文件qrencode.h的引用,为常规的库文件引用操作,在此不在赘述。根据工程介绍,生成二维码并访问其信息的示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if (pQRC = QRcode_encodeString (message, 0 , QR_ECLEVEL_L, QR_MODE_8, 1 )) { pSourceData = pQRC->data; unWidth = pQRC->width; for (y = 0 ; y < unWidth; y++) { for (x = 0 ; x < unWidth; x++) { if (*pSourceData & 1 ) { } pSourceData++; } } QRcode_free (pQRC); }
4.创建二维码符号定义 4.1 创建符号定义 创建一个新的符号定义可以用ProDtlsymdefdataAlloc、ProDtlsymdefCreate等实现,使用ProDtlsymdefdataAttachAdd等函数可以设置其插入方式为自由摆放,ProDtlsymdefdataPathSet设置其名称等。操作相对简单,直接给出创建符号定义对应的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void QRcodeSymdefCreate (ProDrawing drawing, CString name, CString message, ProVector position) { ProError status; ProDtlsyminstdata sdata; ProDtlattach attach; ProDtlsyminst syminst; status = ProDtlsymdefdataAlloc (drawing, &sdata); symdefname = name.AllocSysString (); status = ProDtlsymdefdataPathSet (sdata, symdefname); SysFreeString (symdefname); status = ProDtlsymdefdataHeighttypeSet (sdata, PRODTLSYMDEFHGHTTYPE_FIXED); status = ProDtlsymdefattachAlloc (PROSYMDEFATTACHTYPE_FREE, 0 , 0.0 , origin, &attach); status = ProDtlsymdefdataAttachAdd (sdata, attach); status = ProDtlsymdefattachFree (attach); status = ProDtlsymdefCreate (drawing, sdata, &symdef); status = ProDtlsymdefdataFree (sdata); }
4.2 符号定义中绘制二维码 为便于描述,我们设定在符号中画一个1mm长,线宽1mm的线段作为二维码中的点。在符号中创建草绘与在绘图中创建草绘过程基本一致,只是在调用ProDtlentityCreate函数的参数中的第二个参数需指定为二维码的符号定义对象。创建草绘以及设定其属性在之前CREO Toolkit二次开发-草绘中心线 一文中已经进行了描述,在此不在赘述,直接给出源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 void PrintQRCodeDot (ProDtlsymdef *symdef, ProVector start, ProColortype color) { ProError status; ProDtlentity entity; ProDtlentitydata edata; ProCurvedata *curve; ProColor entity_color; ProVector end; end[0 ] = start[0 ]; end[1 ] = start[1 ] + 1 ; end[2 ] = start[2 ]; status = ProDtlentitydataAlloc (symdef->owner, &edata); status = ProCurvedataAlloc (&curve); status = ProLinedataInit (start, end, curve); status = ProDtlentitydataCurveSet (edata, curve); entity_color.method = PRO_COLOR_METHOD_TYPE; entity_color.value.type = color; status = ProDtlentitydataColorSet (edata, &entity_color); status = ProDtlentitydataWidthSet (edata, 1.0 ); status = ProDtlentityCreate (symdef->owner, symdef, edata, &entity); status = ProDtlentitydataFree (edata); }
在第三节字符串转二维码中我们已获得了二维码信息矩阵,故只需根据该矩阵的信息在对应的位置调用PrintQRCodeDot绘制实心方块即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 void QRcodeSymdefCreate (ProDrawing drawing, CString name, CString message, ProVector position) { ProError status; ProDtlsymdefdata sdata; ProVector origin = {0 , 0 , 0 }, start; ProDtlsymdefattach attach; ProDtlsymdef symdef; wchar_t *symdefname; int unWidth, x, y; unsigned char *pSourceData; QRcode *pQRC; status = ProDtlsymdefdataAlloc (drawing, &sdata); symdefname = name.AllocSysString (); status = ProDtlsymdefdataPathSet (sdata, symdefname); SysFreeString (symdefname); status = ProDtlsymdefdataHeighttypeSet (sdata, PRODTLSYMDEFHGHTTYPE_FIXED); status = ProDtlsymdefattachAlloc (PROSYMDEFATTACHTYPE_FREE, 0 , 0.0 , origin, &attach); status = ProDtlsymdefdataAttachAdd (sdata, attach); status = ProDtlsymdefattachFree (attach); status = ProDtlsymdefCreate (drawing, sdata, &symdef); status = ProDtlsymdefdataFree (sdata); if (pQRC = QRcode_encodeString (message, 0 , QR_ECLEVEL_L, QR_MODE_8, 1 )) { start[0 ] = 0.5 ; start[1 ] = -0.5 ; start[2 ] = 0.0 ; pSourceData = pQRC->data; unWidth = pQRC->width; start[1 ] += unWidth; for (y = 0 ; y < unWidth; y++) { for (x = 0 ; x < unWidth; x++) { if (*pSourceData & 1 ) { PrintQRCodeDot (&symdef, start, PRO_COLOR_LETTER); } start[0 ]++; pSourceData++; } start[0 ] = 0.5 ; start[1 ]--; } QRcode_free (pQRC); } }
5.插入符号实例 插入符号也无非是设定相关参数并显示的操作,各函数调用也是基本的toolkit函数调用,注意内存的释放即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void SymInstCreateFree (ProDrawing drawing, ProDtlsymdef *definition, ProVector position) { ProError status; ProDtlsyminstdata sdata; ProDtlattach attach; ProDtlsyminst syminst; status = ProDtlsyminstdataAlloc (drawing, &sdata); status = ProDtlsyminstdataDefSet (sdata, definition); status = ProDtlsyminstdataAttachtypeSet (sdata, PROSYMDEFATTACHTYPE_FREE); status = ProDtlattachAlloc (PRO_DTLATTACHTYPE_FREE, NULL , position, NULL , &attach); status = ProDtlsyminstdataAttachmentSet (sdata, attach); status = ProDtlattachFree (attach); status = ProDtlsyminstCreate (drawing, sdata, &syminst); status = ProDtlsyminstdataFree (sdata); status = ProDtlsyminstShow (&syminst); }
插入二维码的实际演示效果如下图所示,读者也可以根据实际情况修改对应的文字、颜色及摆放位置:
图 插入二维码示例
完整代码可在Github.com 下载。代码在VS2010,Creo 2.0 M060 X64下编译通过。
参考网址 [1] elicec/MFCQRcode. 2020-09-17[引用日期2020-09-17],https://github.com/elicec/MFCQRcode .