[每日一码] 裁剪命令xclip只能用于块插入,外部块参考;换种方法,可以实现对所有实体集的裁剪
/*本程序的步骤及方法 备忘录:
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.isEqualTo(pts)==Adesk::kTrue)
{
pts.removeLast();
}
//为斜线两点时,作为矩形选择框。但水平或垂直时除外
if (pts.length() == 2)
{
if((fabs(pts.x-pts.x)<0.0001)||(fabs(pts.y-pts.y)<0.0001))
{
acutPrintf("\n边界不能仅为单个水平或垂直线!");
return;
}
else
{
AcGePoint2d p1(pts.x, pts.y);
AcGePoint2d p3(pts.x, pts.y);
pts.insertAt(1, p1);
pts.insertAt(3, p3);
}
}
//多边形不能少于3点
if(pts.length() < 3)
{
acutPrintf("\n边界点数太少!");
return;
}
//最后线设置为平行或垂直
if(fabs(pts-pts)<fabs(pts-pts))
{
pts=pts;
}
else
{
pts=pts;
}
//闭合起点与终点,画临时直线
acedGrDraw(asDblArray(pts),asDblArray(pts),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),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);
}
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.x,pts.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裁剪,生成局部放大图,成功!");
}
页:
[1]