mcpField
B
blockbench-modeling

blockbench-modeling

github.com/jasonjgardner创意与媒体261.3k 次安装5 周前更新
代码仓库

关于 blockbench-modeling

blockbench-modeling 是用于在 Blockbench 中创建和编辑立方体及网格 3D 模型的技能,涵盖几何规划、UV、层级结构和超大 Bedrock 方块模型处理。

主要功能

  1. 01创建和编辑立方体与网格
  2. 02按外形和性能规划几何
  3. 03组织带关节枢轴的层级结构
  4. 04检查和调整 UV 映射
  5. 05切分并整理超大 Bedrock 方块

适用场景

  1. 01先搭建模型轮廓再添加细节
  2. 02使用关节枢轴构建可活动模型
  3. 03创建网格基本体并编辑几何
  4. 04将超大模型拆分为方块区段

MCP 相关

该技能介绍通过 MCP 调用 Blockbench 建模工具,包括立方体、网格、元素、选择和边界操作。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jasonjgardner/blockbench-mcp-project --skill blockbench-modeling

安装后在 Claude Code 中输入/blockbench-modeling确认已加载。

附带文件references/bedrock-primitives.md

详细介绍

Blockbench 建模

在 Blockbench 中使用立方体和网格构建 3D 模型。

规划形状和目标

在创建新模型或进行大幅几何重设计之前,通过 Blockbench 用法 确定用户对外观/准确度、性能或平衡的偏好。遵循外观和性能规划,设定工作元素/面数预算,并选择哪些细节应放在几何体、UV 图块或 PBR 中。在复制扩展之前,先制作一个重复部分的原型并统计数量;支撑件、填充件、底板和紧固件不应自动拆分为独立立方体。

将面数用于轮廓、视差和形变。删除任何必需视角或姿势下都看不到的面,因为实时网格无需密闭。让部件相互交叠,而不是在接合处缝合边环;将薄细节平面悬浮放置,而不是在几何体上刻出细节。对于深度必须随摄像机移动而变化的凹槽和开口,应保留几何体。有关各目标的平台预算和面删除规则,请参阅实时资源规划第 4–6 节。

选择格式或导出时,请参阅格式和交付指南。先搭建轮廓和比例,再进行 UV 布局和表面细节。根据可见形状或形变需求匹配多边形密度;自动细分本身并不等于提升质量。

对于可活动部件,应创建以关节为轴心的层级结构,并使用唯一且一致的骨骼名称。组原点是轴心,不是加到立方体 from/to 坐标上的位移。将立方体边界放在模型的静止坐标空间中;层级结构会围绕这些轴心应用旋转。网格顶点采用网格局部坐标,如下文所述。检查重叠表面是否会发生 Z 冲突,并预览活动部件是否会露出隐藏间隙。请参阅官方建模概览。

以不同尺寸调整或复制带纹理的几何体时,应重新评估各面的 UV 跨度,而不是盲目沿用源矩形。遵循 UV 缩放和失真指南,了解侧面/端面比例、最终缩放变换和共享材质密度。应在所选几何预算内修正映射;增加立方体并非解决纹理拉伸的默认办法。

可用工具

立方体工具
工具用途
place_cube创建立方体并设置位置、尺寸和纹理
modify_cube编辑立方体属性(位置、旋转、UV 等)
get_cube_uv / set_cube_uv检查/编辑盒式或逐面立方体 UV;请参阅纹理技能
网格工具
工具用途
place_mesh创建带索引面的网格;返回 UUID 和运行时几何键
get_mesh_info检查网格局部位置、面、法线、选择状态、纹理和可选 UV
create_sphere创建球体网格
create_cylinder创建圆柱体网格
extrude_mesh挤出所选面区域;不支持边/顶点模式
subdivide_mesh将所选三角形/四边形细分为每条边 cuts + 1 个分段
select_mesh_elements选择顶点/边/面
move_mesh_vertices移动所选顶点
delete_mesh_elements移除几何体
merge_mesh_vertices焊接附近的顶点
create_mesh_face根据顶点创建面
knife_tool不支持通过 MCP 使用网格点列表切割
knife_cut_cube用于立方体的无头 Knife 工具:沿一个轴在指定位置切分
slice_cubes_to_block_grid在 Bedrock 方块边界处切割立方体,并按方块重新分组
inspect_block_bounds检查立方体/组是否超出 30×30×30 的超大方块限制
元素工具
工具用途
add_group创建骨骼/组
list_outline查看模型层级
duplicate_element复制元素
rename_element重命名元素
remove_element删除元素
find_elements_by_criteria按名称模式、类型、父级和尺寸查询元素
select_all_of_type批量选择立方体、网格或组
filter_by_material查找引用某个纹理的元素

