找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1149|回复: 2

[ARX程序]:完全模拟CAD中的直线命令,支持无限次的撤销,带闭合功能

[复制链接]
发表于 2006-7-19 13:42:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我发这个程序的主要目的是:

这个程序从技术上说没有任何难度,但从结构上看还有很多问题,虽然完全实现了CAD的直线功能,但结构很复杂,如果不带撤销功能,程序应该能精简许多.但如果就是带撤销功能,程序还能不能更加优化,程序虽然是写出来了,但至少目前我认为它还是垃圾.

平时我们有时就是这样,往往认为不屑一顾的东西,真正动起手来却不是那么回事.

请高手发表评论,如能从程序的结构或实现的手段上提供更好的方法,本人将不胜感激!
[php]
#include "geassign.h"
#include "dbsymtb.h"
#include "dbapserv.h"
#include "dbtrans.h"
#include "actrans.h"
#include "acdb.h"  
#include "rxregsvc.h"
#include "aced.h"
#include "adslib.h"
#include "dbents.h"

//命令执行函数
void windo()
{
  AcGePoint3d startPt, endPt;
  AcGePoint3d pt;
  AcGePoint3dArray ptArray;

  char kw[10];
  int rc;
  Acad::ErrorStatus es;

  Adesk::Boolean keepPicking  = Adesk::kTrue;   // 是否结束循环
  Adesk::Boolean keepcloseing = Adesk::kFalse;  // 是否闭合

  int i = 0;
  int y = 0;

  while(keepPicking)
  {
    if(i == 0)
    {
      rc = acedGetPoint(NULL, "\n指定第一点: ",  asDblArray(pt));
      if(rc != RTNORM)
      {
            keepPicking = Adesk::kFalse;
            break;
      }

          if(i == y)
          {
             ptArray.append(pt);
             i++;
             y++;
          }
          else
          {
             ptArray.setAt(i, pt);
             i++;
          }
          rc = RTNONE;
       }


       else if(i == 1)
       {
          pt = ptArray.at(i-1);

          acedInitGet(0, "Undo");
          rc = acedGetPoint(asDblArray(pt), "\n指定下一点或[撤销U]: ",  asDblArray(pt));

          switch (rc)
          {
            case RTCAN:
            case RTERROR:
            case RTNONE:
                   keepPicking = Adesk::kFalse;
                   break;

            case RTKWORD:
                   if(acedGetInput(kw) != RTNORM)
                   {
                     keepPicking = Adesk::kFalse;
                     break;
                   }

                   if(strcmp(kw, "Undo") == 0)
                   {
                     //actrTransactionManager->abortTransaction();
                     i--;
                     break;
                   }
                   break;

             case RTNORM:

                   if(i == y)
                   {
                     ptArray.append(pt);
                     i++;
                     y++;
                   }
                   else
                   {
                     ptArray.setAt(i, pt);
                     i++;
                   }      
             } //switch
          }    //if

       else if(i == 2)
       {
          pt = ptArray.at(i-1);

          acedInitGet(0, "Undo");
          rc = acedGetPoint(asDblArray(pt), "\n指定下一点或[撤销U]: ",  asDblArray(pt));

          switch (rc)
          {
            case RTCAN:
            case RTERROR:
            case RTNONE:
                   keepPicking = Adesk::kFalse;
                   break;

            case RTKWORD:
                   if(acedGetInput(kw) != RTNORM)
                   {
                     keepPicking = Adesk::kFalse;
                     break;
                   }

                   if(strcmp(kw, "Undo") == 0)
                   {
                     actrTransactionManager->abortTransaction();
                     i--;
                     break;
                   }
                   break;

             case RTNORM:

                   if(i == y)
                   {
                     ptArray.append(pt);
                     i++;
                     y++;
                   }
                   else
                   {
                     ptArray.setAt(i, pt);
                     i++;
                   }      
             } //switch
          }    //if
            

       else if(i > 2)
       {
          pt = ptArray.at(i-1);

          acedInitGet(0, "Close Undo");
          rc = acedGetPoint(asDblArray(pt), "\n指定下一点或[闭合C/撤销U]: ",  asDblArray(pt));

          switch (rc)
          {
            case RTCAN:
            case RTERROR:
            case RTNONE:
                   keepPicking = Adesk::kFalse;
                   break;

            case RTKWORD:
                   if(acedGetInput(kw) != RTNORM)
                   {
                     keepPicking = Adesk::kFalse;
                     break;
                   }

                   if(strcmp(kw, "Close") == 0)
                   {
                     keepcloseing = Adesk::kTrue;
                     keepPicking = Adesk::kFalse;
                     rc = RTNORM;
                     break;
                   }
                   else if(strcmp(kw, "Undo") == 0)
                   {
                     actrTransactionManager->abortTransaction();
                     i--;
                     break;
                   }

                   break;

             case RTNORM:

                   if(i == y)
                   {
                     ptArray.append(pt);
                     i++;
                     y++;
                   }
                   else
                   {
                     ptArray.setAt(i, pt);
                     i++;
                   }      
             } //switch
          }    //if



if(keepcloseing)
{
  AcTransaction *pTrans;
      pTrans = actrTransactionManager->startTransaction();
      if (pTrans == NULL)
      {
        keepPicking = Adesk::kFalse;
        break;
      }
  startPt = ptArray.at(i-1);
  endPt   = ptArray.at(0);

  AcDbLine *pLine = new AcDbLine(startPt, endPt);

  AcDbObjectId windId;
       
  es = appendToBlock(pLine, windId);
  if(es != Acad::eOk)
  {
    if(pLine)
    {
        delete pLine;
    }
    actrTransactionManager->abortTransaction();
    keepPicking = Adesk::kFalse;
    return;
  }

  es = actrTransactionManager->addNewlyCreatedDBRObject(pLine);
  if(es != Acad::eOk)
  {
    if(pLine)
    {
        delete pLine;
    }
    actrTransactionManager->abortTransaction();
    keepPicking = Adesk::kFalse;
    return;
  }
  pLine->close();
  pLine->draw();
}



else
if(rc == RTNORM)
{
  AcTransaction *pTrans;
      pTrans = actrTransactionManager->startTransaction();
      if (pTrans == NULL)
      {
        keepPicking = Adesk::kFalse;
        break;
      }

  startPt = ptArray.at(i-2);
  endPt   = ptArray.at(i-1);

  AcDbLine *pLine = new AcDbLine(startPt, endPt);

  AcDbObjectId windId;
       
  es = appendToBlock(pLine, windId);
  if(es != Acad::eOk)
  {
    if(pLine)
    {
        delete pLine;
    }
    actrTransactionManager->abortTransaction();
    keepPicking = Adesk::kFalse;
    return;
  }

  es = actrTransactionManager->addNewlyCreatedDBRObject(pLine);
  if(es != Acad::eOk)
  {
    if(pLine)
    {
        delete pLine;
    }
    actrTransactionManager->abortTransaction();
    keepPicking = Adesk::kFalse;
    return;
  }
  pLine->close();
  pLine->draw();
}

} //while

actrTransactionManager->endTransaction();
} //函数结束


