---
name: blender_sculpting_basics
description: "Shape a mesh form in Blender sculpt mode: enter sculpt mode on a base mesh, set symmetry, choose a brush by its sculpt brush type and set size, strength, and falloff, pick one detail strategy (dynamic topology, voxel remesh, or multires), mask finished areas, and stop at the right point to hand off to retopology, UV, or rigging work. Use when a mesh exists as a rough base and needs its form sculpted before any later stage."
metadata: { "includeInPrompt": true }
---

# Blender Sculpting Basics

## Purpose

Take a base mesh from rough volume to a finished form using sculpt brushes. The work runs in a fixed order: prepare a clean base, set symmetry before the first stroke, block out large form with big brushes at low detail, pick one detail strategy and stay with it, refine in passes, protect finished areas with a mask, and stop when the form reads well and the mesh needs a different kind of work than brushes can give. Sculpting decides shape only. Topology for deformation, UV layout, and materials belong to later stages, and this skill hands off to them instead of trying to do their job with brushes.

Scope:
- blender-rigging-basics rigs an already-shaped mesh (armature, weights, IK). This skill produces the shaped mesh that rigging starts from.
- blender-animation-basics animates an already-rigged mesh. This skill does no animation.
- uv-unwrapping-basics unwraps for texturing. This skill does no UV work, and its detail strategies usually produce topology that still needs retopology before unwrapping makes sense.
- blender-material-shaders builds PBR shader materials. This skill sets no materials.
- blender-geometry-nodes-basics generates geometry procedurally with node groups. This skill shapes geometry by hand with brushes, one stroke at a time.
- headless-blender renders headless. This skill uses headless runs only to check scene state with the audit script in the Operating Rules section. It claims no render result.
- This skill is the stage that shapes the mesh form itself with brushes: sculpt mode, DynTopo, voxel remesh, multires. It sits before rigging and UV work.
- Verification note, 2026-10-21: every operator and property named in this skill was probe-checked in real headless runs of Blender 5.1.1, the version `~/.local/bin/blender --version` returned on the drafting machine, started as `~/.local/bin/blender -b --factory-startup --python script.py`. Operators called and returned FINISHED: `bpy.ops.mesh.primitive_uv_sphere_add`, `bpy.ops.mesh.primitive_ico_sphere_add`, `bpy.ops.mesh.primitive_cube_add`, `bpy.ops.object.mode_set` with SCULPT and OBJECT, `bpy.ops.object.modifier_add` with type MULTIRES, `bpy.ops.object.multires_subdivide`, `bpy.ops.object.multires_base_apply`, `bpy.ops.sculpt.dynamic_topology_toggle`, `bpy.ops.sculpt.optimize`, `bpy.ops.object.voxel_remesh`, `bpy.ops.object.quadriflow_remesh`, `bpy.ops.object.shade_smooth`, `bpy.ops.wm.read_factory_settings`, `bpy.ops.wm.save_as_mainfile`, and `bpy.ops.wm.open_mainfile`. A UV sphere at segments 32 and ring_count 16 measured 482 vertices and 512 polygons, an icosphere at subdivisions 3 measured 162 vertices and 320 polygons, a voxel remesh of that UV sphere at voxel size 0.2 measured 536 vertices and 534 polygons, and a quadriflow remesh of it at default settings measured 3964 vertices and 3962 polygons. Properties read or set with the values stated in the Workflow: on `tool_settings.sculpt`, use_symmetry_x, use_symmetry_y, use_symmetry_z, lock_x, lock_y, lock_z, use_deform_only, detail_size, detail_percent, constant_detail_resolution, detail_type_method, detail_refine_method, and unified_paint_settings with use_unified_size, use_unified_strength, size, and strength; on the active brush, size, strength, hardness, auto_smooth_factor, spacing, stroke_method, direction, falloff_shape, sculpt_brush_type, use_pressure_size, use_pressure_strength, use_frontface, use_accumulate, and use_automasking_topology; on the object, use_dynamic_topology_sculpting; on the mesh, remesh_mode, remesh_voxel_size, remesh_voxel_adaptivity, use_remesh_preserve_volume, and use_remesh_preserve_attributes; on a Multiresolution modifier, levels, sculpt_levels, render_levels, total_levels, and quality. The sculpt_brush_type enum was read in full and setting it was tested by switching a brush to CLAY_STRIPS. The checker fixture run in the Operating Rules section returned objects_total: 2, mesh_objects: 2, vertices_total: 644, polygons_total: 832, multires_modifiers: 1 with total_levels 2, dyntopo_objects: 1, and verdict: PASS, on two separate audit runs with identical output. Probes that failed, with the fix applied in this skill: `bpy.ops.object.multires_add` exists in the operator list but calling it failed, so multires modifiers are added with `bpy.ops.object.modifier_add(type='MULTIRES')` instead; `bpy.ops.paint.mask_flood_fill`, `bpy.ops.sculpt.mask_filter`, `bpy.ops.sculpt.face_sets_init`, and `bpy.ops.sculpt.symmetrize` each crashed the headless process (exit 139), so none of them is used or scripted here and mask work is taught through the MASK brush type only; `bpy.ops.sculpt.detail_flood_fill` failed its poll check headless and `bpy.ops.object.multires_unsubdivide` errored on a freshly subdivided sphere, so neither is named in the Workflow; `bpy.ops.object.multires_reshape` requires a second selected mesh object and is out of scope. Names that do not exist in 5.1.1 and are not used here: brush.curve_preset, brush.autosmooth_factor (the real name is auto_smooth_factor), sculpt.use_dynamic_topology_sculpting (the flag lives on the object), and sculpt.constant_detail (the real name is constant_detail_resolution). What was NOT verified: no hand drawn stroke was run and no stylus was used, so tablet pressure feel and stroke results in a live session are untested, and the pressure properties above were only read and set; GUI-only panels, menus, and the brush asset shelf were not exercised headless, so panel locations in a live session may differ from the data names used here; face sets, mask flood and filter operations, and symmetrize are unverified for the crash reason above; no render, no material, and no rigged or posed mesh was tested.

