找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 167|回复: 0

[每日一码] 裁剪命令xclip只能用于块插入,外部块参考;换种方法,可以实现对所有实体集的裁剪

[复制链接]

1

主题

0

回帖

43

积分

管理员

积分
43
发表于 2024-3-14 20:11:44 | 显示全部楼层 |阅读模式
  1. /*
  2. 本程序的步骤及方法 备忘录:
  3.   1 多边形选择实体("CP")
  4.   2 建立匿名块,将以上选择集,克隆到匿名块中
  5.   3 在与块定义重合的位置,插入块引用
  6.   4 以多边形的点集,组成裁剪平面,给块引用加与裁剪相关的扩展词典,
  7.     实现与命令xclip相同的对块引用的裁剪
  8.   5 沿裁剪边界,绘制边界多义线,以便可以对边界修改为双点划线等
  9.   6 点取放大图移出点及放大倍数,将以上裁剪后的块引用及边界多义线,进行平移,放大变换。
  10.     这样,就完成了局部放大图的操作。
  11.   注:xclip仅对块引用及外部参考进行裁剪操作。本程序克服了这一限制,可以对任何实体集进行裁剪操作
  12. */
  13. //代替命令:xclip,生成局部放大图
  14. void all采用clip()
  15. {
  16.         acutPrintf("\n----裁剪,生成局部放大图:");
  17.         //1 设置xclip不画边界线
  18.         acedCommand(RTSTR,"setvar",
  19.                 RTSTR,"xclipframe",
  20.                 RTSTR,"0",
  21.                 0);
  22.         //正交,让点取线为水平或垂直
  23.         acedCommand(RTSTR,"setvar",
  24.                 RTSTR,"orthomode",
  25.                 RTSTR,"1",
  26.                 0);
  27.         //2 取边界点
  28.     //pt0:块的定义点,及引用的插入点
  29.     ads采用point pt0;
  30.         ads采用point pt1,pt2;
  31.     AcGePoint2dArray pts;
  32.         acutPrintf("\n点选区域点:");
  33.     if (acedGetPoint(NULL,采用T("\n第1点:"),pt1)!=RTNORM)
  34.         {
  35.                 acutPrintf("\n用户取消!");
  36.             //取消正交
  37.             acedCommand(RTSTR,"setvar",
  38.                 RTSTR,"orthomode",
  39.                 RTSTR,"0",
  40.                 0);
  41.         //
  42.         return;
  43.         }
  44.         ads采用point采用set(pt1,pt0);//pt0=pt1
  45.     pts.append(asPnt2d(pt1));
  46.         int es0;
  47.     while ((es0=acedGetPoint(pt1,采用T("\n下一点<回车,结束取点>:"),pt2))==RTNORM)
  48.     {
  49.                 //画临时线,作为标志
  50.         acedGrDraw(pt1,pt2,1,1);
  51.         pts.append(asPnt2d(pt2));
  52.         ads采用point采用set(pt2,pt1);//pt1=pt2
  53.     }
  54.         if(es0==RTCAN)
  55.         {
  56.                 acutPrintf("\n用户取消!");
  57.                 //取消正交
  58.                 acedCommand(RTSTR,"setvar",
  59.                         RTSTR,"orthomode",
  60.                         RTSTR,"0",
  61.                         0);
  62.                 return;
  63.         }
  64.         //取消正交
  65.         acedCommand(RTSTR,"setvar",
  66.                 RTSTR,"orthomode",
  67.                 RTSTR,"0",
  68.                 0);
  69.     //起点与终点重合时,仅记作起点
  70.         if(pts[0].isEqualTo(pts[pts.logicalLength()-1])==Adesk::kTrue)
  71.         {
  72.        pts.removeLast();
  73.         }
  74.     //为斜线两点时,作为矩形选择框。但水平或垂直时除外
  75.     if (pts.length() == 2)
  76.     {
  77.                 if((fabs(pts[0].x-pts[1].x)<0.0001)||(fabs(pts[0].y-pts[1].y)<0.0001))
  78.                 {
  79.                     acutPrintf("\n边界不能仅为单个水平或垂直线!");
  80.                         return;
  81.                 }
  82.                 else
  83.                 {
  84.                         AcGePoint2d p1(pts[1].x, pts[0].y);
  85.                         AcGePoint2d p3(pts[0].x, pts[1].y);
  86.                         pts.insertAt(1, p1);
  87.                         pts.insertAt(3, p3);
  88.                 }
  89.         }
  90.     //多边形不能少于3点
  91.         if(pts.length() < 3)
  92.         {
  93.                 acutPrintf("\n边界点数太少!");
  94.                 return;
  95.         }
  96.         //最后线设置为平行或垂直
  97.         if(fabs(pts[0][0]-pts[pts.logicalLength()-1][0])<fabs(pts[0][0]-pts[pts.logicalLength()-1][0]))
  98.         {
  99.        pts[pts.logicalLength()-1][0]=pts[0][0];
  100.         }
  101.     else
  102.         {
  103.        pts[pts.logicalLength()-1][1]=pts[0][1];
  104.         }
  105.         //闭合起点与终点,画临时直线
  106.     acedGrDraw(asDblArray(pts[0]),asDblArray(pts[pts.logicalLength()-1]),1,1);
  107.         //3 多边形交叉选择实体:CP
  108.         //3.1 建立多边形点链表
  109.         ads采用name ss={0L,0L};
  110.     struct resbuf *pointList=NULL;
  111.     struct resbuf *nextNode=NULL;
  112.     for(int i=0;i<pts.logicalLength();i++)
  113.         {
  114.                 //点表
  115.         struct resbuf *newNode=acutNewRb(RTPOINT);
  116.         ads采用point采用set(asDblArray(pts[i]),newNode->resval.rpoint);//(from,to)
  117.                 if(pointList==NULL)
  118.                 {
  119.            pointList=newNode;
  120.            nextNode=newNode;
  121.                 }
  122.                 else
  123.                 {
  124.            nextNode->rbnext=newNode;
  125.            nextNode=newNode;
  126.                 }  
  127.         }
  128.         //3.2 多边形选择:"CP"
  129.         if(acedSSGet("CP",pointList,NULL,NULL,ss)!=RTNORM)
  130.         {
  131.                 acutRelRb(pointList);
  132.                 acutPrintf("\n错误退出!");
  133.                 return;
  134.         }
  135.     acutRelRb(pointList);
  136.         //4 输入插入点,放大倍数
  137.         AcGePoint3d insPt;
  138.     if (acedGetPoint(pt1,采用T("\n输入放大图的插入点:"),asDblArray(insPt))!=RTNORM)
  139.         {
  140.                 acutPrintf("\n用户取消!");
  141.                 acedSSFree(ss);
  142.         return;
  143.         }
  144.         double scl=1;
  145.         acedInitGet(RSG采用NOZERO+RSG采用NONEG,NULL);//非0,非负
  146.     if ((es0=acedGetReal(采用T("\n输入放大倍数<1>:"),&scl))!=RTNORM)
  147.         {
  148.                 if(es0==RTNONE)
  149.                 {
  150.                         scl=1.0;
  151.                 }
  152.                 else
  153.                 {
  154.                    acutPrintf("\n用户取消!");
  155.                    acedSSFree(ss);
  156.            return;
  157.                 }
  158.         }
  159.     acedRedraw(NULL,0);
  160.         //5 并生成匿名块定义,并将选择的实体,拷贝到匿名块定义中
  161.         //5.1 生成匿名块定义
  162.         AcDbBlockTable* pBT=NULL;
  163.     acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForWrite);
  164.         AcDbBlockTableRecord* pBTRec=new AcDbBlockTableRecord();
  165.         AcDbObjectId myBTRecId;
  166.     pBT->add(myBTRecId,pBTRec);
  167.         pBT->close();
  168.         pBTRec->setOrigin(asPnt3d(pt0));
  169.     pBTRec->setName("*U");//匿名
  170.     //5.2 将选择的实体,克隆到块定义中
  171.     long nLen;
  172.         acedSSLength(ss,&nLen);
  173.         AcDbObjectIdArray m采用objId采用arr;
  174.         for(i=0;i<nLen;i++)
  175.         {
  176.                 ads采用name ent;
  177.                 acedSSName(ss,i,ent);
  178.                 AcDbObjectId objId;
  179.                 acdbGetObjectId(objId,ent);
  180.         m采用objId采用arr.append(objId);
  181.         }
  182.         acedSSFree(ss);
  183.     pBTRec->close();
  184.         AcDbIdMapping idMap;
  185.     if(acdbHostApplicationServices()->workingDatabase()->deepCloneObjects(m采用objId采用arr,myBTRecId,idMap)!=Acad::eOk)
  186.         {
  187.                 acutPrintf("\n将选择的实体克隆到块定义中,失败!");
  188.                 return;
  189.         }
  190.         //6 在选择的实体相同处,插入块引用
  191.         //6.1  设置插入点,旋转角度,比例等等  
  192.         AcDbBlockReference *pMyRef =new AcDbBlockReference() ;  
  193.         pMyRef->setBlockTableRecord (myBTRecId) ;  
  194.         pMyRef->setScaleFactors(AcGeScale3d(1,1,1));
  195.         pMyRef->setPosition(asPnt3d(pt0)) ;  
  196.         pMyRef->setRotation (0.0) ;  
  197.         //6.2 将块引用,加入模型空间块表记录  
  198.         AcDbBlockTable *pBlockTable=NULL ;  
  199.         acdbHostApplicationServices()->workingDatabase()->getBlockTable (pBlockTable, AcDb::kForRead) ;  
  200.         AcDbBlockTableRecord *pBlockTableRecord ;  
  201.         pBlockTable->getAt (ACDB采用MODEL采用SPACE, pBlockTableRecord,AcDb::kForWrite) ;  
  202.         pBlockTable->close () ;  
  203.         AcDbObjectId myRefId;
  204.         pBlockTableRecord->appendAcDbEntity(myRefId,pMyRef);
  205.     pMyRef->close();
  206.         //7 用以上的选择框,建立多义线,作为外框线,并进行与块引用相同的移动,放大变换
  207.         AcDbPolyline* pPLine=new AcDbPolyline();
  208.     for(i=0;i<pts.logicalLength();i++)
  209.         {
  210.        pPLine->addVertexAt(i,pts[i]);
  211.         }
  212.         pPLine->setClosed(Adesk::kTrue);
  213.     AcGeMatrix3d matPLine;
  214.         matPLine.setTranslation(insPt-asPnt3d(pt0));//平移
  215.     pPLine->transformBy(matPLine);
  216.     matPLine.setToScaling(scl,insPt);//放大
  217.     pPLine->transformBy(matPLine);
  218.         AcDbObjectId plineId;
  219.         pBlockTableRecord->appendAcDbEntity(plineId,pPLine);
  220.     pPLine->close();
  221.         pBlockTableRecord->close();
  222.         //8 对以上块引用,加裁剪处理(与xclip命令相同的功能)
  223.     AcDbObjectPointer<AcDbBlockReference> pRef(myRefId,AcDb::kForRead);
  224.     if (pRef.openStatus()!=Acad::eOk)
  225.     {
  226.         acutPrintf(采用T("Not an xref!\n"));
  227.         return;
  228.     }
  229.     //从WCS转换为ECS
  230.     AcGeMatrix3d mat(pMyRef->blockTransform());
  231.     mat.invert();
  232.     AcGePoint2dArray ecsPts;
  233.         for(i=0;i<pts.logicalLength();i++)
  234.         {
  235.                 AcGePoint3d pt(AcGePoint3d(pts[i].x,pts[i].y,0));
  236.         //pt.transformBy(mat);
  237.         ecsPts.append(AcGePoint2d(pt.x,pt.y));
  238.         }
  239.         //求其它参数
  240.     AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
  241.     AcGeVector3d normal;
  242.     double elev;
  243.     if (pDb->tilemode())//=1,模型空间
  244.     {
  245.         normal = pDb->ucsxdir().crossProduct(pDb->ucsydir());
  246.         elev = pDb->elevation();
  247.     }
  248.     else //=0,图纸空间
  249.     {
  250.         normal = pDb->pucsxdir().crossProduct(pDb->pucsydir());
  251.         elev = pDb->pelevation();
  252.     }
  253.     normal.normalize();
  254.         //升级打开方式:写
  255.     Acad::ErrorStatus es = pRef.object()->upgradeOpen();
  256.     if (es !=Acad::eOk)
  257.         {
  258.                 acutPrintf("\n写打开失败!");
  259.         return;
  260.         }
  261.     //建立过滤对象
  262.     AcDbSpatialFilter* pFilter = new AcDbSpatialFilter;
  263.         //设置
  264.         /*
  265.     if (pFilter->setDefinition(ecsPts,normal,elev,
  266.         ACDB采用INFINITE采用XCLIP采用DEPTH,-ACDB采用INFINITE采用XCLIP采用DEPTH,true)!=Acad::eOk)
  267.     {
  268.         delete pFilter;
  269.         return;
  270.     }
  271.         */
  272.     if (pFilter->setDefinition( ecsPts,AcGeVector3d(0,0,1),0.0,
  273.         ACDB采用INFINITE采用XCLIP采用DEPTH,
  274.         -ACDB采用INFINITE采用XCLIP采用DEPTH,true)!=Acad::eOk)
  275.    {
  276.         delete pFilter;
  277.                 acutPrintf("\n退出!");
  278.         return;
  279.     }
  280.     // 加扩展管理
  281.     //add it to the extension dictionary of the block reference
  282.     //the AcDbIndexFilterManger class provides convenient utility functions
  283.     if (AcDbIndexFilterManager::addFilter(pRef.object(),pFilter)!=Acad::eOk)
  284.         {
  285.         delete pFilter;
  286.                 acutPrintf("\n退出!");
  287.                 return;
  288.         }
  289.     else
  290.     {
  291.         acutPrintf(采用T("Filter has been succesfully added!\n"));
  292.         pFilter->close();
  293.     }
  294.         //9 裁剪块引用,从原点平移,放大转换
  295.     pRef->setScaleFactors(AcGeScale3d(scl,scl,scl));
  296.         pRef->setPosition(insPt) ;         
  297.     acutPrintf("\n裁剪,生成局部放大图,成功!");
  298. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2025-1-11 00:45 , Processed in 0.129531 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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