找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1750|回复: 4

[分享] 文字转轮廓线的arx方法

[复制链接]

已领礼包: 28个

财富等级: 恭喜发财

发表于 2018-11-12 21:56:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 1121443108qaz 于 2018-11-12 22:46 编辑

1,首先是一次WMFOUT,import
  1. void CEntityUtil::wmfoutIn(ads_name& ssname)
  2. {
  3.         acedCommandS(RTSTR, L"_.wmfout", RTSTR, L"D:\\temp.wmf", RTENAME, ssname, RTSTR, L"", RTNONE);
  4.         acedCommandS(RTSTR, L"_.import", RTSTR, L"D:\\temp.wmf", RTNONE);
  5.         acdbEntLast(ssname);
  6.         AcDbObjectId entId;
  7.         acdbGetObjectId(entId, ssname);
  8.         AcDbBlockReference* pBlk = NULL;
  9.         AcGePoint3d ptBase;
  10.         AcGeMatrix3d mat;
  11.         if (acdbOpenObject(pBlk,entId,AcDb::kForWrite)==Acad::eOk)
  12.         {
  13.                 ptBase = pBlk->position();
  14.                 mat.setToScaling(2.0, ptBase);
  15.                 pBlk->transformBy(mat);
  16.                 pBlk->close();
  17.         }
  18. }

0.2,然后是对每个文字缩放至一定范围,保证转化后轮廓线的精度
  1. AcGePoint3d CTextUtil::zoome(const AcDbText* pText)
  2. {
  3.         CString string;
  4.         ads_name ename;
  5.         AcGePoint3d ptCen,ptMin,ptMax;
  6.         string = pText->textString();
  7.         if (acutWcMatch(string,L".")==RTNORM)
  8.         {
  9.                 //acutPrintf(L"\n是特殊字符");
  10.                 acdbGetAdsName(ename, pText->objectId());
  11.                 AcGePoint2d ptcen2d= CDwgDatabaseUtil::zoomObject(ename);  //直接用zoom object方法
  12.                 ptCen = CConvertUtil::ToPoint3d(ptcen2d);
  13.                 return ptCen;
  14.         }
  15.         double height,width;
  16.         double xfa, yfa;
  17.         AcDbExtents ext;
  18.         pText->bounds(ext);
  19.         ptMin = ext.minPoint();
  20.         ptMax = ext.maxPoint();
  21.         height = ptMax.y - ptMin.y;
  22.         width = ptMax.x - ptMin.x;
  23.         ptCen = CGePointUtil::GetMiddllePoint(ptMin, ptMax);
  24.         AcDbViewTableRecord view;
  25.         if (height>width)
  26.         {
  27.                 yfa = 1;
  28.                 xfa = height / width;
  29.         }
  30.         else
  31.         {
  32.                 xfa = 1;
  33.                 yfa = width / height;
  34.         }
  35.         height = height * (yfa+0.2);
  36.         width = width * (xfa+0.2);
  37.         view.setCenterPoint(CConvertUtil::ToPoint2d(ptCen));
  38.         view.setWidth(width);
  39.         view.setHeight(height);
  40.         acedSetCurrentView(&view, NULL);
  41.         return ptCen;
  42. }

3,对于已经颠倒或反向的文字来说WMFOUT,导入一次后就行,否则需要镜像后WMFOUT,import,再镜像回来。然而如果对一个多行文字镜像再打破,此时这个文字事实上是镜像的,但是特性上显示不颠倒且不反向,所以需要判断。
  1. bool CTextUtil::isMirror(const AcDbText* pText)
  2. {
  3.         bool ismirror = true;
  4.         if (pText->isMirroredInX() || pText->isMirroredInY())
  5.         {
  6.                 return ismirror;
  7.         }
  8.         AcDbExtents ext;
  9.         pText->getGeomExtents(ext);
  10.         AcGePoint3d position, minPt, maxPt,leftUpPt,rightDownPt;
  11.         minPt = ext.minPoint();
  12.         maxPt = ext.maxPoint();
  13.         rightDownPt = AcGePoint3d(maxPt.x, minPt.y, 0);
  14.         leftUpPt = AcGePoint3d(minPt.x, maxPt.y, 0);
  15.         position = pText->position();
  16.         double dis1, dis2, dis3;
  17.         dis1 = position.distanceTo(minPt);
  18.         dis2 = position.distanceTo(leftUpPt);
  19.         dis3 = position.distanceTo(rightDownPt);
  20.         if (dis1<dis2 && dis1<dis3)
  21.         {
  22.                 ismirror = false;
  23.         }
  24.         return ismirror;
  25. }