立方体建模

当前源插件中的 place_cube 支持创建无纹理的灰盒模型;使用 get_capabilities: include_tools=true 可识别已加载的构建版本。确定轮廓后即可创建新纹理。提供纹理或组时,必须使用有效的现有引用。后续编辑请使用返回的 UUID;字面值 group="root" 或 add_group 的 parent="root" 表示大纲视图的根节点。为避免使用此保留目标,请将实际的根骨骼命名为 rig_root,或使用其 UUID。

放置一个立方体
place_cube: elements=[{
  name: "body",
  from: [-4, 0, -2],
  to: [4, 12, 2]
}], faces=true  # Size-based Auto UV; this does not pack a texture atlas
放置多个立方体
place_cube: elements=[
  {name: "head", from: [-4, 12, -4], to: [4, 20, 4]},
  {name: "arm_left", from: [4, 4, -1], to: [6, 12, 1]},
  {name: "arm_right", from: [-6, 4, -1], to: [-4, 12, 1]}
], group="body"
修改立方体
modify_cube: id="body", rotation=[0, 45, 0], origin=[0, 6, 0]
带纹理的立方体
place_cube: elements=[{name: "block", from: [0,0,0], to: [16,16,16]}],
  texture="stone", faces=true
Bedrock 杆、圆柱和管

对于 Bedrock 立方体模型中的圆形基元,请阅读Bedrock 基元构造。其中推导了实心和中空形状的多边形边宽及共享枢轴旋转,并遵循 Shape Generator 插件的八边形和 16 边形构造方式。请根据外观/性能预算选择面数,区分平面间距与角间直径,并检查重叠端面和 UV 缩放。create_cylinder 会创建网格;如果目标要求使用立方体,请使用计算得出的 place_cube 批次。

网格建模

创建网格前,请检查 get_capabilities。请使用已注册且 format.features.meshes=true 的格式,通常为 free(Generic Model)。

创建网格并保留其 ID

以下 JavaScript 示例是客户端编排伪代码:call(name, args) 会调用对应的 MCP 工具并检查 isError。对于 JSON 结果,它会返回 structuredContent 或解码后的 JSON 文本;对于纯文本结果,则会原样返回文本。这不是供 risky_eval 使用的代码。panel.uuid 和 panel.face_keys[0] 等变量在实际工具参数中必须替换为其返回值,不可作为字面字符串发送。

const placed = await call("place_mesh", {
  elements: [{
    name: "panel",
    vertices: [[0, 0, 0], [4, 0, 0], [4, 4, 0], [0, 4, 0]],
    faces: [[0, 1, 2, 3]],
  }],
});
const panel = placed.meshes[0];
// panel: {name, uuid, vertex_keys: [...], face_keys: [...]}

输入面的顶点使用从零开始的索引。返回的 vertex_keys 和 face_keys 按输入顺序排列,并包含实际的运行时键。后续的选择、创建面和 UV 工具都需要这些键。网格名称或 UUID 用于标识网格,而不是其顶点或面。请保留 UUID,以避免名称歧义。拓扑编辑或撤销/重做后,请重新检查,再重复使用组件键。

检查几何体并读取所有分页

对于基元或现有网格,请使用 get_mesh_info 获取键。顶点条目包含 {key, position, selected};面条目包含 {key, vertices, normal, selected, texture}。位置、边界和法线均为网格局部坐标,不包含原点、旋转和父级变换。

async function readMeshPages(meshId, part, offset = 0) {
  // part is "vertices" or "faces". Read one list independently.
  const info = await call("get_mesh_info", {
    mesh_id: meshId,
    include_vertices: part === "vertices",
    include_faces: part === "faces",
    [part === "vertices" ? "vertex_offset" : "face_offset"]: offset,
    limit: 500,
  });
  const page = info[part];
  if (page.next_offset === null) return page.items;
  return page.items.concat(await readMeshPages(meshId, part, page.next_offset));
}

