zoukankan      html  css  js  c++  java
  • 简单模拟多段线绘制Pline命令过程的撤销功能

    简单模拟多段线绘制Pline命令过程的撤销功能

    这是关于多段线pline命令中的撤销功能的简单代码

    代码使用了事务管理器来执行增加对象和撤销处理.

    代码

    		/// <summary>
    		/// 简单模拟多段线绘制过程的撤销功能.
    		/// code by edata 2020-3-11 
    		/// </summary>
    		/// <remarks>简单模拟多段线绘制过程的_u撤销功能.仅考虑了UCS问题</remarks>
    		//设置坐标系转换缓冲区链表
    		resbuf ucs,wcs;
    		ucs.restype=RTSHORT;
    		ucs.resval.rint=1;
    		wcs.restype=RTSHORT;
    		wcs.resval.rint=0;
    
    		ads_point pt;
    		ads_point ptWcs;
    		if (RTNORM != acedGetPoint(NULL,_T("
     选择起点: "),pt))
    		{
    			return;
    		}
    		acedTrans(pt,&ucs,&wcs,0,ptWcs);
    		AcGePoint3d p1=asPnt3d(ptWcs);
    		AcGePoint3d ptStart=p1;
    		AcDbPolyline *pPoly=NULL;
    		//开启事务管理器
    		AcTransaction *pTrans =actrTransactionManager->startTransaction();
    		while (true)
    		{
    			CString strPrompt=_T("
     选择下一个点[(U)撤销]: ");
    			CString strKword=_T("Undo _ u");
    			if (pPoly!=NULL)
    			{
    				int nCount =pPoly->numVerts();
    				if (nCount>1)
    				{
    					strPrompt=_T("
     选择下一个点[(U)撤销/(C)闭合]: ");
    					strKword=_T("Undo Close _ u c");	
    										
    				}
    			}
    			
    			//设置使用Undo关键字,该值允许使用ctrl+z撤销
    			acedInitGet(NULL,strKword);
    			int nRet=acedGetPoint(pt,strPrompt,pt);
    			if (RTKWORD == nRet)
    			{
    				ACHAR szKword[132];
    				if (RTNORM != acedGetInput(szKword))
    				{
    					continue;
    				}
    				if (_tcscmp(szKword,_T("u")) == 0)
    				{
    					if (pPoly != NULL)
    					{
    						int nCount = pPoly->numVerts();
    						if (nCount>0)
    						{
    							//此处使用removeVertexAt不能移除仅剩的一个点,后面对1个点的线取消事务
    							Acad::ErrorStatus es= pPoly->removeVertexAt(nCount-1);	
    							//重新生成
    							pPoly->draw();
    							if (nCount>1)
    							{
    								pPoly->getEndPoint(p1);
    								pt[X] = p1.x;
    								pt[Y] = p1.y;
    								pt[Z] = p1.z;
    								acedTrans(pt,&wcs,&ucs,0,pt);
    							}
    							else
    							{							
    								p1=ptStart;
    								pt[X] = p1.x;
    								pt[Y] = p1.y;
    								pt[Z] = p1.z;
    								acedTrans(pt,&wcs,&ucs,0,pt);
    							}
    						}					
    					}
    				}
    				else if (_tcscmp(szKword,_T("c")) == 0)
    				{
    					if (pPoly!=NULL)
    					{
    						int nCount =pPoly->numVerts();
    						if (nCount>1)
    						{
    							pPoly->setClosed(true);
    							break;
    						}
    					}
    				}				
    				continue;
    			}
    			else if (RTNORM != nRet)
    			{
    				break;
    			}
    
    			acedTrans(pt,&ucs,&wcs,0,ptWcs);
    			AcGePoint3d p2=asPnt3d(ptWcs);			
    			//处理多段线图形
    			if (pPoly == NULL)
    			{
    				pPoly = new AcDbPolyline();
    				pPoly->addVertexAt(0,AcGePoint2d(p1.x,p1.y));
    				pPoly->addVertexAt(1,AcGePoint2d(p2.x,p2.y));
    				//添加到当前数据库当前空间
    				AddEntToCurSpace(pPoly);
    				//添加对象到事务处理
    				actrTransactionManager->addNewlyCreatedDBRObject(pPoly);
    				//显示图形
    				pPoly->draw();
    			}
    			else
    			{
    				int nCount = pPoly->numVerts();
    				pPoly->addVertexAt(nCount,AcGePoint2d(p2.x,p2.y));
    				//显示图形
    				pPoly->draw();
    			}		
    			p1=p2;
    		}
    
    		if (pPoly == NULL)
    		{
    			//未创建多段线,终止事务
    			actrTransactionManager->abortTransaction();
    			return;
    		}
    		else
    		{
    			int nCount = pPoly->numVerts();
    			if (nCount == 1)
    			{
    				//仅有一个点,终止事务
    				actrTransactionManager->abortTransaction();
    				return;
    			}
    		}
    		//事务结束
    		actrTransactionManager->endTransaction();
    

    AddEntToCurSpace 添加实体对象到当前数据库当前空间

    代码

    	static Acad::ErrorStatus AddEntToCurSpace(AcDbEntity *pEnt)
    	{
    		AcDbObjectId objId=AcDbObjectId::kNull;
    		return AddEntToCurSpace(pEnt,objId);
    	}
    	static Acad::ErrorStatus AddEntToCurSpace(AcDbEntity *pEnt,AcDbObjectId &objId)
    	{
    		if (pEnt == NULL)
    		{
    			return Acad::eNullEntityPointer;
    		}
    		AcDbBlockTableRecordPointer pBlkRcd(acdbHostApplicationServices()->workingDatabase()->currentSpaceId(),AcDb::kForWrite);
    		if (Acad::eOk != pBlkRcd.openStatus())
    		{
    			return pBlkRcd.openStatus(); 
    		}
    		return pBlkRcd->appendAcDbEntity(objId,pEnt);
    	}
    

    结束语:使用事务管理器的时候,事务中的对象不能使用close()关闭对象了;

  • 相关阅读:
    数组定义和使用
    跳转语句—break,continue,goto
    案例 天线抬不起头来
    int是几位;short是几位;long是几位 负数怎么表示
    Python3的类注意事项
    用usb线配置直流电机驱动器不能配置成功
    案例 电源灯亮,但是就是不闪灯,而且也下载不了程序
    关于ai算法的一个点子
    进程 并发 线程 032
    ftp功能深度剖析 + 线程 031
  • 原文地址:https://www.cnblogs.com/edata/p/12463675.html
Copyright © 2011-2022 走看看