- UID
- 765036
- 积分
- 478
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2016-11-25
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
/*
本程序的步骤及方法 备忘录:
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裁剪,生成局部放大图,成功!");
}
|
评分
-
查看全部评分
|