## Workflow

1. Start from a clean base mesh and save a pre-sculpt copy.
   - Use a simple, closed, evenly spread base: a UV sphere, an icosphere, a cube with enough subdivision to bend, or an existing rough mesh built for this purpose. Thin walls, holes, and poles packed into one small area all fight the brushes later, so fix them before sculpting starts.
   - Reference sizes from the probe runs: `bpy.ops.mesh.primitive_uv_sphere_add(segments=32, ring_count=16, radius=1.0)` gives 482 vertices and 512 polygons, a good low base. `bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=3, radius=1.0)` gives 162 vertices and 320 polygons with no poles, which suits organic blobs. `bpy.ops.mesh.primitive_cube_add(size=2.0)` gives the hard surface starting point.
   - Apply scale and rotation on the base before sculpting. Brush size, voxel size, and DynTopo detail are all measured in scene units or screen space, and a scaled object makes every one of those numbers lie.
   - Save the untouched base as its own file or its own object copy with `bpy.ops.wm.save_as_mainfile`. Every detail strategy in step 7 can destroy base topology, and the base is the only clean way back.

2. Enter sculpt mode on one object and confirm the state.
   - Select the mesh, make it active, and enter sculpt mode: in the interface from the mode menu, in code with `bpy.ops.object.mode_set(mode='SCULPT')`. Read the mode back from the object before trusting it. Sculpting applies to the active object only, so a scene with several meshes is sculpted one object at a time.
   - Shade the base smooth if the form is organic, with `bpy.ops.object.shade_smooth` in object mode. Flat shading hides form errors that smooth shading shows at once.
   - Check the object has no live mirror or subdivision modifier doing hidden work. A multires modifier from step 7 is the one planned exception. Anything else that changes the surface while sculpting makes stroke results hard to read.
   - Leave sculpt mode the same way, with mode OBJECT, whenever a step needs object level operations such as remeshing or adding a modifier. Several operators in step 7 poll fail or misbehave in the wrong mode, so the mode change is part of the step, not an afterthought.