4,最后是整体代码。
  1. void MyUtil::t2lb(AcDbObjectIdArray& entIds)
  2. {
  3.         AcDbObjectIdArray tempIds;
  4.         AcDbObjectId entId,tempId,layId,recordId;
  5.         AcGePoint2d pt,ptCen;
  6.         ads_name ename;
  7.         AcDbDatabase* pData = acdbHostApplicationServices()->workingDatabase();
  8.         pData->setMirrtext(true);
  9.         resbuf cmdstart, cmdend, wmf1, VTDURATION;;  
  10.         acedGetVar(L"wmfforegnd", &wmf1);
  11.         wmf1.resval.rint = 1;
  12.         acedSetVar(L"wmfforegnd", &wmf1);
  13.         wmf1.resval.rint = 0;
  14.         acedSetVar(L"wmfbkgnd", &wmf1);
  15.         acedGetVar(L"cmdecho", &cmdstart);
  16.         cmdend = cmdstart;
  17.         cmdend.resval.rint = 0;
  18.         acedSetVar(L"cmdecho", &cmdend);
  19.         acedGetVar(L"VTDURATION", &VTDURATION);
  20.         VTDURATION.resval.rint = 0;
  21.         acedSetVar(L"VTDURATION", &VTDURATION);
  22.         AcDbEntity* pEnt = NULL,*pTempEnt= NULL;
  23.         AcDbVoidPtrArray pts;
  24.         AcDbText* pText = NULL;
  25.         AcDbBlockReference* pBlock = NULL;
  26.         AcDbBlockTableRecord* pBlkRcd = NULL;
  27.         for (int i=0;i<entIds.length();i++)
  28.         {
  29.                 entId = entIds.at(i);
  30.                 acdbGetAdsName(ename, entId);
  31.                 if (acdbOpenAcDbEntity(pEnt,entId,AcDb::kForWrite)==Acad ::eOk)
  32.                 {
  33.                         if (pEnt->isKindOf(AcDbText::desc()))
  34.                         {
  35.                                 layId = pEnt->layerId();
  36.                                 pText = AcDbText::cast(pEnt);
  37.                                 if (CTextUtil::isMirror(pText))
  38.                                 {
  39.                                         pEnt->close();
  40.                                         ptCen = CConvertUtil::ToPoint2d(CTextUtil::zoome(pText));
  41.                                         //CDwgDatabaseUtil::zoomObject(ename);
  42.                                         pData->setClayer(layId);
  43.                                         CEntityUtil::wmfoutIn(ename);
  44.                                         CEntityUtil::erase(entId);
  45.                                         acdbGetObjectId(entId, ename);
  46.                                         if (acdbOpenObject(pBlock,entId,AcDb::kForWrite)==Acad ::eOk)
  47.                                         {
  48.                                                 recordId=pBlock->blockTableRecord();
  49.                                                 pBlock->explode(pts);
  50.                                                 for (int k=0;k<pts.length();k++)
  51.                                                 {
  52.                                                         AcDbPolyline* pPoly = new AcDbPolyline();
  53.                                                         pTempEnt = (AcDbEntity*)pts.at(k);
  54.                                                         tempId = CDwgDatabaseUtil::postToMOdelSpace(pTempEnt);
  55.                                                         tempIds.append(tempId);
  56.                                                         if (acdbOpenAcDbEntity(pTempEnt, tempId, AcDb::kForWrite) == Acad::eOk)
  57.                                                         {
  58.                                                                 pPoly->convertFrom(pTempEnt, true);     //转化为普通多段线
  59.                                                                 CPolylineUtil::normal(pPoly);
  60.                                                                 pPoly->close();
  61.                                                         }
  62.                                                 }
  63.                                                 pts.removeAll();
  64.                                                 pBlock->erase();
  65.                                                 pBlock->close();
  66.                                                 if (acdbOpenObject(pBlkRcd,recordId,AcDb::kForWrite)==Acad ::eOk)
  67.                                                 {
  68.                                                         pBlkRcd->erase();
  69.                                                         pBlkRcd->close();
  70.                                                 }
  71.                                         }
  72.                                 }
  73.                                 else
  74.                                 {
  75.                                         pEnt->close();
  76.                                         ptCen = CConvertUtil::ToPoint2d(CTextUtil::zoome(pText));
  77.                                         pData->setClayer(layId);                                        //设置为当前层
  78.                                         CEntityUtil::mirror(entId, CConvertUtil::ToPoint3d(ptCen), CConvertUtil::ToPoint3d(ptCen) + AcGeVector3d(0, 10, 0)); //以视图中心点镜像
  79.                                         acdbGetAdsName(ename, entId);
  80.                                         CEntityUtil::wmfoutIn(ename);                                        //wmfout wmfin一次
  81.                                         CEntityUtil::erase(entId);                                                        //删除文字                                                               
  82.                                         acdbGetObjectId(entId, ename);
  83.                                         CEntityUtil::mirror(entId, CConvertUtil::ToPoint3d(ptCen), CConvertUtil::ToPoint3d(ptCen) + AcGeVector3d(0, 10, 0));//镜像回去
  84.                                         if (acdbOpenObject(pBlock, entId, AcDb::kForWrite) == Acad::eOk)
  85.                                         {
  86.                                                 recordId = pBlock->blockTableRecord();
  87.                                                 pBlock->explode(pts);
  88.                                                 for (int k = 0; k < pts.length(); k++)
  89.                                                 {
  90.                                                         AcDbPolyline* pPoly = new AcDbPolyline();
  91.                                                         pTempEnt = (AcDbEntity*)pts.at(k);
  92.                                                         tempId = CDwgDatabaseUtil::postToMOdelSpace(pTempEnt);
  93.                                                         tempIds.append(tempId);
  94.                                                         if (acdbOpenAcDbEntity(pTempEnt, tempId, AcDb::kForWrite) == Acad::eOk)
  95.                                                         {
  96.                                                                 pPoly->convertFrom(pTempEnt, true);     //转化为普通多段线
  97.                                                                 CPolylineUtil::normal(pPoly);
  98.                                                                 pPoly->close();
  99.                                                         }
  100.                                                 }
  101.                                                 pBlock->erase();
  102.                                                 pBlock->close();
  103.                                                 pts.removeAll();
  104.                                                 if (acdbOpenObject(pBlkRcd, recordId, AcDb::kForWrite) == Acad::eOk)
  105.                                                 {
  106.                                                         pBlkRcd->erase();
  107.                                                         pBlkRcd->close();
  108.                                                 }
  109.                                         }
  110.                                 }
  111.                         }else if (pEnt->isKindOf(AcDbMText::desc()))
  112.                         {
  113.                                 //acutPrintf(L"\n是多行文字");
  114.                                 pEnt->explode(pts);
  115.                                 pEnt->erase();
  116.                                 pEnt->close();
  117.                                 for (int j = 0; j < pts.length(); j++)
  118.                                 {
  119.                                         pTempEnt =(AcDbEntity*)(pts.at(j));
  120.                                         tempId=CDwgDatabaseUtil::postToMOdelSpace(pTempEnt);
  121.                                         entIds.append(tempId);
  122.                                 }
  123.                                 pts.removeAll();
  124.                         }
  125.                         else
  126.                         {
  127.                                 pEnt->close();
  128.                         }
  129.                 }
  130.         }
  131.         acedSetVar(L"cmdecho", &cmdstart);
  132.         pData->setMirrtext(false);
  133. }