每个列表都有自己的 next_offset;null 表示已完成。默认限制为 100,每个列表最多为 500。修改几何体前请完成分页,因为键会排序,编辑可能导致偏移量失效。检查操作为只读,不会选择组件。

创建球体
create_sphere: elements=[{
  name: "ball",
  position: [0, 8, 0],
  diameter: 16,
  sides: 12
}]
创建圆柱体
create_cylinder: elements=[{
  name: "pillar",
  position: [0, 0, 0],
  diameter: 8,
  height: 24,
  sides: 12,
  capped: true
}]
挤出面

对于上面创建的未旋转、带封口的圆柱体,请选择所有朝向局部 +Y 的封口三角面:

const pillarFaces = await readMeshPages("pillar", "faces");
const capKeys = pillarFaces.filter(face => face.normal[1] > 0.99).map(face => face.key);
if (capKeys.length === 0) throw new Error("No upward cap faces found; inspect the mesh.");
await call("select_mesh_elements", {mesh_id: "pillar", mode: "face", elements: capKeys});
await call("extrude_mesh", {mesh_id: "pillar", mode: "faces", distance: 4});
细分以增加细节
select_mesh_elements: mesh_id="ball", mode="face"  # Select all faces explicitly
subdivide_mesh: mesh_id="ball", cuts=2
移动顶点

继续使用 panel 创建示例,在更改其拓扑之前执行:

await call("select_mesh_elements", {
  mesh_id: panel.uuid, mode: "vertex", elements: panel.vertex_keys.slice(2, 4),
});
await call("move_mesh_vertices", {mesh_id: panel.uuid, offset: [0, 2, 0]});
合并相近顶点
merge_mesh_vertices: mesh_id="panel", threshold=0.1
刀切

网格刀具依赖交互式指针状态,因此 knife_tool 对点列表会返回不支持的操作错误。若要通过脚本切割网格,请使用 get_mesh_info 检查网格,使用 place_mesh 构造预期的替换顶点和面,验证后,再在用户要求的范围内替换原始几何体。如果用户希望手动切割,请使用 Blockbench 的交互式刀具。

立方体可以在无头模式下切割。knife_cut_cube 模拟 Blockbench 对立方体的刀切:每个切割平面都垂直于一个轴,原立方体保留较低的一块,新块会获得唯一名称(pole_2、pole_3),并按比例共用面 UV。所有切割共用一个撤销记录。

knife_cut_cube({ cubes: ["pole"], axis: "y", positions: [16, 32, 48] })
超大 Bedrock 方块