3. Set symmetry and axis locks before the first stroke.
   - Turn on mirroring for the axes the form is symmetric across: `tool_settings.sculpt.use_symmetry_x`, `use_symmetry_y`, and `use_symmetry_z`. X starts on by default in a factory scene, Y and Z start off. Symmetry set late cannot repair form built lopsided early without rework.
   - Symmetry here mirrors strokes across the object origin planes. The object origin has to sit on the symmetry plane of the form, or every mirrored stroke lands offset. Move the origin first if it sits off center.
   - Use the axis locks, `tool_settings.sculpt.lock_x`, `lock_y`, and `lock_z`, when a stroke must not move vertices along one axis, for example flattening a back or a sole without narrowing the form.
   - Turn on `tool_settings.sculpt.use_deform_only` when a pass should move existing vertices without adding or removing any, such as a late smoothing pass on a dyntopo mesh where new tessellation would change the detail budget.
   - Record the symmetry axes in the session notes. A later pass with different symmetry is a common source of quiet form damage, and the audit in the Operating Rules prints the saved axes so they can be checked instead of remembered.

4. Choose the brush by type, then set the settings that matter.
   - Brushes in 5.1.1 are picked by their `sculpt_brush_type` value on the brush data. The full enum read in the probe run: DRAW, DRAW_SHARP, CLAY, CLAY_STRIPS, CLAY_THUMB, LAYER, INFLATE, BLOB, CREASE, SMOOTH, PLANE, MULTIPLANE_SCRAPE, PINCH, GRAB, ELASTIC_DEFORM, SNAKE_HOOK, THUMB, POSE, NUDGE, ROTATE, TOPOLOGY, BOUNDARY, CLOTH, SIMPLIFY, MASK, DRAW_FACE_SETS, DISPLACEMENT_ERASER, DISPLACEMENT_SMEAR, PAINT, SMEAR, and BLUR. Work with a small set first: GRAB to move masses, CLAY and CLAY_STRIPS to build volume, DRAW to add or cut soft form, INFLATE to swell, CREASE and PINCH to sharpen edges, PLANE to flatten, and SMOOTH to finish.
   - Radius first: brush `size`, in pixels on screen. Big form wants a brush near the size of the mass being moved. Detail wants a brush near the size of the feature. Working a whole form with a small brush makes lumpy, stroked surfaces that no amount of smoothing fully repairs.
   - Strength second: brush `strength`, 0.0 to 1.0. Low strength with several light strokes builds form that can be stopped at the right point. Full strength settles a shape in one stroke and overshoots just as fast. Default Draw strength in a factory scene is 0.5.
   - Direction: brush `direction`, ADD or SUBTRACT. The same DRAW brush adds material on ADD and carves on SUBTRACT. Most brushes have a natural direction, and flipping it is faster than swapping brushes for a cut.
   - Hardness and autosmooth: brush `hardness` firms the edge of the brush falloff, and `auto_smooth_factor` blends each stroke into the surface under it. Autosmooth above zero softens stroke borders as you work and costs some sharpness. Keep it low or off while blocking, raise it for blending passes.
   - Stroke spacing: brush `stroke_method`, SPACE by default, with `spacing` as a percent of brush size (10 in a factory scene). Wide spacing leaves a dotted trail on fast strokes. Tight spacing costs performance on dense meshes.
   - Pressure, when a stylus is in use: `use_pressure_size` and `use_pressure_strength` on the brush decide whether pen pressure drives radius and strength. The factory Draw brush has use_pressure_strength on and use_pressure_size off. These flags were read and set in the probe runs. Their feel on real hardware was not tested, per the verification note.
   - Unified settings: `tool_settings.sculpt.unified_paint_settings` holds `size` and `strength` shared across brushes when `use_unified_size` and `use_unified_strength` are on. Unified size starts on and unified strength starts off in a factory scene. Turn both on when switching brushes often, so a size tuned for one brush is still there on the next.

