Skip to content

面域 ​

面域(Region)是由一条或多条闭合边界轮廓围成的二维填充区域,常用于表达带有面积的平面图形。与普通曲线不同,面域记录的是"区域"而非"轮廓线",因此支持对多个区域做布尔运算、边界偏移、三角化等几何处理。我们可以通过实例化一个 McDbMxRegion() 对象创建面域。

点击 McDbMxRegion() 查看详细属性和方法说明。

创建面域 ​

通过 addContour() 方法给面域添加一组点构成的边界轮廓,也可以通过 addEntityContour() 方法基于一个已有的曲线对象(如圆、多义线等)给面域添加边界轮廓,同一个面域可以添加多条边界轮廓。

点击 addContour() 、addEntityContour() 查看详细属性和方法说明。

ts
import { MxCpp, McCmColor, McDbMxRegion, McDbCircle, McGePoint3d, McGePoint3dArray } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()

// 通过一组点边界轮廓创建矩形面域
const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)

// 基于一个圆对象创建圆形面域
const region_1 = new McDbMxRegion()
region_1.addEntityContour(new McDbCircle(250, 40, 0, 40))
region_1.trueColor = new McCmColor(0, 255, 0)
mxcad.drawEntity(region_1)

布尔运算 ​

booleanOption(type, other) 用于把当前面域与另一个面域 other 进行布尔运算,运算类型由 BooleanOptionType 指定。布尔运算会重新计算区域的覆盖范围,是面域最核心的几何操作,常用于合并零件、求公共区域、开孔挖槽等场景。四种运算的几何意义与实现效果如下:

运算类型枚举值几何意义实现效果
并集 Union1合并两个面域覆盖的全部区域,重叠部分只保留一次把相邻或相交的多个区域拼成一个整体
交集 Intersection0只保留两个面域重叠的公共部分求公共区域,可用于裁剪、求重合面积
差集 Difference2从当前面域中减去与 other 重叠的部分在区域上开孔、挖槽、扣除(有方向性,是"当前面域 减 other")
异或 Xor3保留两个面域各自不重叠的部分,去掉公共重叠区域求两个区域的对称差

需要注意,布尔运算的结果可能分裂成多个互不连通的区域(例如差集之后剩下的部分可能不连续),因此 booleanOption() 返回的是面域数组 McDbMxRegion[],需要遍历数组逐个绘制。此外,每种运算都建议使用全新的面域对象,避免上一次运算的结果影响下一次。

点击 booleanOption() 查看详细属性和方法说明。

ts
import { MxCpp, McDbMxRegion, McDbCircle, McGePoint3d, McGePoint3dArray, McDb } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()

// 构造一对部分重叠的面域:矩形 A 与圆形 B
function createPair() {
  const regionA = new McDbMxRegion()
  const pointsA = new McGePoint3dArray()
  pointsA.append(new McGePoint3d(0, 0, 0))
  pointsA.append(new McGePoint3d(100, 0, 0))
  pointsA.append(new McGePoint3d(100, 80, 0))
  pointsA.append(new McGePoint3d(0, 80, 0))
  regionA.addContour(pointsA)

  const regionB = new McDbMxRegion()
  regionB.addEntityContour(new McDbCircle(100, 40, 0, 50))
  return [regionA, regionB]
}

// 并集:合并 A、B 覆盖的全部区域
const [a1, b1] = createPair()
a1.booleanOption(McDb.BooleanOptionType.Union, b1).forEach(item => mxcad.drawEntity(item))

// 交集:只保留 A、B 重叠的公共部分
const [a2, b2] = createPair()
a2.booleanOption(McDb.BooleanOptionType.Intersection, b2).forEach(item => mxcad.drawEntity(item))

// 差集:从 A 中减去与 B 重叠的部分(A 减 B 与 B 减 A 结果不同)
const [a3, b3] = createPair()
a3.booleanOption(McDb.BooleanOptionType.Difference, b3).forEach(item => mxcad.drawEntity(item))

// 异或:保留 A、B 各自不重叠的部分,去掉公共区域
const [a4, b4] = createPair()
a4.booleanOption(McDb.BooleanOptionType.Xor, b4).forEach(item => mxcad.drawEntity(item))

边界偏移 ​

inflatePaths(delta, joinType?, endType?) 用于把面域的边界整体向内或向外平移,生成一个新的面域。其几何意义是对区域做"等距膨胀/收缩":delta 为偏移距离,正值使边界向外扩张、区域变大,负值使边界向内收缩、区域变小。这一运算常用于生成轮廓的等距偏移线、预留加工余量、做区域缓冲(buffer)等。

其中 joinType 控制边界拐角处的连接方式(如直角、斜接、圆角),默认值为 2;endType 控制边界端点的闭合方式,默认值为 0。两者均为数值类型,具体取值含义可参考 API 文档。

点击 inflatePaths() 查看详细属性和方法说明。

ts
import { MxCpp, McCmColor, McDbMxRegion, McGePoint3d, McGePoint3dArray } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()

// 创建一个矩形面域
const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)

// 边界向外扩张 10,得到一个放大后的新面域
const inflated = region.inflatePaths(10)
inflated.trueColor = new McCmColor(255, 233, 0)
mxcad.drawEntity(inflated)

// 边界向内收缩 10,得到一个缩小后的新面域
const shrunk = region.inflatePaths(-10)
shrunk.trueColor = new McCmColor(0, 255, 0)
mxcad.drawEntity(shrunk)

三角化 ​

triangulate(useDelaunay?) 用于把面域剖分成一组三角形,返回一个新的面域。其几何意义是把任意形状的多边形区域离散成三角形网格:当 useDelaunay 为 true(默认)时采用德劳内(Delaunay)三角剖分,它会尽量让每个三角形都不"狭长",从而得到质量更均匀的网格。三角化是渲染填充、网格划分、有限元前处理等场景的常见前置步骤。

点击 triangulate() 查看详细属性和方法说明。

ts
import { MxCpp, McCmColor, McDbMxRegion, McDbCircle } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()

// 基于一个圆创建面域
const region = new McDbMxRegion()
region.addEntityContour(new McDbCircle(0, 0, 0, 50))
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)

// 对圆形面域做德劳内三角剖分,得到由三角形组成的新面域
const triangulated = region.triangulate(true)
triangulated.trueColor = new McCmColor(0, 128, 255)
mxcad.drawEntity(triangulated)

边界与面积查询 ​

面域还提供了一组查询与数据管理方法:getContourCount() 得到边界轮廓的数目,getContour(index) 得到指定序号的边界坐标,getArea() 计算面域面积(返回 { ret, val },ret 表示是否成功、val 为面积值),getBoundingBox() 得到面域的最小外包矩形。此外可以用 isEmpty() 判断面域数据是否为空、clearData() 清除面域数据、copyData() 从另一个面域拷贝数据。

点击 getContourCount() 、getContour() 、getArea() 、getBoundingBox() 查看详细属性和方法说明。

ts
import { MxCpp, McDbMxRegion, McGePoint3d, McGePoint3dArray } from "mxcad"

const mxcad = MxCpp.getCurrentMxCAD()

const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)

// 边界轮廓数目
console.log("边界数目:", region.getContourCount())
// 第 0 条边界的坐标点
console.log("边界坐标:", region.getContour(0))
// 面积
const area = region.getArea()
if (area.ret) console.log("面积:", area.val)
// 最小外包矩形
const box = region.getBoundingBox()
if (box.ret) console.log("外包矩形:", box.minPt, box.maxPt)