评分

参与人数 1D豆 +5 收起 理由
newer + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1667个

财富等级: 堆金积玉

发表于 2018-11-13 11:32:09 | 显示全部楼层
谢谢你分享的经验和代码.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 28个

财富等级: 恭喜发财

 楼主| 发表于 2018-11-22 09:04:35 | 显示全部楼层
本帖最后由 1121443108qaz 于 2018-11-22 09:06 编辑

太笨了,判断文字是否可以一次wmfout,import有更简便的方法。多行文字如果镜像后再打破,此时文字虽然显示为不颠倒不反向,但是其normal是(0,0,-1),依此可以简便地判断,更改如下。
  1. bool CTextUtil::isMirror(const AcDbText* pText)
  2. {
  3. bool ismirror;
  4. AcGeVector3d normal;
  5. normal = pText->normal();
  6. if (pText->isMirroredInX() || pText->isMirroredInY() || normal.z<0)
  7. {
  8.    ismirror=true;
  9. }
  10. else
  11. {
  12.   ismirror = false;
  13. }
  14. return ismirror;
  15. }

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 20个

财富等级: 恭喜发财

发表于 2020-2-25 11:00:11 | 显示全部楼层
真是太厉害了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 10个

财富等级: 恭喜发财

发表于 2020-9-29 18:03:17 | 显示全部楼层
thank you for code
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-26 17:02 , Processed in 0.379256 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表