5. Set the falloff before blaming the brush.
   - Falloff shape: brush `falloff_shape`, SPHERE or PROJECTED. SPHERE applies the brush in a ball around the cursor and reaches into curved and partly hidden surface. PROJECTED applies it flat from the view direction and gives cleaner control on the face of a form facing the camera.
   - Strength curve: the brush data carries a strength curve as `curve_strength` and a size curve as `curve_size`, both curve mapping data. A curve that stays high then drops fast gives a firm center and a clear edge. A curve that falls from the center gives soft, blended strokes. When a brush feels weak at the center or harsh at the edge, the curve is the cause more often than strength.
   - Front faces only: brush `use_frontface` limits a stroke to faces pointing at the view. Turn it on when working thin forms, ears, or cloth-like shapes, so the back side does not move with the front.
   - Accumulate: brush `use_accumulate` lets repeated strokes in one drag keep building past the single stroke limit on brushes that support it. Leave it off while learning a form, because overshoot arrives with no clear stroke to blame.
   - Change one falloff setting at a time and test on a plain area of the mesh. Changing size, strength, hardness, and curve together produces a brush whose behavior nobody can predict or repeat.

6. Block out the large form at low detail.
   - Work in passes over the whole object, not in finished corners. Pass one places the masses with GRAB at a large radius and low strength. Pass two sets the main planes with CLAY, PLANE, and DRAW on SUBTRACT. Only after the silhouette reads from every side does any area get local detail.
   - Check the silhouette in object mode and from fixed views often. Sculpt mode encourages close work, and close work hides a wrong proportion until the detail pass has made it expensive to change.
   - Keep the vertex count low in this stage on purpose. A base of a few hundred to a few thousand vertices bends cleanly under GRAB and POSE work. Density added now is density that fights every large move later.
   - Stop blocking when three things hold: the silhouette matches the reference or intent from front, side, and top; no mass is missing; and no area carries detail finer than its neighbors by more than one pass. Then pick the detail strategy in step 7.

7. Pick one detail strategy: DynTopo, voxel remesh, or multires.
   - The three strategies answer the same need, more resolution where detail goes, in three different ways. They combine badly when stacked without a plan: DynTopo on a multires mesh fights the modifier, and a voxel remesh erases multires levels. Choose per object, write the choice in the session notes, and change strategy only at a saved checkpoint.
   - DynTopo, dynamic topology: enter sculpt mode and toggle it with `bpy.ops.sculpt.dynamic_topology_toggle()`. Read the state from `use_dynamic_topology_sculpting` on the object, not on the tool settings, because in 5.1.1 the flag lives on the object. DynTopo subdivides and collapses triangles under the brush as you work, so detail can start anywhere with no base density planning. Save while the object is still in sculpt mode when this state matters: the checker fixture showed the flag and the active brush read back clean on reopen only when the file was saved in sculpt mode.
   - DynTopo detail sizing: `tool_settings.sculpt.detail_type_method` takes RELATIVE, CONSTANT, BRUSH, and MANUAL. RELATIVE sizes detail in screen pixels with `detail_size`, 12.0 in a factory scene, so zooming in gives finer detail. CONSTANT fixes detail in scene units with `constant_detail_resolution`, set to 4.0 in the checker fixture, so detail stays even at any zoom. BRUSH sizes detail from the brush with `detail_percent`, 25.0 in a factory scene. CONSTANT suits a form that needs even skin or scale detail. RELATIVE suits exploratory work where close areas earn detail first.
   - DynTopo refine method: `tool_settings.sculpt.detail_refine_method` takes SUBDIVIDE, COLLAPSE, and SUBDIVIDE_COLLAPSE, the factory default. SUBDIVIDE_COLLAPSE adds detail where strokes need it and removes it where the surface is plain. COLLAPSE alone is the cleanup setting for a mesh that grew too dense. `bpy.ops.sculpt.optimize()` rebalances a dyntopo mesh without a stroke and returned FINISHED in the probe run with DynTopo on.
   - Voxel remesh: in object mode, set `remesh_voxel_size` and `remesh_voxel_adaptivity` on the mesh data, then call `bpy.ops.object.voxel_remesh()`. The remesh rebuilds the whole surface as an even grid of quads at the voxel size, joins separate shells that overlap, and erases poles and stretched faces. Probe numbers: the 482 vertex UV sphere at voxel size 0.2 came back with 536 vertices and 534 polygons. Smaller voxels hold finer detail and cost far more vertices, so halve the voxel size in steps and check the count each time.
   - Voxel remesh preservation: `use_remesh_preserve_volume` on the mesh, on by default, keeps the overall volume through the rebuild. `use_remesh_preserve_attributes` keeps mesh attributes where the rebuild can carry them. Neither preserves a pose built from careful topology, because the topology itself is replaced. Remesh is the standard reset between blocking and detail: block with DynTopo or by hand, remesh once at a voxel size that holds the blocked form, then detail on the clean surface.
   - Quad remesh: the mesh `remesh_mode` property takes VOXEL and QUAD. For the QUAD path, `bpy.ops.object.quadriflow_remesh()` rebuilt the probe sphere at default settings into 3964 vertices and 3962 polygons. It is slower than the voxel path and aims for flow that follows the form. Use it when the sculpt is nearly done and the result will be used with light cleanup rather than a full retopology pass.
   - Multires: in object mode, add the modifier with `bpy.ops.object.modifier_add(type='MULTIRES')`. In 5.1.1 the older `bpy.ops.object.multires_add` call fails, per the verification note. Subdivide with `bpy.ops.object.multires_subdivide(modifier=mod.name)`, once per level. Each call raised total_levels by one in the probe runs, to 2 after two calls.
   - Multires levels: the modifier carries `levels` for the viewport, `sculpt_levels` for sculpt mode, `render_levels` for renders, and `total_levels` for the levels that exist. The checker fixture holds levels 2, sculpt_levels 1, render_levels 2, and total_levels 2 on one object, which is the working pattern: sculpt large moves at a low sculpt level, raise the level for finer detail, and lower it again when a big proportion fix appears late. Multires keeps the low base intact under the detail, which makes it the only one of the three strategies that can step detail down without a remesh.
   - Multires cautions: strokes at a high level bake into that level, and large edits at a low level move all levels above them. Keep the base mesh clean, because multires detail sits on it. `bpy.ops.object.multires_base_apply(modifier=mod.name)` applies the lowest level shape into the base mesh and returned FINISHED in the probe run with the vertex count unchanged at 482. Treat it as a checkpoint operation: save first, apply, then check the form.

