开发过程中,当从外部获取了一个,需要修改块中的实体时,有以下几种方法。
1.第一个通过explode函数炸开AcDbBlockReference,获取块参照中的实体对象,然后遍历对象,找到修改的实体,完成修改后将所有的实体插入到模型空间。
注意的是:炸开块参照并不是将已经插入到模型空间中的参照分解,而是在内存中创造一个分解后的对象。其对象并没有存在于数据库中。
所以第一种方法一般用于将块参照插入到数据库之前。
2.第二个通过遍历块定义中的实体对象,找到需要修改的块并进行修改。 这种方法是修改了AcDbBlockTableRecord中的模板,所以这会作用于所有以该模板生成的块插入中。
并且会存在修改之后无法更新修改过的实体的情况。(如直径标注和对齐标注)
3.第三个通过创建匿名块定义,修改匿名块定义中的实体,这样创造出来的AcDbBlockReference就是唯一对应于该匿名块的块参照,避免了重复插入和相互之间的影响。
在CAD中需要进行空间坐标系的转换或位置的偏移或角度旋转都需要用到AcGeMatrix3d这个类。
如在AcDbBlockTableRecord中的图形对象它的位置和实际Modal_Space空间中的AcDbBlockReference中图形对象的位置存在偏差,需要用以下函数进行转换。
AcGeMatrix3d blockTransform() const;
获取AcDbBlockReference的转换矩阵。当用户按照AcDbBlockTableRecord模板创造AcDbBlockReference后并插入到模型空间中,这个过程伴随着实体对象的位置、大小形状等变化。而变化的依据在于该矩阵。当我们需要获取块定义中一个实体的位置信息却不想炸开块插入时,我们可以遍历AcDbBlockTableRecord,找到模板中的实体并通过以下函数进行转换,pEnt为转换后,在模型空间中的实体。
ACDB_PORT ADESK_SEALED_VIRTUAL Acad::ErrorStatus getTransformedCopy( const AcGeMatrix3d& xform, AcDbEntity*& pEnt ) const;
其次,当需要在模型空间中旋转一个实体时,若该实体不提供Rotation函数,同样可适用AcGeMatrix3d。
static AcGeMatrix3d rotation(
double angle, const AcGeVector3d& axis, const AcGePoint3d& center = AcGePoint3d::kOrigin );
获取该矩阵旋转之后的结果。
setToMirroring:设置以某一点进行对称的镜像变换。
setToRotation:设置绕某一点旋转一定角度的旋转变换。
setToScaling:设置以某一个基点缩放变换
setToTranslation:设置某个矢量为移动基准的移动变换
CAD中,得到两点之间的距离:
double distanceTo( const AcGePoint3d& pnt ) const;
在CAD中,若要对块参照进行伸缩变换,可以使用AcGeScale3d这个类.
这个类可以通过设置不同轴的伸缩比例来进行缩放。
AcGeScale3d DbScale = DbReference->scaleFactors();
DbScale.sy*=scale; //scale为比例系数
DbReference->setScaleFactors(DbScale);