setPlotWindowArea函数使用问题的分析与解决

一、现象:使用AcDbDatabase readDwgFile dwg文件,然后使用setPlotWindowArea函数设置模型空间打印区域,保存退出。打开dwg后,预览发现设置的打印区域与实际需要的区域有偏移。
二、分析方法
1、检查发现设置区域的min点和max点的x、y值均正确
2、执行图纸修复,无错误,问题依旧
3、调整setPlotWindowArea函数与setPlotCentered、setPlotType函数执行顺序的位置,无效。
4、将图框复制到新的dwg文件中,发现结果正确,初步判断可能和系统变量有关,但变量值太多,不知道是哪个起的作用。
5、采用逆向思路,步骤如下:
5.1 找到数值的偏差
setPlotWindowArea函数使用问题的分析与解决_第1张图片
如上图,通过预览功能,将鼠标放在屏幕点上,可以知道设置的实际打印区域min点的x,y与设置区域min点的x,y有偏差。
5.2、计算出两个min点间的x,y差值。
5.3、通过setvar命令获取所有的图纸系统变量值,然后用5.2步骤计算出的差值进行查找,注意值不用完全符合,高位几位数大致符合即有可能是目标。最后发现“target”环境变量的值符合差值。

三、原因:dwg文件的target系统变量发生改变,默认为(0,0,0),出问题的图纸的x,y不为0,导致设置出现偏移。
四、解决方法:对设置的打印区域按target变量的值进行反平移,使之正确,部分代码如下:

  //readDwgFile不能通过acedGetVar获取target对象,要通过读取AcDbViewportTableRecord对象的target函数获取
  AcDbObjectId vpID= pDB->viewportTableId();

  AcDbObjectPointer<AcDbViewportTable> vpTable_Ptr(vpID,AcDb::kForRead);
  AcGePoint3d pnt_ViewTarget;
  {
   if (Acad::eOk == vpTable_Ptr.openStatus())
   {
    AcDbViewportTableRecord *vp_TbRec=NULL;
    if (Acad::eOk == vpTable_Ptr->getAt(acdbSymUtil()->viewportActiveName(),vp_TbRec,AcDb::kForRead))
    {
     pnt_ViewTarget=vp_TbRec->target();
     vp_TbRec->close();
     vp_TbRec=NULL;
    }
   }
  }

  AcGeMatrix3d mat;
  mat.setToTranslation(-(pnt_ViewTarget.asVector()));  //反向平移
  AcGePoint3d maxPnt,minPnt;
  maxPnt[X]=ext.maxPoint().x;
  maxPnt[Y]=ext.maxPoint().y;
  maxPnt[Z]=ext.maxPoint().z;
  minPnt[X]=ext.minPoint().x;
  minPnt[Y]=ext.minPoint().y;
  minPnt[Z]=ext.minPoint().z;
  maxPnt.transformBy(mat);
  minPnt.transformBy(mat);
  DwgBoxMaxExtInMSpace.set(minPnt,maxPnt);

你可能感兴趣的:(ObjectARX)