8. Mask finished areas before working near them.
   - Switch a brush to the MASK value of `sculpt_brush_type` and paint the areas that must not move: a finished face while the head around it changes, a hard edge while the surface next to it gets smoothed, fingers while the palm is reshaped. Painted mask protects vertices from brush deformation.
   - Build the mask with a large soft brush at partial coverage first, then firm it up. A mask edge that is too sharp prints a visible step into the next stroke that crosses it.
   - Mask state in 5.1.1 headless runs has a hard limit, stated in the verification note: the flood fill and filter operators for masks crashed the drafting machine's headless Blender, so this skill does not script mask clearing, inverting, or filtering, and does not promise their behavior. Do those operations in a live session and check the result on screen.
   - Brush automasking is a separate, lighter tool: the brush data carries options such as `use_automasking_topology`, read as off on the factory Draw brush. Topology automasking keeps a stroke from crossing to disconnected surface under the brush, which protects nearby shells without painting a mask at all.
   - Check the mask before a big pass, not after. A stroke over an area that was meant to be protected is visible damage, and with DynTopo on it also changes the tessellation there.

9. Review the form outside sculpt mode and save in versions.
   - Return to object mode, orbit the whole form at a distance, and read it as silhouette and planes only. Note the two or three largest form errors and fix those next, at a low level or a large brush size, before any new detail pass.
   - Compare vertex and polygon counts against the last checkpoint. A count that jumped with no matching gain in form means the detail settings in step 7 are too fine for the current pass. Counts come from the mesh data or from the audit script, not from a guess at how dense the surface looks.
   - Save numbered versions at each stage boundary: blocked, remeshed, detailed, final. Use `bpy.ops.wm.save_as_mainfile` with a new file name each time. Sculpting has no reliable undo across sessions, and versioned files are the recovery path.
   - Run the audit from the Operating Rules on the saved file before calling a stage done. The audit prints per object counts, multires levels, the dyntopo flag per object, symmetry axes, the detail method, and the unified brush settings, all read from the file itself.

