원클릭으로
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.