Mxs技术问询:按边界拆分收集网格开放边至多维数组
解决MaxScript中网格开放边按边界环分组的问题
没问题,这需求很明确——要把网格里的开放边按独立的边界环(比如孔洞的边缘)拆分成对应的子数组对吧?我写了个MaxScript脚本,完美实现这个功能,还加了详细注释,你可以直接用:
fn getBoundaryEdgeLoops targetMesh = ( -- 存储最终的边界环数组,每个子数组对应一个边界的边索引 local boundaryLoops = #() -- 提前获取网格的边总数,方便后续操作 local edgeCount = targetMesh.numEdges -- 第一步:收集所有开放边的索引 local openEdges = #() for e in 1 to edgeCount do ( if targetMesh.openEdge[e] do append openEdges e ) -- 如果没有开放边,直接返回空数组 if openEdges.count == 0 do return boundaryLoops -- 创建一个数组标记边是否已被处理,避免重复遍历 local visitedEdges = #(false) * (edgeCount + 1) -- 边索引从1开始,所以多开一个位置 -- 第二步:遍历所有开放边,分组连通的边形成边界环 for startEdge in openEdges do ( -- 如果这条边已经被处理过,跳过 if visitedEdges[startEdge] do continue -- 初始化当前边界环的数组 local currentLoop = #() -- 当前处理的边,从起始边开始 local currentEdge = startEdge -- 记录起始边的第一个顶点,用于判断环是否闭合 local startVert = targetMesh.getEdgeVert currentEdge 1 while true do ( -- 将当前边加入环数组,并标记为已访问 append currentLoop currentEdge visitedEdges[currentEdge] = true -- 获取当前边的两个顶点 local vert1 = targetMesh.getEdgeVert currentEdge 1 local vert2 = targetMesh.getEdgeVert currentEdge 2 -- 找下一条连通的开放边:从vert2出发,找未被访问的开放边 local nextEdge = undefined for e in openEdges do ( if not visitedEdges[e] do ( local eVert1 = targetMesh.getEdgeVert e 1 local eVert2 = targetMesh.getEdgeVert e 2 -- 判断这条边是否和当前边的vert2相连 if (eVert1 == vert2) or (eVert2 == vert2) do ( nextEdge = e exit -- 找到就跳出循环 ) ) ) -- 如果找不到下一条边,检查是否回到起始顶点(闭合环) if nextEdge == undefined do ( -- 最后一条边的第二个顶点应该和起始顶点一致,确保环闭合 if vert2 == startVert do break -- 特殊情况:如果是不闭合的边界?不过Max里的开放边环应该都是闭合的(比如孔洞) -- 如果遇到不闭合的,也直接结束当前环 break ) -- 更新当前边为找到的下一条边 currentEdge = nextEdge ) -- 将当前边界环加入结果数组 append boundaryLoops currentLoop ) -- 返回分组后的边界环数组 return boundaryLoops ) -- 示例用法:选中一个网格对象后运行 if selection.count == 1 and classof selection[1] == Editable_Mesh do ( local meshObj = selection[1] local loops = getBoundaryEdgeLoops meshObj print "找到的边界环数量:" + loops.count as string for i in 1 to loops.count do ( print ("边界环 " + i as string + " 的边索引:" + loops[i] as string) ) ) else ( print "请选中一个Editable Mesh对象!" )
脚本说明:
- 核心逻辑:先筛选出所有开放边,然后通过遍历连通的开放边,把属于同一个边界环的边归到同一个子数组里,用
visitedEdges数组避免重复处理。 - 适配性:不管网格有几个孔洞(边界环),都会自动分成对应的子数组,比如2个孔洞就返回包含2个子数组的数组。
- 使用方式:选中一个Editable Mesh对象,运行脚本即可,控制台会输出每个边界环的边索引。
如果你的网格是Poly对象,只需要先转换成Editable Mesh(或者修改脚本里的判断和边的获取方式,不过上面的脚本用Editable Mesh更稳定)。
内容的提问来源于stack exchange,提问作者Maarten -Monica for president
相关产品推荐
相关产品推荐