10. Stop sculpting and hand off at the right point.
   - Stop when the form reads correctly at viewing distance, surface detail is even for its purpose, and the remaining problems are problems of topology, UV layout, or deformation rather than shape. More brush time past that point polishes a mesh that the next stage will rebuild anyway.
   - Hand off to retopology when the sculpt came from DynTopo or voxel remesh and the mesh will deform, be UV unwrapped, or carry fine painted detail. Sculpt output from those strategies has even but directionless flow, and that flow is the retopology stage's whole reason to exist.
   - Hand off to uv-unwrapping-basics after retopology, or directly when the sculpt was built on a clean base with multires and the base topology already flows well enough to unwrap.
   - Hand off to blender-rigging-basics when the form is final and the mesh, multires included or applied at a stated level, is the shape the rig will deform. State the sculpt level or remesh state in the handoff, because a rig built on level 1 proportions and rendered at level 3 can drift.
   - Hand off to blender-material-shaders only after UVs exist. Shader work on a sculpt with no UV plan wastes the material pass on a surface that will be rebuilt.
   - Freeze the sculpt as delivered: one saved file, named as the final sculpt, with the audit output from step 9 kept with it. Any later change starts from that file and produces a new version, so the handed off state can always be recovered.

## Output Contract

Deliver these items, in this order:

1. Final sculpt file: the saved .blend holding the finished form, named as the final sculpt, with the object or objects that carry the sculpt and no test objects left in the scene.
2. Stage record: one short record per stage boundary (blocked, strategy start, remesh or level change, detailed, final), with the file name saved at that boundary and the vertex and polygon counts read from the mesh data at that point.
3. Checker output: the full output of sculpt_audit.py for the final file. On the worked fixture in the Operating Rules section the headline numbers are: objects_total: 2, mesh_objects: 2, vertices_total: 644, polygons_total: 832, multires_modifiers: 1, dyntopo_objects: 1, verdict: PASS.
4. Sculpt settings record: the symmetry axes used, the detail strategy chosen per object, and for that strategy the working settings: DynTopo detail_type_method with its detail_size, constant_detail_resolution, or detail_percent, plus detail_refine_method; or the voxel size and adaptivity used at each remesh; or the multires levels, sculpt_levels, render_levels, and total_levels.
5. Brush record: the brush types used for blocking, detail, and finishing, with the unified paint settings state (use_unified_size, unified size, use_unified_strength, unified strength) as printed by the audit, and any falloff_shape or hardness changes made from factory values.
6. Handoff note: the next stage by name (retopology, uv-unwrapping-basics, blender-rigging-basics, or blender-material-shaders), the mesh state it receives, and the one thing that stage must know about the sculpt, such as a protected area, a thin region, or a level the form was approved at.
7. Limits: anything the sculpt did not cover, stated plainly (for example an area left blocked rather than detailed, a mask operation that could only be checked in a live session, or pressure feel on the stylus used).

## Operating Rules

1. One detail strategy per object at a time. DynTopo, voxel remesh, and multires each own the resolution story while they are active, and switching strategy happens at a saved checkpoint with the switch written in the stage record.
2. Symmetry and the detail strategy are set before detail work, never during it. A change to either one mid pass is a stage boundary: save, change, record, then continue.
3. Every number in the deliverable comes from the mesh data, the modifier data, the tool settings, or the audit output. Vertex counts, polygon counts, levels, and voxel sizes are read, not estimated from how dense a surface looks.
4. Large form before fine detail, always. A proportion error found during a detail pass sends the work back to a low multires level, a large brush, or a remesh, rather than being corrected with detail sized strokes.
5. The base mesh and every stage version stay saved and untouched once written. Recovery comes from versioned files, not from undo history or from rebuilding a stage from memory.
6. Mask before a risky pass near finished work. An unmasked smoothing or grab pass beside a finished area is how finished areas stop being finished.
7. Operators that failed probe checks stay out of the work. The failed list in the verification note is binding for scripted steps: mask flood and filter work, face sets, and symmetrize are live session operations here, checked on screen, until a probe run on the current build passes.
8. Use the checker below for the state checks. Save it as sculpt_audit.py, run it inside Blender as its header describes, and put its full output in the deliverable as item 3 of the Output Contract. Report numbers from its output, not from the viewport.

