|
[code]在AcDbEntity筛选器中添加
Hatch.h
#pragma once
class Hatch
{
public:
Hatch();
~Hatch();
// 填充add方法:传入数据库对象ID列表、填充名字
static AcDbObjectId Add(const AcDbObjectIdArray &objIds,
const ACHAR* patName);
};
Hatch.cpp
#include "stdafx.h"
#include "Hatch.h"
#include "Database.h"
Hatch::Hatch(){}
Hatch::~Hatch(){}
// 填充add方法:传入数据库对象列表、填充名字
AcDbObjectId Hatch::Add(const AcDbObjectIdArray &objIds,
const ACHAR* patName)
{ // 异常变量
Acad::ErrorStatus es;
// 空的数据库填充对象
AcDbHatch *pHatch = new AcDbHatch();
// 填充对象的法向量、填充对象的标高
AcGeVector3d normal(0, 0, 1);
pHatch->setNormal(normal);
pHatch->setElevation(0);
// 是否关联边界(拉动边界线,填充图案跟着变化),需要反应器,下面if语句
pHatch->setAssociative(true);
// 填充图案:此处选择系统预定义(kPreDefined)图案,
// 名字为patName(系统命名的,参看Commands.cpp)
pHatch->setPattern(AcDbHatch::kPreDefined, patName);
// 填充边界:给填充对象添加边界
es = pHatch->appendLoop(AcDbHatch::kExternal, objIds);
// 显示填充
es = pHatch->evaluateHatch(true);
// 以上都在内存中操作,下面这句是将对象写入数据库文件dwg
AcDbObjectId hatchId = Database::PostToModelSpace(pHatch);
// 将填充对象与边界绑定
// 方法参数:pHatch接收由 读方式 打开的对象ID hatchId 返回的对象指针
if (acdbOpenObject(pHatch, hatchId, AcDb::kForRead) == Acad::eOk)
{ // 待绑定边界对象ID列表
AcDbObjectIdArray assocEntids;
// 给pHatch对象传入 待绑定边界对象ID列表
pHatch->getAssocObjIds(assocEntids);
// 读取每个ID
for (int i = 0; i < assocEntids.length(); i++)
{ // 获取每个待绑定边界对象ID相对应的指针
AcDbEntity *pEnt = NULL;
// 获取每个 待绑定边界对象ID 相对应的 指针 ,
// 添加到填充的反应器中(后面篇章讲)
if (acdbOpenObject(pEnt,
assocEntids.at(i),
AcDb::kForWrite) == Acad::eOk)
{ // 将对象指针 添加进 填充对象的永久反应器(后面篇章讲)中
pEnt->addPersistentReactor(hatchId);
pEnt->close();
}
}
pHatch->close();
}
return hatchId;
}
1.2 测试代码
Commands.h
#include "StdAfx.h"
void AddCommands();
void CreateHatch();
Commands.cpp
#include "StdAfx.h"
#include "Hatch.h"
#include "Editor.h"
#include "Commands.h"
void AddCommands()
{
Editor::AddCommand(_T("addHatch"), ACRX_CMD_MODAL, CreateHatch);
}
void CreateHatch()
{ // 接收待绑定数据库边界对象实体ID列表
AcDbObjectIdArray objIds;
// 选择集:框选实体对象 返回的一个对象集合(后续讲)
ads_name ss;
if (acedSSGet(NULL, NULL, NULL, NULL, ss) == RTNORM)
{
Adesk::Int32 len;
// 获取 选择集 选择了多少个实体对象:传入ss,返回len
if (RTNORM == acedSSLength(ss, &len))
{ // 遍历 选择集对象
for (Adesk::Int32 i = 0; i < len; i++)
{
ads_name ent;
// 获取选择集中的具体位置选择集对象ent
acedSSName(ss, i, ent);
AcDbObjectId objId;
// ads_name 转 数据库实体对象ID方法
acdbGetObjectId(objId, ent);
// 将objId添加进 待绑定数据库边界对象实体ID列表 objIds 中
objIds.append(objId);
}
}
}
// 释放选择集
acedSSFree(ss);
// 添加填充:objIds为if语句构造,ANGLE见下图
Hatch::Add(objIds, _T("ANGLE"));
}
hatch的图案名字
在这里插入图片描述
二、面域
2.1 面域类
模板:以第(三)篇文件结构为基础,构建自己的类库
在AcDbEntity筛选器中添加Region类
Region.h
#pragma once
class Region
{
public:
Region();
~Region();
// 面域add函数:传入面域边界数据库对象id列表
static AcDbObjectIdArray Add(const AcDbObjectIdArray &objIds);
};
Region.cpp
#include "stdafx.h"
#include "Region.h"
#include "Database.h"
Region::Region(){}
Region::~Region(){}
// 面域add函数:传入面域边界数据库对象id列表
AcDbObjectIdArray Region::Add(const AcDbObjectIdArray &objIds)
{ // 用于生成面域对象的列表
AcDbObjectIdArray regionArrs;
// 指向曲线实体的指针列表
AcDbVoidPtrArray curves;
// 面域类型: 指向新创建的面域的指针列表
AcDbVoidPtrArray regions;
AcDbEntity *pEnt = NULL;
AcDbRegion *pRegion = NULL;
// 遍历边界对象
for (int i = 0; i < objIds.length(); i++)
{ // 提取每个边界对象的指针
acdbOpenObject(pEnt, objIds.at(i), AcDb::kForRead);
// 判断指针是否为曲线类的派生类(面域边界的必要条件)
if (pEnt->isKindOf(AcDbCurve::desc()))
{ // 将指针类型强制转换为曲线类对象
AcDbCurve *pCurve = AcDbCurve::cast(pEnt);
// 添加到指针列表中
curves.append(pCurve);
}
}
// 用AcDbRegion的方法创建面域:用指针列表curves创建面域
Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
// 如果创建成功,将面域添加进数据库文件dwg
if (es == Acad::eOk)
{
for (int i = 0; i < regions.length(); i++)
{
pRegion = (AcDbRegion *)regions.at(i);
pRegion->setDatabaseDefaults();
AcDbObjectId regId;
regId = Database::PostToModelSpace(pRegion);
regionArrs.append(regId);
}
}
else
{ // 如果创建失败,释放指针指向的内存空间
for (int i = 0; i < regions.length(); i++)
{
delete (AcRxObject*)regions.at(i);
}
}
// 关闭对象
for (int i = 0; i < curves.length(); i++)
{
pEnt = (AcDbEntity *)curves.at(i);
pEnt->close();
}
return regionArrs;
}
2.2 测试代码
Commands.h
#include "StdAfx.h"
void AddCommands();
void CreateRegion();
Commands.cpp
#include "StdAfx.h"
#include "Region.h"
#include "Editor.h"
#include "Commands.h"
void AddCommands()
{
Editor::AddCommand(_T("addRegion"), ACRX_CMD_MODAL, CreateRegion);
}
void CreateRegion()
{
ads_name ss;
// 选择集选择边界对象
AcDbObjectIdArray ids;
if (acedSSGet(NULL, NULL, NULL, NULL, ss) == RTNORM)
{
Adesk::Int32 length;
if (RTNORM == acedSSLength(ss, &length))
{
for (Adesk::Int32 i = 0; i < length; i++)
{ // 遍历每个选择集内的对象
ads_name en;
acedSSName(ss, i, en);
// 将每个选择集内对象转换成数据库对象id
AcDbObjectId id;
acdbGetObjectId(id, en);
// 添加进对象列表中
ids.append(id);
}
}
}
// 释放选择集
acedSSFree(ss);
AcDbObjectIdArray regIds;
regIds = Region::Add(ids);
acutPrintf(_T("创建面域数量为%d"), regIds.length());
}
三、标注
3.1 标注类
模板:以第(三)篇文件结构为基础,构建自己的类库
在AcDbEntity筛选器中添加Dim类
Dim.h
#pragma once
class Dimension
{
public:
Dimension();
~Dimension();
// 对齐标注:起始点、终止点、标注线通过的点、文字内容(默认不改写)、标注样式(默认样式)
static AcDbObjectId AddAlignDimension(const AcGePoint3d &pt1,
const AcGePoint3d &pt2,
const AcGePoint3d &ptLine,
const ACHAR* dimTEXT = NULL,
AcDbObjectId dimStyle = AcDbObjectId::kNull);
// 重载对齐标注:起始点、终止点、标注线通过的点、标注文字偏移向量(默认)、文字内容(默认不改写)
static AcDbObjectId AddAlignDimension(const AcGePoint3d &pt1,
const AcGePoint3d &pt2,
const AcGePoint3d &ptLine,
const AcGeVector3d &vecOffset =
AcGeVector3d::kIdentity,
const ACHAR *dimText = NULL);
// 半径标注:圆心、弦上点、引线长度、标注文字(默认)、标注样式(默认)
static AcDbObjectId AddDimRadial(const AcGePoint3d &ptCenter,
const AcGePoint3d &ptChord,
double leaderLength,
const ACHAR *dimText = NULL,
AcDbObjectId dimStyle = AcDbObjectId::kNull);
// 重载半径标注:圆心、半径、弧度、引线长度(默认5)
static AcDbObjectId AddDimRadial(const AcGePoint3d &ptCenter,
double radius, double rad,
double leaderLength = 5);
// 两线求夹角:两线上的四个点、角度标注线上一点、标注文字(默认)、标注样式(默认)
static AcDbObjectId AddDim2LineAngular(const AcGePoint3d &ptStart1,
const AcGePoint3d &ptEnd1,
const AcGePoint3d &ptStart2,
const AcGePoint3d &ptEnd2,
const AcGePoint3d &ptArc,
const ACHAR* dimText = NULL,
AcDbObjectId dimStyle = AcDbObjectId::kNull);
// 三点夹角:角点、起点、终点、角度标注线上一点、标注文字(默认)、标注样式(默认)
static AcDbObjectId AddDim3PtAngular(const AcGePoint3d &ptCenter,
const AcGePoint3d &ptEnd1,
const AcGePoint3d &ptEnd2,
const AcGePoint3d &ptArc,
const ACHAR* dimText = NULL,
AcDbObjectId dimStyle = AcDbObjectId::kNull);
// 坐标标注:是否为x轴坐标(若为Adesk::kFalse则为y轴坐标)、待标点、轴标控制点、替换文字、样式
static AcDbObjectId AddDimOrdinate(Adesk::Boolean xAxis,
const AcGePoint3d &ptStart,
const AcGePoint3d &ptEnd,
const ACHAR *dimText = NULL,
AcDbObjectId dimStyle = AcDbObjectId::kNull);
// 第一个重载坐标标注:待标点、X轴标控制点、Y轴标控制点
static AcDbObjectIdArray AddDimOrdinate(const AcGePoint3d &ptDef,
const AcGePoint3d &ptTextX,
const AcGePoint3d &ptTextY);
// 第二个重载坐标标注:待标点、X轴坐标标注点向量、Y轴坐标标注点向量
static AcDbObjectIdArray AddDimOrdinate(const AcGePoint3d &ptDef,
const AcGeVector3d &vecOffsetX,
const AcGeVector3d &vecOffsetY);
};
Dim.cpp
#include "stdafx.h"
#include "Dimension.h"
#include "Database.h"
#include "Geometry.h"
#include "MathUtil.h"
Dimension::Dimension(){}
Dimension::~Dimension(){}
// 对齐标注:起始点、终止点、标注线通过的点、文字内容、标注样式
AcDbObjectId Dimension::AddAlignDimension(const AcGePoint3d &pt1,
const AcGePoint3d &pt2,
const AcGePoint3d &ptLine,
const ACHAR* dimTEXT ,
AcDbObjectId dimStyle)
{ // 单纯的调用对齐标注的构造函数创建
AcDbAlignedDimension *pDim = new AcDbAlignedDimension(pt1, pt2, ptLine,
dimTEXT, dimStyle);
return Database::PostToModelSpace(pDim);
}
// 重载对齐标注:起始点、终止点、标注线通过的点、标注文字偏移向量、文字内容(默认不改写)
AcDbObjectId Dimension::AddAlignDimension(const AcGePoint3d &pt1,
const AcGePoint3d &pt2,
const AcGePoint3d &ptLine,
const AcGeVector3d &vecOffset,
const ACHAR *dimText)
{ // 调用对齐标注构造函数,样式为默认
AcDbAlignedDimension *pDim = new AcDbAlignedDimension(pt1, pt2, ptLine,
dimText,
AcDbObjectId::kNull);
AcDbObjectId dimId = Database::PostToModelSpace(pDim);
// 操作数据库标注对象,调整其标注文字位置
AcDbAlignedDimension *pDimension = NULL;
// 打开数据库标注对象:传入数据库对象id dimId , 将返回的指针给pDimension
if (acdbOpenObject(pDimension,dimId,AcDb::kForWrite) == Acad::eOk)
{ // 移动文字位置前,需先指定尺寸线的变化情况(这里指定为:
// 尺寸线不动,在文字和尺寸线之间加箭头)
pDimension->setDimtmove(1);
// 获取当前标注文字的位置点坐标
AcGePoint3d ptText = pDimension->textPosition();
// 点运算:点 加 向量 等于 点
ptText = ptText + vecOffset;
// 设置标注文字位置:传入运算后的点
pDimension->setTextPosition(ptText);
// 关闭数据库对象指针
pDimension->close();
}
return dimId;
}
// 半径标注:圆心、弦上点、引线长度、标注文字、标注样式
AcDbObjectId Dimension::AddDimRadial(const AcGePoint3d &ptCenter,
const AcGePoint3d &ptChord,
double leaderLength,
const ACHAR *dimText,
AcDbObjectId dimStyle)
{ // 半径标注构造函数
AcDbRadialDimension *pDim = new AcDbRadialDimension(ptCenter,
ptChord,
leaderLength,
dimText,
dimStyle);
return Database::PostToModelSpace(pDim);
}
// 重载半径标注:圆心、半径、弧度、引线长度
AcDbObjectId Dimension::AddDimRadial(const AcGePoint3d &ptCenter,
double radius,
double rad,
double leaderLength)
{ // 极坐标系转平面坐标系
AcGePoint3d ptChord = Geometry::Polar(ptCenter, rad, radius);
// 调用半径标注第一个构造函数
return AddDimRadial(ptCenter, ptChord, leaderLength);
}
// 两线求夹脚:两线上的四个点、角度标注线上一点、标注文字、标注样式
AcDbObjectId Dimension::AddDim2LineAngular(const AcGePoint3d &ptStart1,
const AcGePoint3d &ptEnd1,
const AcGePoint3d &ptStart2,
const AcGePoint3d &ptEnd2,
const AcGePoint3d &ptArc,
const ACHAR* dimText,
AcDbObjectId dimStyle)
{ // 两线夹脚构造函数
AcDb2LineAngularDimension *pDim = new AcDb2LineAngularDimension(ptStart1, ptEnd1,
ptStart2, ptEnd2,
ptArc,
dimText,
dimStyle);
return Database::PostToModelSpace(pDim);
}
// 三点夹脚:角点、起点、终点、角度标注线上一点、标注文字、标注样式
AcDbObjectId Dimension::AddDim3PtAngular(const AcGePoint3d &ptCenter,
const AcGePoint3d &ptEnd1,
const AcGePoint3d &ptEnd2,
const AcGePoint3d &ptArc,
const ACHAR* dimText,
AcDbObjectId dimStyle)
{ // 三点夹脚构造函数
AcDb3PointAngularDimension *pDim = new AcDb3PointAngularDimension(ptCenter,
ptEnd1,
ptEnd2,
ptArc,
dimText,
dimStyle);
return Database::PostToModelSpace(pDim);
}
// 坐标标注:是否为x轴坐标(若为Adesk::kFalse则为y轴坐标)、待标点、轴标控制点、替换文字、样式
AcDbObjectId Dimension::AddDimOrdinate(Adesk::Boolean xAxis,
const AcGePoint3d &ptStart,
const AcGePoint3d &ptEnd,
const ACHAR *dimText,
AcDbObjectId dimStyle )
{
AcDbOrdinateDimension *pDim = new AcDbOrdinateDimension(xAxis, ptStart, ptEnd,
dimText, dimStyle);
return Database::PostToModelSpace(pDim);
}
// 第一个重载坐标标注:待标点、X轴标控制点、Y轴标控制点
AcDbObjectIdArray Dimension::AddDimOrdinate(const AcGePoint3d &ptDef,
const AcGePoint3d &ptTextX,
const AcGePoint3d &ptTextY)
{
AcDbObjectId dimId;
AcDbObjectIdArray dimIds;
// 调用坐标标注函数,创建X轴坐标标注
dimId = AddDimOrdinate(Adesk::kTrue, ptDef, ptTextX);
// 将返回的数据库坐标标注对象id添加进对象id列表中
dimIds.append(dimId);
// 调用坐标标注函数,创建Y轴坐标标注
dimId = AddDimOrdinate(Adesk::kTrue, ptDef, ptTextY);
// 将返回的数据库坐标标注对象id添加进对象id列表中
dimIds.append(dimId);
// 返回的对象id列表
return dimIds;
}
// 第二个重载坐标标注:待标点、X轴标向量、Y轴标向量
AcDbObjectIdArray Dimension::AddDimOrdinate(const AcGePoint3d &ptDef,
const AcGeVector3d &vecOffsetX,
const AcGeVector3d &vecOffsetY)
{ // 求X、Y轴标控制点
AcGePoint3d ptTextX = ptDef + vecOffsetX;
AcGePoint3d ptTextY = ptDef + vecOffsetY;
// 调用第一个重载坐标标注
return AddDimOrdinate(ptDef, ptTextX, ptTextY);
}
3.2 测试代码
Commands.h
#include "StdAfx.h"
void AddCommands();
void CreateDim();
Commands.cpp
#include "StdAfx.h"
#include "Commands.h"
#include "Line.h"
#include "Editor.h"
#include "Circle.h"
#include "Geometry.h"
#include "MathUtil.h"
#include "Dim.h"
void AddCommands()
{
Editor::AddCommand(_T("AddDim"), ACRX_CMD_MODAL, CreateDim);
}
void CreateDim()
{ // 创建点:常规、相对坐标、极坐标
AcGePoint3d pt1(0, 0, 0);
AcGePoint3d pt2 = Geometry::RelativePoint(pt1, 150, 0);
AcGePoint3d pt3 = Geometry::Polar(pt1, MathUtil::PI()/4, 150);
// 画线、圆, 并修改颜色
AcDbObjectId id_1 = Line::Add(pt1, pt2);
AcDbObjectId id_2 = Line::Add(pt1, pt3);
AcDbObjectId id_3 = Circle::Add(pt3, 50);
Editor::SetColor(id_1, 2);
Editor::SetColor(id_2, 2);
Editor::SetColor(id_3, 2);
// 对齐标注:起始点、终止点、标注线通过的点、标注文字偏移向量、文字内容
AcGePoint3d ptTemp = Geometry::RelativePoint(pt1, 0, 10);
Dimension::AddAlignDimension(pt1, pt3, ptTemp, AcGeVector3d(0, 10, 0), _T("对齐标注"));
// 三点夹脚:起点、圆心点、终点、角度标注线上一点
ptTemp = Geometry::RelativePoint(pt1, 50, 0);
Dimension::AddDim3PtAngular(pt1, pt2, pt3, ptTemp);
// 半径标注:圆心、弦上点、引出线长
ptTemp = Geometry::Polar(pt3, MathUtil::PI() / 3, 50);
Dimension::AddDimRadial(pt3, ptTemp, 25);
// 坐标标注:待标点、X轴坐标标注点向量、Y轴坐标标注点向量
Dimension::AddDimOrdinate(pt2, AcGeVector3d(10, -20, 0), AcGeVector3d(10,10, 0));[/code] |
|