TA的每日心情 | 开心 昨天 06:36 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
管理员
- 积分
- 1308
|
- /*
- 本程序的步骤及方法 备忘录:
- 1 多边形选择实体("CP")
- 2 建立匿名块,将以上选择集,克隆到匿名块中
- 3 在与块定义重合的位置,插入块引用
- 4 以多边形的点集,组成裁剪平面,给块引用加与裁剪相关的扩展词典,
- 实现与命令xclip相同的对块引用的裁剪
- 5 沿裁剪边界,绘制边界多义线,以便可以对边界修改为双点划线等
- 6 点取放大图移出点及放大倍数,将以上裁剪后的块引用及边界多义线,进行平移,放大变换。
- 这样,就完成了局部放大图的操作。
- 注:xclip仅对块引用及外部参考进行裁剪操作。本程序克服了这一限制,可以对任何实体集进行裁剪操作
- */
- //代替命令:xclip,生成局部放大图
- void all采用clip()
- {
- acutPrintf("\n----裁剪,生成局部放大图:");
- //1 设置xclip不画边界线
- acedCommand(RTSTR,"setvar",
- RTSTR,"xclipframe",
- RTSTR,"0",
- 0);
- //正交,让点取线为水平或垂直
- acedCommand(RTSTR,"setvar",
- RTSTR,"orthomode",
- RTSTR,"1",
- 0);
- //2 取边界点
- //pt0:块的定义点,及引用的插入点
- ads采用point pt0;
- ads采用point pt1,pt2;
- AcGePoint2dArray pts;
- acutPrintf("\n点选区域点:");
- if (acedGetPoint(NULL,采用T("\n第1点:"),pt1)!=RTNORM)
- {
- acutPrintf("\n用户取消!");
- //取消正交
- acedCommand(RTSTR,"setvar",
- RTSTR,"orthomode",
- RTSTR,"0",
- 0);
- //
- return;
- }
- ads采用point采用set(pt1,pt0);//pt0=pt1
- pts.append(asPnt2d(pt1));
- int es0;
- while ((es0=acedGetPoint(pt1,采用T("\n下一点<回车,结束取点>:"),pt2))==RTNORM)
- {
- //画临时线,作为标志
- acedGrDraw(pt1,pt2,1,1);
- pts.append(asPnt2d(pt2));
- ads采用point采用set(pt2,pt1);//pt1=pt2
- }
- if(es0==RTCAN)
- {
- acutPrintf("\n用户取消!");
- //取消正交
- acedCommand(RTSTR,"setvar",
- RTSTR,"orthomode",
- RTSTR,"0",
- 0);
- return;
- }
- //取消正交
- acedCommand(RTSTR,"setvar",
- RTSTR,"orthomode",
- RTSTR,"0",
- 0);
- //起点与终点重合时,仅记作起点
- if(pts[0].isEqualTo(pts[pts.logicalLength()-1])==Adesk::kTrue)
- {
- pts.removeLast();
- }
- //为斜线两点时,作为矩形选择框。但水平或垂直时除外
- if (pts.length() == 2)
- {
- if((fabs(pts[0].x-pts[1].x)<0.0001)||(fabs(pts[0].y-pts[1].y)<0.0001))
- {
- acutPrintf("\n边界不能仅为单个水平或垂直线!");
- return;
- }
- else
- {
- AcGePoint2d p1(pts[1].x, pts[0].y);
- AcGePoint2d p3(pts[0].x, pts[1].y);
- pts.insertAt(1, p1);
- pts.insertAt(3, p3);
- }
- }
- //多边形不能少于3点
- if(pts.length() < 3)
- {
- acutPrintf("\n边界点数太少!");
- return;
- }
- //最后线设置为平行或垂直
- if(fabs(pts[0][0]-pts[pts.logicalLength()-1][0])<fabs(pts[0][0]-pts[pts.logicalLength()-1][0]))
- {
- pts[pts.logicalLength()-1][0]=pts[0][0];
- }
- else
- {
- pts[pts.logicalLength()-1][1]=pts[0][1];
- }
- //闭合起点与终点,画临时直线
- acedGrDraw(asDblArray(pts[0]),asDblArray(pts[pts.logicalLength()-1]),1,1);
- //3 多边形交叉选择实体:CP
- //3.1 建立多边形点链表
- ads采用name ss={0L,0L};
- struct resbuf *pointList=NULL;
- struct resbuf *nextNode=NULL;
- for(int i=0;i<pts.logicalLength();i++)
- {
- //点表
- struct resbuf *newNode=acutNewRb(RTPOINT);
- ads采用point采用set(asDblArray(pts[i]),newNode->resval.rpoint);//(from,to)
- if(pointList==NULL)
- {
- pointList=newNode;
- nextNode=newNode;
- }
- else
- {
- nextNode->rbnext=newNode;
- nextNode=newNode;
- }
- }
- //3.2 多边形选择:"CP"
- if(acedSSGet("CP",pointList,NULL,NULL,ss)!=RTNORM)
- {
- acutRelRb(pointList);
- acutPrintf("\n错误退出!");
- return;
- }
- acutRelRb(pointList);
- //4 输入插入点,放大倍数
- AcGePoint3d insPt;
- if (acedGetPoint(pt1,采用T("\n输入放大图的插入点:"),asDblArray(insPt))!=RTNORM)
- {
- acutPrintf("\n用户取消!");
- acedSSFree(ss);
- return;
- }
- double scl=1;
- acedInitGet(RSG采用NOZERO+RSG采用NONEG,NULL);//非0,非负
- if ((es0=acedGetReal(采用T("\n输入放大倍数<1>:"),&scl))!=RTNORM)
- {
- if(es0==RTNONE)
- {
- scl=1.0;
- }
- else
- {
- acutPrintf("\n用户取消!");
- acedSSFree(ss);
- return;
- }
- }
- acedRedraw(NULL,0);
- //5 并生成匿名块定义,并将选择的实体,拷贝到匿名块定义中
- //5.1 生成匿名块定义
- AcDbBlockTable* pBT=NULL;
- acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForWrite);
- AcDbBlockTableRecord* pBTRec=new AcDbBlockTableRecord();
- AcDbObjectId myBTRecId;
- pBT->add(myBTRecId,pBTRec);
- pBT->close();
- pBTRec->setOrigin(asPnt3d(pt0));
- pBTRec->setName("*U");//匿名
- //5.2 将选择的实体,克隆到块定义中
- long nLen;
- acedSSLength(ss,&nLen);
- AcDbObjectIdArray m采用objId采用arr;
- for(i=0;i<nLen;i++)
- {
- ads采用name ent;
- acedSSName(ss,i,ent);
- AcDbObjectId objId;
- acdbGetObjectId(objId,ent);
- m采用objId采用arr.append(objId);
- }
- acedSSFree(ss);
- pBTRec->close();
- AcDbIdMapping idMap;
- if(acdbHostApplicationServices()->workingDatabase()->deepCloneObjects(m采用objId采用arr,myBTRecId,idMap)!=Acad::eOk)
- {
- acutPrintf("\n将选择的实体克隆到块定义中,失败!");
- return;
- }
- //6 在选择的实体相同处,插入块引用
- //6.1 设置插入点,旋转角度,比例等等
- AcDbBlockReference *pMyRef =new AcDbBlockReference() ;
- pMyRef->setBlockTableRecord (myBTRecId) ;
- pMyRef->setScaleFactors(AcGeScale3d(1,1,1));
- pMyRef->setPosition(asPnt3d(pt0)) ;
- pMyRef->setRotation (0.0) ;
- //6.2 将块引用,加入模型空间块表记录
- AcDbBlockTable *pBlockTable=NULL ;
- acdbHostApplicationServices()->workingDatabase()->getBlockTable (pBlockTable, AcDb::kForRead) ;
- AcDbBlockTableRecord *pBlockTableRecord ;
- pBlockTable->getAt (ACDB采用MODEL采用SPACE, pBlockTableRecord,AcDb::kForWrite) ;
- pBlockTable->close () ;
- AcDbObjectId myRefId;
- pBlockTableRecord->appendAcDbEntity(myRefId,pMyRef);
- pMyRef->close();
- //7 用以上的选择框,建立多义线,作为外框线,并进行与块引用相同的移动,放大变换
- AcDbPolyline* pPLine=new AcDbPolyline();
- for(i=0;i<pts.logicalLength();i++)
- {
- pPLine->addVertexAt(i,pts[i]);
- }
- pPLine->setClosed(Adesk::kTrue);
- AcGeMatrix3d matPLine;
- matPLine.setTranslation(insPt-asPnt3d(pt0));//平移
- pPLine->transformBy(matPLine);
- matPLine.setToScaling(scl,insPt);//放大
- pPLine->transformBy(matPLine);
- AcDbObjectId plineId;
- pBlockTableRecord->appendAcDbEntity(plineId,pPLine);
- pPLine->close();
- pBlockTableRecord->close();
- //8 对以上块引用,加裁剪处理(与xclip命令相同的功能)
- AcDbObjectPointer<AcDbBlockReference> pRef(myRefId,AcDb::kForRead);
- if (pRef.openStatus()!=Acad::eOk)
- {
- acutPrintf(采用T("Not an xref!\n"));
- return;
- }
- //从WCS转换为ECS
- AcGeMatrix3d mat(pMyRef->blockTransform());
- mat.invert();
- AcGePoint2dArray ecsPts;
- for(i=0;i<pts.logicalLength();i++)
- {
- AcGePoint3d pt(AcGePoint3d(pts[i].x,pts[i].y,0));
- //pt.transformBy(mat);
- ecsPts.append(AcGePoint2d(pt.x,pt.y));
- }
- //求其它参数
- AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
- AcGeVector3d normal;
- double elev;
- if (pDb->tilemode())//=1,模型空间
- {
- normal = pDb->ucsxdir().crossProduct(pDb->ucsydir());
- elev = pDb->elevation();
- }
- else //=0,图纸空间
- {
- normal = pDb->pucsxdir().crossProduct(pDb->pucsydir());
- elev = pDb->pelevation();
- }
- normal.normalize();
- //升级打开方式:写
- Acad::ErrorStatus es = pRef.object()->upgradeOpen();
- if (es !=Acad::eOk)
- {
- acutPrintf("\n写打开失败!");
- return;
- }
- //建立过滤对象
- AcDbSpatialFilter* pFilter = new AcDbSpatialFilter;
- //设置
- /*
- if (pFilter->setDefinition(ecsPts,normal,elev,
- ACDB采用INFINITE采用XCLIP采用DEPTH,-ACDB采用INFINITE采用XCLIP采用DEPTH,true)!=Acad::eOk)
- {
- delete pFilter;
- return;
- }
- */
- if (pFilter->setDefinition( ecsPts,AcGeVector3d(0,0,1),0.0,
- ACDB采用INFINITE采用XCLIP采用DEPTH,
- -ACDB采用INFINITE采用XCLIP采用DEPTH,true)!=Acad::eOk)
- {
- delete pFilter;
- acutPrintf("\n退出!");
- return;
- }
- // 加扩展管理
- //add it to the extension dictionary of the block reference
- //the AcDbIndexFilterManger class provides convenient utility functions
- if (AcDbIndexFilterManager::addFilter(pRef.object(),pFilter)!=Acad::eOk)
- {
- delete pFilter;
- acutPrintf("\n退出!");
- return;
- }
- else
- {
- acutPrintf(采用T("Filter has been succesfully added!\n"));
- pFilter->close();
- }
- //9 裁剪块引用,从原点平移,放大转换
- pRef->setScaleFactors(AcGeScale3d(scl,scl,scl));
- pRef->setPosition(insPt) ;
- acutPrintf("\n裁剪,生成局部放大图,成功!");
- }
复制代码 |
|