### Sculpt audit (sculpt_audit.py)

Run: `~/.local/bin/blender -b --factory-startup --python sculpt_audit.py -- --make-fixture sculpt_fixture.blend` builds the worked fixture blend file. Then run: `~/.local/bin/blender -b --factory-startup --python sculpt_audit.py -- sculpt_fixture.blend` to reproduce the output below. Run it on a real sculpt with `~/.local/bin/blender -b --factory-startup --python sculpt_audit.py -- FILE.blend`. Blender prints its own banner and a read line before the script output. The block below is the script output only.

Expected output for the fixture run:

```text
fixture_file: sculpt_fixture.blend
objects_total: 2
mesh_objects: 2
OBJECT DynoBall verts=162 polys=320 modifiers=0 dyntopo=True
OBJECT SculptTarget verts=482 polys=512 modifiers=1 dyntopo=False
MULTIRES object=SculptTarget levels=2 sculpt_levels=1 render_levels=2 total_levels=2
vertices_total: 644
polygons_total: 832
multires_modifiers: 1
dyntopo_objects: 1
symmetry_x: True
symmetry_y: False
symmetry_z: False
detail_type_method: CONSTANT
constant_detail_resolution: 4.0
detail_refine_method: SUBDIVIDE_COLLAPSE
brush_name: Draw
brush_type: DRAW
use_unified_size: True
unified_size: 120
use_unified_strength: True
unified_strength: 0.70
verdict: PASS
```

The fixture is built to show each audit result once: two mesh objects, one carrying a Multiresolution modifier subdivided twice with sculpt_levels lowered to 1, and one with dynamic topology on, saved while still in sculpt mode so the flag and the active Draw brush read back on reopen. X symmetry is on, the detail method is CONSTANT at resolution 4.0, and unified size and strength are both on at 120 and 0.70, which gives vertices_total: 644, polygons_total: 832, and a verdict of PASS.

sculpt_audit.py (runs inside Blender, uses bpy). Save this code as sculpt_audit.py:

