找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1510|回复: 11

[ARX函数]:请大家测试AcDbPolyline的getOffsetCurves函数

[复制链接]
发表于 2004-4-1 22:19:55 | 显示全部楼层 |阅读模式

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

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

×
由于原来的那个帖子我不能继续回复,只好再贴一个
这是一个完整的测试函数,大家自己定义一个命令就可以了;
注意:
画的多一线(多边形)尺寸近两大一点,因为最大便宜距离达到了40。
定点的横坐标都大于10000;可以先画一个,然后移动到(10000,0)
得到的结果:一条在原位置,三条在原点附近
预期的结果是:四条线得位置应该在原位置

[program]
void testPlOffset()
{
        AcDbEntity* ent=NULL;
        ads_name en;
        ads_point pt;
        int rc = acedEntSel("\nPlease select Pline:", en, pt);
        if (rc != RTNORM) {
                acutPrintf("\nNothing selected.");
                return ;
        }
        AcDbObjectId eId=NULL;

        acdbGetObjectId(eId, en);
        acdbOpenObject(ent, eId, kForWrite);
        //acdbOpenObject(ent, eId, kForRead);
//上面打开状态只能为kForWrite,如果是kForRead,则在运行时出错
//根据getOffsetCurves的声明,打开状态设为kForRead应该是可以的
        if(ent==NULL)
                return;
        AcDbPolyline* pl=NULL;
        pl=AcDbPolyline::cast(ent);
        if(pl==NULL)
        {
                ent->close();
                acutPrintf("\npl NUll");
                return;
        }
        AcDbExtents ext;
        pl->getGeomExtents(ext);
//把这个判断注释掉,可以测试一般位置的多一线,横坐标小雨9600的运行结果正常与预期结果相同(这个横坐标边界我没法确定)
        if(ext.minPoint().x<10000)
        {
                acutPrintf("\nPosion error!");
                pl->close();
                return;
        }
        AcDbVoidPtrArray vs02,vd04,vd03;
        AcDbPolyline* pls02=NULL;
        AcDbPolyline* pld04=NULL;
        AcDbPolyline* pld03=NULL;
        AcDbEntity* ent1=NULL;
        pl->getOffsetCurves(30,vd04);
        pl->getOffsetCurves(20,vd03);
        pl->getOffsetCurves(10,vs02);
        AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
        AcDbBlockTable *pBlockTable;
        pDb->getBlockTable(pBlockTable, AcDb::kForRead);

        AcDbBlockTableRecord *pBlockRec;
        pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockRec, AcDb::kForWrite);
        AcDbObjectId objId;
        if(vd04.length()!=0)
        {
                pld04=AcDbPolyline::cast((AcDbEntity*)vd04.first());
                if(pld04!=NULL)
                {
                        pBlockRec->appendAcDbEntity(objId, pld04);
                        pld04->close();
                }
                for(int i=1;i<vd04.length();i++)
                {
                        ent1=(AcDbEntity*)vd04.at(i);
                        delete ent1;
                }
        }
        if(vd03.length()!=0)
        {
                pld03=AcDbPolyline::cast((AcDbEntity*)vd03.first());
                if(pld03!=NULL)
                {
                        pBlockRec->appendAcDbEntity(objId, pld03);
                        pld03->close();
                }
                for(int i=1;i<vd03.length();i++)
                {
                        ent1=(AcDbEntity*)vd03.at(i);
                        delete ent1;
                }
        }
        if(vs02.length()!=0)
        {
                pls02=AcDbPolyline::cast((AcDbEntity*)vs02.first());
                if(pls02!=NULL)
                {
                        pBlockRec->appendAcDbEntity(objId, pls02);
                        pls02->close();
                }
                for(int i=1;i<vs02.length();i++)
                {
                        ent=(AcDbEntity*)vs02.at(i);
                        delete ent;
                }
        }
        pl->close();

        pBlockRec->close();
        pBlockTable->close();
}
[/program]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-4-1 23:28:47 | 显示全部楼层
pld04=AcDbPolyline::cast((AcDbEntity*)vd03.first());
->
pld04=AcDbPolyline::cast((AcDbEntity*)vd04.first());
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-1 23:38:24 | 显示全部楼层
害我测了半天,是你自己马虎写错了,程序没问题,得到了预期结果
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-4-2 08:58:20 | 显示全部楼层
不好意思,耽误了大家的时间。昨天晚上那个地方打错了,刚才又把代码编辑了一下,请大家在试一次阿;
下面是我测试使用的两条多以线,得到的结果不一样,较大尺寸的得到了预期结果,小尺寸的多以线得到了出错的结果
现在好像与位置和尺寸都有关系了

  1.                   LWPOLYLINE  Layer: "0"
  2.                             Space: Model space
  3.                    Handle = A3
  4.             Closed
  5.     Constant width    0.0000
  6.               area   1531301.7603
  7.          perimeter   4969.7798

  8.           at point  X=13882.2437  Y=2723.9903  Z=   0.0000
  9.           at point  X=13009.6254  Y=1602.9983  Z=   0.0000
  10.           at point  X=14072.8855  Y=1009.3244  Z=   0.0000
  11.           at point  X=14757.9735  Y=1942.7478  Z=   0.0000

  12. Command: list

  13. Select objects: 1 found

  14. Select objects:
  15.                   LWPOLYLINE  Layer: "0"
  16.                             Space: Model space
  17.                    Handle = A6
  18.             Closed
  19.     Constant width    0.0000
  20.               area   32933809.0738
  21.          perimeter   23042.1472

  22.           at point  X=10084.2223  Y=  18.6890  Z=   0.0000
  23.           at point  X=13301.1357  Y=4614.2007  Z=   0.0000
  24.           at point  X=18510.6365  Y=1507.0690  Z=   0.0000
  25.           at point  X=14549.3705  Y=-2982.1231  Z=   0.0000
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-2 17:30:03 | 显示全部楼层
Autocad有个很大的bug的,对于大座标,比如444444.444,再做一些图面计算,比如偏移、填充等操作时,就会出错。这是因为计算时数据溢出的原因,autocad没有做好。

