一键导入
dm-primitive-tool-implementation-pattern
Standardized pattern for creating interactive SDF primitive tools in the Direct Modeling workbench.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Standardized pattern for creating interactive SDF primitive tools in the Direct Modeling workbench.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Architecture reference for the unified edit-mode transform gizmo (translation arrows + rotation rings, transform spaces, x-ray rendering). Required reading before implementing any task in todo.md whose ID begins with GIZMO-.
Reference for the two-color (orange/blue) boolean system where IsSubtractive classifies inputs into groups and boolean operations combine them into a parent-child tree. Required reading before implementing any task in todo_bool.md.
Template and rules for creating new SDF primitive field classes in core/sdf/sdf/. Required reading before implementing any new SdfField subclass.
Reference for converting SVG path data (M L H V C S Q T A Z) and shape elements (rect, circle, ellipse, line, polyline, polygon) into cubic Bezier segments with no rasterization. Required reading before implementing svg_importer.py.
Convention for registering primitive-specific GLSL inside the primitive's own .py file. Required reading before editing any to_glsl/to_glsl_2d method.
FreeCAD BSpline API reference and to_glsl() contract for SdfNurbsCurveField and SdfNurbsSurfaceField — tasks NS-001..NS-008 in todo_arch_refactor.md.
| name | DM Primitive Tool Implementation Pattern |
| description | Standardized pattern for creating interactive SDF primitive tools in the Direct Modeling workbench. |
This skill defines the canonical pattern for implementing interactive SDF primitive creator tools (e.g., Box, Sphere, Cylinder) in the Direct Modeling workbench. All new primitive tools must follow this pattern to ensure consistent UX, workplane support, and visual feedback.
self.working_plane).self.projector.get_mouse_plane_pt instead of get_mouse_world_pos to ensure input is projected onto the active plane._last_working_plane).DMPoint to show where the user has clicked during the multi-step creation process._do_terminate to clean up Coin3D visuals (points, etc.).class MyPrimitiveCreator(PrimitiveCreatorBase):
def __init__(self):
super().__init__()
# PrimitiveCreatorBase.__init__ already handles:
# self.dm_points, self.points_root, self._init_working_plane()
# Only add tool-specific state here:
self.points = []
self.current_point = None
self.projector.get_mouse_plane_pt(event_dict, working_plane=self.working_plane) in on_button1_down.wp_hit from the projector result to lock onto a specific plane on the first click.DMInputManager.get_instance().get_axis_point.# In on_button1_down or similar:
dm_pt = DMPoint(pos)
dm_pt.draw_point(self.points_root, self._compute_handle_radius(ref_pt=pos))
self.dm_points.append(dm_pt)
def _do_terminate(self):
for pt in self.dm_points: pt.undraw()
if self.points_root:
self.view.getSceneGraph().removeChild(self.points_root)
super()._do_terminate()
Every PrimitiveCreatorBase subclass must override get_sdf_type() to return a unique
lowercase string identifying the primitive type:
def get_sdf_type(self):
return "sphere" # or "box", "cylinder", "torus", etc.
The base class returns "", which suppresses saving. Both commit paths (__do_commit and
_do_commit_and_edit) call self.get_sdf_type() and store the result as obj.SdfType
(an App::PropertyString). This property is read by DMObjectProxy._reconstruct_field()
on document load to rebuild the SdfField.
After adding a new primitive type, also add a matching branch in DMObjectProxy._reconstruct_field()
in core/dm_object.py that reconstructs the field from fp.Points and fp.Placement.
See BoxCreator in tools/primitive_tool.py as the "Gold Standard" implementation.