```python
#!/usr/bin/env python3
"""Audit sculpt-relevant state in a Blender scene.

This script runs inside Blender, not in plain Python:

  blender -b --factory-startup --python sculpt_audit.py -- --make-fixture sculpt_fixture.blend
  blender -b --factory-startup --python sculpt_audit.py -- sculpt_fixture.blend

The --make-fixture form builds a small fixture blend file holding
two mesh objects: SculptTarget, a UV sphere with a Multiresolution
modifier subdivided twice with sculpt_levels lowered to 1, and
DynoBall, an icosphere with dynamic topology enabled, constant
detail at resolution 4.0, X symmetry on, and unified paint
settings at size 120 and strength 0.70 with both unified flags
on. It saves that scene while DynoBall is
still in sculpt mode, which is what keeps the dynamic topology
flag and the active brush readable on reopen, and prints two
fixture lines.

The audit form opens the blend file named after the -- separator,
then prints one line per mesh object sorted by name, one line per
Multiresolution modifier, the saved sculpt tool settings, and
summary counts. The verdict is PASS when the scene holds exactly
the fixture shape: two mesh objects, one Multiresolution modifier
with total_levels 2, and one dynamic topology object. Any other
shape prints REVIEW. Blender prints its own banner lines before
the script output; the lines below are the script output only.
"""
import sys

import bpy


def build_fixture(path):
    bpy.ops.wm.read_factory_settings(use_empty=True)
    bpy.ops.mesh.primitive_uv_sphere_add(segments=32, ring_count=16, radius=1.0)
    target = bpy.context.active_object
    target.name = "SculptTarget"
    bpy.ops.object.modifier_add(type='MULTIRES')
    mod = target.modifiers[-1]
    bpy.ops.object.multires_subdivide(modifier=mod.name)
    bpy.ops.object.multires_subdivide(modifier=mod.name)
    mod.sculpt_levels = 1
    bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=3, radius=1.0)
    dyno = bpy.context.active_object
    dyno.name = "DynoBall"
    bpy.ops.object.mode_set(mode='SCULPT')
    bpy.ops.sculpt.dynamic_topology_toggle()
    sculpt = bpy.context.tool_settings.sculpt
    sculpt.detail_type_method = 'CONSTANT'
    sculpt.constant_detail_resolution = 4.0
    sculpt.detail_refine_method = 'SUBDIVIDE_COLLAPSE'
    sculpt.use_symmetry_x = True
    unified = sculpt.unified_paint_settings
    unified.use_unified_size = True
    unified.size = 120
    unified.use_unified_strength = True
    unified.strength = 0.7
    bpy.ops.wm.save_as_mainfile(filepath=path)
    print(f"fixture_file: {path}")
    print("fixture_objects: 2")
    return 0


def audit(path):
    bpy.ops.wm.open_mainfile(filepath=path)
    meshes = sorted(
        (ob for ob in bpy.data.objects if ob.type == 'MESH'),
        key=lambda ob: ob.name,
    )
    sculpt = bpy.context.tool_settings.sculpt
    brush = sculpt.brush
    print(f"fixture_file: {path}")
    print(f"objects_total: {len(bpy.data.objects)}")
    print(f"mesh_objects: {len(meshes)}")
    verts_total = 0
    polys_total = 0
    dyntopo_objects = 0
    multires_rows = []
    for ob in meshes:
        verts = len(ob.data.vertices)
        polys = len(ob.data.polygons)
        verts_total += verts
        polys_total += polys
        if ob.use_dynamic_topology_sculpting:
            dyntopo_objects += 1
        print(
            f"OBJECT {ob.name} verts={verts} polys={polys} "
            f"modifiers={len(ob.modifiers)} dyntopo={ob.use_dynamic_topology_sculpting}"
        )
        for mod in ob.modifiers:
            if mod.type == 'MULTIRES':
                multires_rows.append((ob.name, mod))
    for name, mod in multires_rows:
        print(
            f"MULTIRES object={name} levels={mod.levels} "
            f"sculpt_levels={mod.sculpt_levels} render_levels={mod.render_levels} "
            f"total_levels={mod.total_levels}"
        )
    print(f"vertices_total: {verts_total}")
    print(f"polygons_total: {polys_total}")
    print(f"multires_modifiers: {len(multires_rows)}")
    print(f"dyntopo_objects: {dyntopo_objects}")
    print(f"symmetry_x: {sculpt.use_symmetry_x}")
    print(f"symmetry_y: {sculpt.use_symmetry_y}")
    print(f"symmetry_z: {sculpt.use_symmetry_z}")
    print(f"detail_type_method: {sculpt.detail_type_method}")
    print(f"constant_detail_resolution: {sculpt.constant_detail_resolution:.1f}")
    print(f"detail_refine_method: {sculpt.detail_refine_method}")
    unified = sculpt.unified_paint_settings
    print(f"brush_name: {brush.name if brush else '-'}")
    print(f"brush_type: {brush.sculpt_brush_type if brush else '-'}")
    print(f"use_unified_size: {unified.use_unified_size}")
    print(f"unified_size: {unified.size}")
    print(f"use_unified_strength: {unified.use_unified_strength}")
    print(f"unified_strength: {unified.strength:.2f}")
    ok = (
        len(meshes) == 2
        and len(multires_rows) == 1
        and multires_rows[0][1].total_levels == 2
        and dyntopo_objects == 1
    )
    print(f"verdict: {'PASS' if ok else 'REVIEW'}")
    return 0


def main():
    args = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
    if len(args) == 2 and args[0] == "--make-fixture":
        return build_fixture(args[1])
    if len(args) == 1:
        return audit(args[0])
    print("usage: sculpt_audit.py -- [--make-fixture FILE.blend | FILE.blend]")
    return 2


if __name__ == "__main__":
    raise SystemExit(main())
```