//通用函数,把实体加入块表记录,但不关闭实体的指针
Acad::ErrorStatus appendToBlock(AcDbEntity *pEnt, AcDbObjectId& idEnt)
{
  Acad::ErrorStatus es;
  AcDbBlockTable *pBlockTable = NULL;
  AcDbBlockTableRecord *pBlockTableRecord = NULL;

  if((es = acdbHostApplicationServices()->workingDatabase()
           ->getBlockTable( pBlockTable, AcDb::kForRead )) != Acad::eOk)
                return es;

  if((es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite )) != Acad::eOk)
  {
                pBlockTable->close();
                return es;
  }
   
  es = pBlockTableRecord->appendAcDbEntity( idEnt, pEnt );
            
  pBlockTableRecord->close();
  pBlockTable->close();

  return es;
}
[/php]
下面是用VC++6.0编译好的程序,大家运行看看:
命令名WINDO
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2006-7-19 22:41:08 | 显示全部楼层
这样的程序要求并不苛刻,其结构也是很明确的,如果采用自定义类那这个设计起来思路就更简单清晰了。这样的程序从结构上讲根本算不上难的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-11-23 00:01:53 | 显示全部楼层
不能下载阿?搂主,怎么回事情?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-21 04:38 , Processed in 0.262733 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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