Bedrock 自定义方块的几何体必须适合一个 30×30×30 的盒子,其中心与方块中心的距离最多为 7 个单位;Blockbench 会强制要求 x/z 在 ±22 以内,y 在 -14…30 以内(Microsoft 的页面对限制的描述较为宽泛:https://learn.microsoft.com/minecraft/creator/documents/customblockoversized)。更大的模型必须拆分为按方块划分的区段。

  1. inspect_block_bounds 会根据这些限制报告模型、组和立方体的范围,指出每个立方体所在的方块单元,以及可能将其分割的网格切割位置。
  2. slice_cubes_to_block_grid 会在每个立方体跨越方块边界时进行切割(x/z 边界为 ±8、±24、…;y 边界为 0、16、32、…),并默认将各块移入每个方块单元对应的独立组(bottom、top、right_top_front、top2、…),组枢轴设在该方块的原点。绕其他两个轴旋转的立方体不会被切割,并会列在 skipped_rotated 中。
  3. 将每个单元组导出为独立的方块几何体;如果自动网格切割不符合模型需求,也可以使用 knife_cut_cube 手动切割。
inspect_block_bounds({})
slice_cubes_to_block_grid({ regroup: true, group_prefix: "goal_" })

组织结构

创建组层级
add_group: name="rig_root", origin=[0, 0, 0], rotation=[0, 0, 0]
add_group: name="body", parent="rig_root", origin=[0, 12, 0]
add_group: name="head", parent="body", origin=[0, 24, 0]
将立方体添加到组
place_cube: elements=[{name: "torso", from: [-4, 12, -2], to: [4, 24, 2]}],
  group="body"
复制元素
duplicate_element: id="arm_left", newName="arm_right", offset=[-8, 0, 0]
查看层级
list_outline  # Returns all groups and elements

选择与筛选

无需加载完整大纲即可查询模型。除 select_all_of_type 外,这些工具均为只读。

按条件查找元素

可组合使用以下任意条件:正则表达式名称匹配、子字符串匹配、类型、父组范围、立方体尺寸范围、选择范围。

# All cubes under "body" named like "arm_*"
find_elements_by_criteria: type="cube", parent_group="body", name_pattern="^arm_"

# Small cubes (under 4 units on any axis) in the currently selected elements
find_elements_by_criteria: selected_only=true, max_size=[4, 4, 4]

# Groups whose name contains "hand" (case-insensitive)
find_elements_by_criteria: type="group", name_contains="hand"

返回 { count, truncated, matches: [{ uuid, name, type, parent }] }。

选择所有指定类型的元素
# Replace selection with every cube in the project
select_all_of_type: type="cube"

# Add all meshes under "head" to the current selection
select_all_of_type: type="mesh", parent_group="head", add_to_selection=true
按材质筛选

查找所有引用特定纹理的立方体或网格。对于立方体,会返回精确的面键。

filter_by_material: texture="skin"
# → { texture, count, matches: [{ uuid, name, type: "cube", faces: ["north", "up"] }] }

重构纹理时很有用:替换或停用纹理前,先查找所有使用该纹理的元素。

常见模式

Minecraft 角色

此示例假设使用带有骨骼绑定的立方体格式,且静止姿势高度为 32 个单位。它不规定玩家皮肤模板。立方体边界已包含其在角色中的位置;组枢轴不会重新定位立方体。

# Create hierarchy
add_group: name="rig_root", origin=[0, 0, 0]
add_group: name="body", parent="rig_root", origin=[0, 24, 0]
add_group: name="head", parent="body", origin=[0, 24, 0]
add_group: name="arm_left", parent="body", origin=[5, 22, 0]
add_group: name="arm_right", parent="body", origin=[-5, 22, 0]
add_group: name="leg_left", parent="rig_root", origin=[2, 12, 0]
add_group: name="leg_right", parent="rig_root", origin=[-2, 12, 0]

# Add geometry
place_cube: elements=[{name: "head_geo", from: [-4, 24, -4], to: [4, 32, 4]}], group="head"
place_cube: elements=[{name: "body_geo", from: [-4, 12, -2], to: [4, 24, 2]}], group="body"
place_cube: elements=[{name: "arm_left_geo", from: [4, 12, -1], to: [6, 22, 1]}], group="arm_left"
place_cube: elements=[{name: "arm_right_geo", from: [-6, 12, -1], to: [-4, 22, 1]}], group="arm_right"
place_cube: elements=[{name: "leg_left_geo", from: [0, 0, -2], to: [4, 12, 2]}], group="leg_left"
place_cube: elements=[{name: "leg_right_geo", from: [-4, 0, -2], to: [0, 12, 2]}], group="leg_right"
平滑有机形状

仅当所需形状需要更多顶点时才进行细分。细分会增加拓扑;它本身不会平滑轮廓。

await call("create_sphere", {
  elements: [{name: "base", position: [0, 8, 0], diameter: 16, sides: 16}],
});
await call("select_mesh_elements", {mesh_id: "base", mode: "face"});
await call("subdivide_mesh", {mesh_id: "base", cuts: 1});
const vertices = await readMeshPages("base", "vertices");
const upperKeys = vertices.filter(vertex => vertex.position[1] > 0).map(vertex => vertex.key);
await call("move_mesh_vertices", {mesh_id: "base", offset: [0, 4, 0], vertices: upperKeys});

该谓词使用局部 Y,因此即使球体的世界 Y 坐标原点为 8,> 0 仍会选中球体的上半部分。对于其他形状,请根据检查到的几何体使用合适的谓词。

提示

  • 使用 list_outline 查看当前模型结构
  • 使用 find_elements_by_criteria 进行有针对性的查询,而不是在客户端筛选 list_outline 的结果
  • 将组原点设在关节/枢轴点处,以便进行动画制作
  • 对基于尺寸的立方体 UV 使用 faces=true;详细绘制前先检查并整理 UV
  • 添加几何体前先创建骨骼层级
  • 使用偏移量调用 duplicate_element 会创建平移副本,而非镜像形状或镜像 UV 布局
  • 网格编辑更加灵活,但对于 Minecraft 风格的模型,立方体更简单
  • 大规模返工时,save_checkpoint 历史记录标记有助于恢复;执行 undo 前请先检查实际历史记录

评论

支持 Markdown