比方说,你可以将图形转到大座标下,然后绘制一个稍微复杂一些的封闭图形,然后调用autocad的填充命令,这时就会出现莫名其妙的结果。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-4 04:15:59 | 显示全部楼层
[program]
double pickpt[3];
long entname[2];
if(acedEntSel("\nPlease Select a PolyLine:",entname,pickpt)!=RTNORM) return;

AcDbObjectId EntID;
acdbGetObjectId(EntID,entname);

AcDbPolyline *pLine=NULL;
if(acdbOpenObject(pLine,EntID,AcDb::kForRead)!=Acad::eOk) return;

AcDbVoidPtrArray avp;
pLine->getOffsetCurves(10,avp);
pLine->close();

if(avp.isEmpty()==TRUE) return;

int i;
unsigned j;
AcGePoint3d agpt;
for(i=0;i<avp.length();i++){
   pLine=(AcDbPolyline *)avp.at(i);
   for(j=0;j<pLine->numVerts();j++){
      pLine->getPointAt(j,agpt);
      acutPrintf("\n[%2d,%2d](%.3f,%.3f)",i+1,j+1,agpt.x,agpt.y);
   }
}
[/program]
并不是每条多义线都会产生偏移,不同的形状,偏移的大小会产生不同的结果,可能会产生多条多义线。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-4-4 14:40:39 | 显示全部楼层
其实我是想说,数据溢出在程序中可以说是很正常的,偶尔没有处理的话应该得到的是不可思议的结果(至少图形会变形吧),系统一般会提示内存溢出的,然后程序挂掉。但这里的结果不象是5楼说的那样,图形的形状没有改变,只是位置变了,而且AutoCAD也号称图纸空间无限大的,也就是没有图面尺寸限制的,所以autoCAD应该会考虑处理大型数据的。所以我觉得出现这种情况应该不是数据溢出引起的。
另外,六楼说的“并不是每条多义线都会产生偏移,不同的形状,偏移的大小会产生不同的结果,可能会产生多条多义线。”这个文档里说得很清楚,想必每个使用的人都知道的,但是“源多义线”在操作前后应该不会改变的吧,但是偏偏是“源多义线”的位置变化了。你可以在“源多义线”上进行标注,进行偏移操作后,标注跟着一块移动了,而且大家注意一下我再open操作那里的注释。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-7 15:40:08 | 显示全部楼层
其实也有尺寸限制,1E308,在程序里,ARX用double来定义坐标,就存在了范围,在命令行,可能没人会输这么长(最长512个字符),也没有意义。不过我到建议楼主把代码重新写过,换个解法,或许会得出正确地结果。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-4-8 13:54:37 | 显示全部楼层
在命令行,可能没人会输这么长(最长512个字符),,赫赫这个当然是了,如果你输入过长,还会让autocad死掉呢,不信你试一下。
数字太大会溢出谁都知道,可是,图形坐标再10000(1e4)就出错不应该吧,应该不会是数字太大了吧。我想讨论的不是编程时double的范围问题,请大家不要往那上面扯吧,至少我觉得出错的原因肯定不是double范围的问题.
不知道晓东如何看待这个问题
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-8 17:06:20 | 显示全部楼层
对,就是建议楼主把代码重新写过,换个解法!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-8 18:02:50 | 显示全部楼层
我也建议楼主把代码重新写过,因为楼主的代码确实存在问题,
比如getOffsetCurves要检查结果,然后才能作下一步,如果getOffsetCurves返回错误的话,
vd04.length()也可能>0,另外,pld04=AcDbPolyline::cast((AcDbEntity*)vd04.first()); 如果
vd04.first()不为NULL,但pld04可能为NULL,这样会存在vd04.first()内存没有释放。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-4-11 10:30:45 | 显示全部楼层
象AcDbVoidPtrArray 这种参数使用方法,属于C风格,使用需要非常小心,很容易内存泄漏,与C++倡导的强类型检测是矛盾的,容易让人出错的设计不是好的设计。
好的办法是从AcDbVoidPtrArray 中继承对象,小心产生slice问题,让构析函数自动清理内存。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 15:46 , Processed in 0.211244 second(s), 52 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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