| mpfb_add_assetA | Equip a MakeHuman character with one mesh asset from an MHCLO - a
garment, a body part (hair, eyes, eyebrows, eyelashes, teeth, tongue)
or the body proxy. Rig the character before dressing it: MPFB rigs a garment only if a
rig is present when the garment is attached, and nothing rigs it
retroactively. The asset is attached either way, and rigged_to names
the armature or is null with parented_to naming the basemesh. object_type is required, and is exactly what
mpfb_list_assets reports for the entry: Clothes, Proxymeshes,
Eyes, Eyebrows, Eyelashes, Hair, Teeth or Tongue. MPFB's
own function defaults it to "Clothes", which mislabels a body part
silently and permanently, so there is no default here;
object_type_recorded echoes what was stored.
Name the asset with either path or fragment, never both;
mpfb_list_assets reports both. A fragment ("fedora/fedora.mhclo")
is portable but is resolved by basename, so two packs shipping
hat.mhclo resolve to a coin toss - check resolved_path when
path_resolved_by is "fragment". material_type is MAKESKIN, GAMEENGINE, PROCEDURAL_EYES or
NONE, and is best left unset: it then follows MPFB's settings panel
per asset type - NONE for Proxymeshes, MAKESKIN for everything
else - and material_type_used reports the choice. PROCEDURAL_EYES
is accepted only for Eyes. NONE deletes the imported mesh's
materials and creates nothing, even when the MHCLO names one;
material_created and warnings say when that happened.
subdiv_levels (default 1, MPFB's own) sets the subdivision modifier's
render level, viewport level 0; 0 adds no modifier.
set_up_rigging, interpolate_weights, import_subrig and
import_weights are MPFB's own flags at MPFB's own defaults. Fitting
to the body and the delete group are unconditional, so neither has an
argument, and an alternative material is chosen afterwards with
mpfb_set_asset_material.
On added: true, result carries asset_object_name - read off the
created object, since Blender uniquifies a name already in use, and the
address mpfb_remove_asset and mpfb_set_asset_material need - plus
basemesh_name, resolved_path/path_resolved_by/asset_source,
object_type_recorded, material_type_used,
material_created/material_name, rigged_to or parented_to,
subrig_object_name, delete_group_name and
delete_group_applied_to, subdiv_modifier_added, warnings for what
MPFB only logs, and proxy_extras - the four things a Proxymeshes
asset gets from MPFB's .mhm loading path, which this follows rather
than its proxy library panel. Refusals come back as added: false (and so performed: false) with a
blocked_by and a sentence: subject_not_found, asset_not_found,
unknown_object_type (with known_object_types),
invalid_material_type, no_asset_subdir and not_object_mode. |
| mpfb_add_rigA | Attach a rig to an existing MakeHuman character - MPFB's "Add standard
rig" / "Add rigify rig" / "Add custom rig". Rig the character before dressing it. MPFB rigs a garment only if a
rig is present when the garment is attached, and nothing rigs it
retroactively. This tool does not refuse to rig a dressed character -
decorative garments are legitimate - but mesh_assets_not_rigged names
every asset it just failed to rig, and a non-empty list is a mistake
unless you meant it. identifier is exactly what mpfb_list_rigs reports in its
identifier field, never the name beside it and never a filename:
"default_no_toes" for a standard rig, "rigify.human" for a Rigify
one, "custom.my_rig" for a user one. The prefix selects which of
MPFB's two non-interchangeable adding functions runs, and
add_function_used says which was taken.
import_weights (default true, MPFB's own) loads the vertex weights
and adds the armature modifier. With it false the mesh is parented to
the armature but not deformed by it.
A rigify.* identifier produces a meta rig, not a finished rig.
is_metarig: true comes back with a next_step: attach the garments
first, then call mpfb_generate_rigify_rig. A meta rig deforms nothing
on its own. On added: true, result carries rig_object_name - read off the
created object, since Blender uniquifies a name already in use, and the
address other tools need for the rig - plus basemesh_name,
add_function_used, family, is_metarig/next_step,
weights_loaded with weights_from and weights_path (MPFB
resolves weights through a fallback table, so a rig legitimately
borrowing another's is normal and weights_loaded: false is not),
armature_modifier_added, basemesh_location_before with
basemesh_moved_to_origin and rig_location - both adding functions
move the basemesh to the origin and give the armature its old location,
which visibly moves a character standing anywhere else - and
mesh_assets_not_rigged / subrigs_not_rigged. Refusals come back as added: false (and so performed: false) with a
blocked_by and a sentence: subject_not_found, unknown_identifier
(with known_identifiers for the family you addressed),
rigify_unavailable, not_object_mode, and already_rigged - MPFB
cannot swap a rig, so an existing one has to be deleted first. |
| mpfb_apply_expressionsA | Put a MakeHuman character into saved expressions, through MPFB's
applied-expressions stack - the mechanism its expressions-library panel
and presets use, so the result survives mpfb_save_preset. expressions is a list of {fragment, weight}: fragment as
mpfb_list_expressions reports it, weight in 0.0-1.0. Weight 0.0
removes that expression. mode is "merge" (default: add or update
these rows, keep the rest) or "replace" (the stack becomes exactly
these rows) - replace with an empty list takes every expression
off. Weights from several rows add up per face unit and are clamped
at 1.0.
Nothing is written unless every fragment resolves; the refusal
(blocked_by: "unresolved_fragments") names the misses and the closest
existing fragments. It also refuses without the faceunits01 pack. The face is rebuilt from the stack, so units composed on top of it
with mpfb_set_face_units are discarded and named in
discarded_face_units - call mpfb_save_expression first to keep them.
refit (default true, as MPFB's library panel) refits the mesh assets and the rig. result carries changed (the stack or the face moved), requested
(per row: action of added / updated /
removed / unchanged / absent, and resolved_path), the resulting stack
and face as mpfb_get_expression reports them (applied_expressions,
aggregate, clamped_face_units, matches_stack), stack_before,
removed_by_replace and panel_synced (MPFB's library sliders updated).
|
| mpfb_create_humanA | Create a new MakeHuman character - a basemesh with a phenotype -
through MPFB's HumanService.create_human(). The starting point for
building a character: shape it further with mpfb_set_targets, rig it
with mpfb_add_rig before dressing it with mpfb_add_asset, and
give it a skin with mpfb_set_skin, without which it stays grey. The eleven macro sliders (gender, age, muscle, weight,
proportions, height, cupsize, firmness, race_asian,
race_caucasian, race_african) are 0.0-1.0 and are the same
sliders under the same names as mpfb_set_macro_details takes, so a
character can be created and then adjusted without relearning the
vocabulary. The two differ in what an omitted slider means: here every
one has a default and the character is built from the full set, while
there an omitted slider is left alone. Set the phenotype in this call
when you know it; use mpfb_set_macro_details to change one
afterwards. 0.5 is neutral for every slider except the three race weights, whose
neutral is 0.33 each. age runs 0.0 = baby, 0.1875 = child, 0.5 =
young adult, 1.0 = old; gender 0.0 = fully female, 1.0 = fully male.
The three race weights are independent and MPFB does not normalize
them, so the defaults sum to 0.99 and setting one to 1.0 does not
reduce the other two. scale is the basemesh scale factor (0.1 = decimeters, MPFB's own
default). Change it only deliberately: mpfb_set_skin's enhanced skin
types read it to pick subsurface radii.
create_human()'s own defaults are used for mask_helpers,
detailed_helpers, extra_vertex_groups and feet_on_ground; this
tool does not expose them.
On status: "ok", result carries basemesh_name - the address every
later tool needs, since Blender uniquifies a name already in use - plus vertex_count,
location and the macro_detail_dict that was applied, in MPFB's own
nested shape. performed is true: creation either succeeds or raises,
so this tool has no separate verb of its own. |
| mpfb_create_human_from_presetA | Build a new character from a saved MPFB preset: phenotype,
modeling targets, rig, body parts, garments, skin and eye materials. It adds
a character and changes nothing already in the scene - this is not
"load into the current character". Seconds, not milliseconds: it
imports and fits every asset the preset names. preset_name is a name, never a path - mpfb_list_presets reports the
ones that exist, and a miss here comes back with available_presets
naming them.
Each override defaults to null meaning use what the preset says;
overrides in the response reports, per argument, what you asked for,
what the preset held and what was used. override_rig: "NONE" for no rig, or any identifier
mpfb_list_rigs reports, custom.* included. A rigify.* preset
gives you a meta rig - finish it with
mpfb_generate_rigify_rig.
override_skin_type: mpfb_set_skin's five skin_type values,
plus "NONE" for no skin at all.
override_clothes_material_type / override_eyes_material_type:
mpfb_add_asset's material_type, for garments and every body
part but the eyes, and for the eyes.
load_clothes false builds the body and skips the garments.
scale: 0.1 metre (MPFB's default), 1.0 decimetre, 10.0
centimetre.
material_instances_policy: NEVER, ENHANCED or ENHANCEDMS -
which skin types get per-region material slots. Defaults to
ENHANCED, which is MPFB's preset panel's default rather than the
NEVER its service function defaults to; both come back, as
material_instances_policy_used and _service_default.
On created: true (and so performed: true), result carries
basemesh_name, rig_object_name and rig_identified_as,
equipped_assets (kind, name and asset_source per item),
skin_material_identified_as, settings_used (MPFB's own settings
dict, in MPFB's own key names), objects_created and
active_object_after - the selection is not restored, because
deserialization activates what it creates and there is no prior state
to return to. Read unresolved_assets. A preset that names a garment or body
part which is not installed here loads without it and MPFB says
nothing; that field names each one and the subdirectory it was looked
for in. Refusals come back as created: false with a blocked_by:
preset_not_found (with available_presets), preset_unreadable,
not_object_mode, unknown_material_instances_policy,
config_dir_missing,
settings_incomplete, and deserialization_failed - the one that is
not a no-op, since a character is built in stages, so
objects_created names what was left behind. Its commonest cause is a
rig the preset names and this Blender lacks: MPFB's rig adders raise
rather than degrade, so retry with override_rig. |
| mpfb_generate_rigify_rigA | Turn a character's Rigify meta rig into a generated, poseable
Rigify rig - the second step of the two mpfb_add_rig starts when
given a rigify.* identifier. Attach the character's garments and other mesh assets before calling
this. Generation re-parents and re-weights whatever is on the
character at the moment it runs, and nothing handles an asset added
afterwards. mesh_assets_present reports what was there. Unlike the other character tools, name resolves to the meta rig
rather than to the basemesh, and metarig_name says which armature was
used. generated_rig_name is a basename, not the final object name:
omit it for MPFB's own fallback, which derives a unique name from the
meta rig's, and read rig_object_name for what it became. meta_rig_action (default "hide", MPFB's own) is what becomes of the
meta rig afterwards: "keep" leaves it visible, "hide" keeps it in
the scene but out of viewport and renders, "delete" removes it.
Prefer "hide". Deleting the meta rig makes the character
permanently unrefittable: mpfb_refit_human can only refit a generated
Rigify rig through its meta rig, and with none in the scene it refits
the mesh assets, leaves the rig behind and says nothing.
refit_will_be_possible reports this either way.
This tool is not undoable and cannot restore your selection.
Generation's own last act is to select and activate the rig it made, so
active_object_after reports what is active now instead. On generated: true, result carries rig_object_name,
metarig_name, metarig_disposition (kept/hidden/deleted),
refit_will_be_possible, mesh_assets_present and
active_object_after. generated: false does not mean nothing happened, though
performed follows it. When Rigify judges the meta rig invalid it
returns after MPFB has already deselected everything, activated the
meta rig and possibly renamed it or run Rigify's face upgrade; that
case reports metarig_renamed and metarig_name_after beside the
refusal. Other refusals carry a blocked_by: subject_not_found,
no_armature_found, not_a_metarig (rigged, but not with a Rigify
meta rig), already_generated (generation moved this character onto
its generated rig, so its meta rig is no longer among its relatives),
rigify_unavailable and not_object_mode.
|
| mpfb_get_character_summaryA | Summarize one MakeHuman character before changing it, in one call:
what it is, what it wears, and what its face is doing. Changes
nothing. Call this first; call a detailed tool only for what the
summary leaves out. result carries one section per detailed tool: a subset of its
fields under the same names, read by the same code, so the two never
disagree.
phenotype - mpfb_get_macro_details.
rig - mpfb_get_object_info on the rig; null when there is
none. rigify_role says whether it is a meta rig or generated.
equipped_assets - mpfb_get_object_info's related objects: every
equipped garment, body part and body proxy, by type then name. Not
capped.
skin - mpfb_get_object_info on the basemesh.
targets - mpfb_get_target_stack with its defaults: the
modifiers rollup, asymmetries and the counts. Capped: if
rollup_truncated, only the largest entries are here, and
modifier_count/asymmetry_count give the whole.
face - mpfb_get_face_units (non-zero units only) and
mpfb_get_expression (applied_expressions, matches_stack,
unexplained_face_units). A non-empty unexplained_face_units is
composed work the next mpfb_apply_expressions call destroys.
On a miss found is false and every section is null or empty. |
| mpfb_get_expressionA | Read which saved expressions a MakeHuman character is wearing (MPFB's
applied-expressions stack) and whether they explain its live face.
Changes nothing. For the raw live face-unit values, call
mpfb_get_face_units; this tool reports only how they differ from the
stack. result's applied_expressions is one row per expression: fragment,
weight, resolved and path. A row whose file cannot be found or
read (resolved: false, counted in unresolved_count) contributes
nothing to the face. aggregate is the face the stack produces;
clamped_face_units names units whose sum across rows passed 1.0.
matches_stack is false when the live face differs from
aggregate; unexplained_face_units then lists each such unit with
its live and from_stack values. That is composed work (see
mpfb_set_face_units) that the next mpfb_apply_expressions call or
preset load will overwrite; mpfb_save_expression keeps it.
faceunits01_installed is always present; refresh re-probes for it.
An unresolvable subject is found: false, not an error;
basemesh_name names the object actually read.
|
| mpfb_get_face_unitsA | Read the ARKit face units currently applied to a MakeHuman character's
face - the live !ex- shape key values mpfb_set_face_units writes.
Changes nothing. result's face_units is one entry per face unit: face_unit (the bare ARKit
name, e.g. "jawOpen"), value, and shapekey_present - whether a
real shape key backs this value or MPFB is reporting a default for a
unit that has never been touched. Defaults to the non-zero units only;
include_zero (default false) returns all 52.
known_face_units is always present regardless of whether a
subject resolves: every legal name mpfb_set_face_units will accept,
grouped by facial region (brow, eye, cheek, jaw, mouth, nose, tongue)
the way MPFB's own composer panel lays out its sliders.
faceunits01_installed is always present too, and is the one
thing that separates "a neutral face" from "the faceunits01 asset pack
was never installed" - both read as every unit at 0.0, and MPFB
itself gives no other way to tell them apart. That check is cached for
the Blender session; refresh (default false) busts the cache, which
matters if the pack was installed after this Blender started.
A subject that cannot be resolved to a basemesh is an answer, found: false with a sentence, not an error; basemesh_name names the object
the answer was actually read from. |
| mpfb_get_macro_detailsA | Read a MakeHuman character's macro details - its phenotype sliders:
gender, age, muscle, weight, proportions, height, cupsize, firmness and
the three race weights. Changes nothing. Call this before mpfb_set_macro_details: that tool leaves unnamed
sliders alone, so knowing the current values is what makes a relative
change ("a bit older") possible. An unresolvable name, nothing active,
or an object with no basemesh among its relatives each come back as
found: false with a message, not as an error. result carries:
macro_details: the current values in MPFB's own nested shape
(gender, age, ..., plus race holding asian, caucasian and
african). mpfb_set_macro_details returns the same shape but
takes its arguments flat: race.asian is set as race_asian.
default_macro_details: what MPFB considers neutral - every slider
0.5, every race weight 0.33.
race_sum and race_normalized: the three race weights are
independent 0.0-1.0 properties and MPFB does not normalize them.
The default sums to 0.99; setting race_asian to 1.0 and leaving
the others alone builds a character from weights summing to 1.66,
which is legal and probably not what was wanted.
macro_target_stack and macro_target_count: what those values
mean in target terms, each entry carrying the target_fragment
MPFB loads from disk and the shapekey_name it becomes. Neither
is a name any tool accepts as input; they explain the shape, they
do not address it.
current_macro_shapekeys: the macro shape keys actually on the
mesh now, under the names they are stored with - the same
vocabulary as macro_target_stack's shapekey_name, so the two
can be compared directly. If they disagree, the properties were
changed without a recalculation and mpfb_set_macro_details will
repair it. macro_drift is that comparison made for you, weights
included. current_macro_shapekeys_decoded is the same list in
MPFB's readable form, for reading rather than comparing.
has_shapekeys and is_human_project: a mesh tagged as a basemesh
but never built by MPFB reads back a full set of macro properties
that mean nothing. These two are how that is told apart.
basemesh_name, subject_name and subject_resolved_by ("name"
or "active").
|
| mpfb_get_material_settingsA | Read a MakeHuman character's procedural material settings - exactly
what mpfb_save_preset saves for them - for
mpfb_set_material_settings to change. Changes nothing. result has three sections: eyes (procedural eyes), skin (the
LAYERED skin) and color_adjustments (one record per mesh asset, for
the MakeSkin node on its Base Color). One that does not apply says
applies: false and a reason. section ("eyes", "skin" or
"color_adjustments") reads one and reports the others as null; a
full answer can pass 20 KB.
Per node - the eyes, each group in skin.groups (keyed color,
body, face, ... as the preset keys them), each colour adjustment -
keyed by MPFB's own socket names: settings: each value as the preset holds it, a float or a colour
as four scene-linear RGBA numbers. A write takes these as is.
srgb_hex: #rrggbb per colour socket, derived for reading only.
ranges: [min, max] where a float declares one, null for an
open end; values_outside_range names any value already outside.
linked: sockets driven by another node (from_node,
from_socket), which a write cannot change. Most layered region
colours are linked from the color group.
material_shared_with: other objects a write would change too.
A colour adjustment record also has object_name, object_type,
uuid (the preset's key) and node_name: diffuseIntensity, or on
an asset with an AO map aoMix, whose only writable socket is the AO
strength - MPFB saves that node, and the tint is out of reach. The
eyes never keep one. An unresolved subject is found: false. |
| mpfb_get_object_infoA | Identify one Blender object, say what MakeHuman asset it was made from,
and list what else belongs with it. Changes nothing, selects nothing. name is a Blender object name, typically one from
mpfb_list_objects. Omit it to ask about the currently active
object - what the user just created or clicked. Not resolving a
subject is a normal answer: found is false and message says whether
no such object exists or nothing is active.
result always carries found, subject_resolved_by ("name" or
"active") and message. When found is true it also carries:
name: the resolved object's name. Carry this forward rather than
re-deriving from the active object, which changes as the user
clicks.
in_current_scene: object names are unique across the whole
.blend, so a name can resolve to an object mpfb_list_objects does
not list. False here is not a contradiction between the two tools.
object_type (MPFB's type, or null for a plain Blender object),
blender_type, is_makehuman_object.
rigify_role: "generated_rig", "metarig", or null - reported
whatever the object's type, because MPFB tags the rig it generates
through Rigify as a Skeleton.
asset_info: what the object was made from, or null when it has no
MPFB type. Its keys depend on the object type - a skeleton has
no mhclo, so it has no mhclo_path key rather than a null one.
Skeleton/Subrig carry rig_identified_as and rig_definition_path; a
mesh asset (Clothes, Eyes, Hair, Proxymeshes, ...) carries
asset_source, mhclo_path, material_identified_as, material_source
and mhmat_path; a Basemesh carries the last three. An
unrecognized MakeHuman type gets an empty dict.
related_objects: the MakeHuman objects among this one's parents,
children and siblings - "what belongs with this character" - each
with the same fields plus its own asset_info, excluding the
subject. A flat list, not a tree; call this tool again on a name to
walk the structure.
other_related_objects: relatives carrying no MPFB type, each with
a rigify_role. This is where a Rigify rig built outside MPFB
shows up: it drives the character but appears in no other list this
server returns.
Reading asset_info correctly: every *_path is an absolute path or
null, while the *_source fields beside them are MPFB's short
fragments and are not paths. The pair keeps two situations apart -
a null fragment means nothing was recorded, a fragment with a null path
means the asset is recorded but is not installed under any asset root
this Blender can see. A null material_source on a mesh asset is
ordinary: the object uses the default material named inside its mhclo,
deliberately not resolved here. The *_identified_as values are read
off the object as it is now, while the *_source fragments
record what was loaded and are never rewritten when the object is
edited by hand; where they disagree, the identified value describes
reality. And mhclo_path may point at a .proxy file, so do not
decide what something is from the suffix. |
| mpfb_get_statusA | Report whether MPFB is loaded and usable in the connected Blender, and
how it is configured. Takes no arguments, changes nothing. Call this first when any other MPFB tool fails unexpectedly: those
tools fail with a bare error when MPFB is missing or broken, and this
one tells the two apart. result always carries:
state: "absent" (MPFB not loaded), "not_initialized" (loaded, but
registration did not complete - installed and broken, or
half-registered) or "ok". All three are normal answers, not errors.
message: one sentence naming the state and the likely next step,
suitable for showing to a user verbatim.
candidate_modules: every loaded module name ending in "mpfb".
Normally one; two or more means MPFB is installed twice, which
explains erratic behavior from the other MPFB tools.
package, enabled, blender.version.
With state "not_initialized" or "ok" it also carries version and
build_info. With state "ok" it additionally carries
is_source_dist, addon_installation_path, paths (each entry a
path plus a configured flag), asset_roots, asset_packs,
rigify_available, and blender.platform /
blender.meets_mpfb_minimum / blender.mpfb_minimum_version. Parts of the result (paths.second_root and anything derived from it)
are scene-scoped and change when a different .blend is loaded. Re-call
rather than cache. |
| mpfb_get_target_stackA | Read the modeling targets currently applied to a MakeHuman character -
every shape key on its basemesh, and the modeling sliders they add up
to. Changes nothing. result has two views of the same facts, addressed differently.
targets - one entry per shape key: shapekey_name (the raw
Blender name, and the address mpfb_set_targets' targets list
takes), decoded_name (readable; a name over 60 characters is
stored encoded, and only the raw one works as an address), value,
kind (macro/expression/detail/unknown), and where the
target sits in MPFB's index: section, category, side,
polarity, listed_in_target_json, all null for a user target
belonging to no category.
modifiers - the same information rolled up per target.json
category, each {section, category, side, value} with value in
-1.0..+1.0. This is the view MPFB's own sliders show and the one
that feeds straight back into mpfb_set_targets' modifiers list.
Only categories with a non-zero reading appear; never paged, never
filtered by name_contains.
asymmetries lists the left/right categories whose two sides differ -
which MPFB's own UI does not surface anywhere - and is what makes
mpfb_symmetrize_targets an informed operation rather than a blind
one. basemesh_name names the object the stack was read from.
include_macro (default false) adds the $md- phenotype shape keys,
which are mpfb_get_macro_details' subject; include_expressions
(default false) adds the !ex- expression ones. counts_by_kind
reports both counts whether or not they were included.
The answer is capped. limit defaults to 200 and cannot exceed
1000. Read truncated and total_count before concluding a target is
not on this character, and narrow with name_contains rather than
paging blindly; counts_by_section says where the entries are. This tool sees one thing MPFB itself cannot. MPFB excludes any
shape key whose name contains "basis", not merely equals it, so a
user target called basis-nose-widen is real, is deforming the mesh,
and is invisible to every MPFB read and write. It is listed here with
visible_to_targetservice: false, and it cannot be changed through
mpfb_set_targets either. A subject that cannot be resolved to a basemesh is an answer, found: false with a sentence, not an error. A character whose macro numbers
and macro shape keys have drifted apart is reported as it is, not
repaired. |
| mpfb_list_asset_materialsA | List the alternative materials that ship beside one equipped MHCLO
asset - the other colours of a hat - and name the one it is wearing
now. Changes nothing about the character. These are not in mpfb_list_assets' answer. That tool lists MPFB's
asset library sections; alternative materials live in the asset's own
directory instead. This is the only catalogue for them, and it is what
mpfb_set_asset_material consumes. name is the asset's own Blender object name, as
mpfb_list_objects reports it or as mpfb_add_asset returned it in
asset_object_name.
The answer is a snapshot. MPFB caches this scan per asset and
nothing invalidates that cache on its own, so a material added to the
asset's directory after the first call for that asset - in this
Blender session - will not appear. refresh=true clears the cache
first; cache_invalidated says whether it did. That clear is global -
every asset's cached list is dropped, not only this one's - which is
why the default stays false. result carries asset_object_name, object_type, asset_source and
the asset_subdir searched; default_material, the absolute path the
asset's own MHCLO names, with exists saying whether that file is
there, or null with default_material_reason saying why not;
current_alternative_material, the fragment recorded on the object
now; materials, one entry per alternative with path, fragment,
name and is_default - MPFB does not filter the asset's own
material out of this scan, so the default usually appears and is
flagged rather than removed; count; search_roots, the directories
actually scanned, so "this hat has no other colours" is distinguishable
from "the hat's asset source no longer resolves"; and
cache_invalidated.
An object that is not an asset comes back as found: false, or with an
empty list and an explanation, never as an error. |
| mpfb_list_assetsA | Find the MakeHuman assets installed in this Blender - garments, hair,
eyes, eyebrows, eyelashes, teeth, tongue, body proxies, skins,
poses - narrowed by subdir, by a keyword in the name, and by asset
pack. Adds nothing to the scene. The forward counterpart of
mpfb_get_object_info, which says what an existing object was made
from. The answer is capped and is usually a subset. Check truncated
before concluding an asset is not installed; total_count says how
many matched. The first call for a subdir is the slow one: MPFB loads a
preview image per asset, once per subdir per Blender session. Arguments, all optional and combining with AND: asset_subdir - one of "clothes", "hair", "eyes",
"eyebrows", "eyelashes", "teeth", "tongue",
"proxymeshes", "skins", "poses", "ink_layers", matched
exactly and case-insensitively. Omit it to search every subdir,
then read counts_by_asset_subdir to pick a narrower one.
name_contains - case-insensitive substring of the asset's name or
label.
pack - substring of an installed pack's name, so "hair03" finds
hair03_ccby.
limit (default 200, max 1000) and offset - paging over the
matched set, sorted by subdir then name.
refresh - rescan first. Needed only when assets were installed
after Blender started; it rescans the whole library and writes
MPFB's caches.
result carries:
assets: this page's entries, each with name (filename without
extension), label (MPFB's display text), fragment, path,
object_type, asset_subdir, file_type, pack,
pack_ambiguous and thumb_path.
counts_by_asset_subdir: how many assets each scanned subdir
holds, ignoring name_contains, pack and the cap.
requested_asset_subdir/asset_subdir_recognized/
known_asset_subdirs and requested_pack/pack_recognized/
known_packs, so a misspelling is distinguishable from an empty
subdir or pack.
asset_roots_searched: per subdir, the directories actually
scanned. A configured data root that does not hold that subdir is
not searched, which is the usual explanation for "I installed it
and it is not listed".
count, total_count, truncated, offset, limit.
How to name an asset when applying it. Pass an entry's path
(absolute) or its fragment ("fedora/fedora.mhclo", what MPFB
records on the resulting object and what survives a move to another
machine) to mpfb_add_asset, together with its object_type. Assets
in skins are materials rather than meshes and go to mpfb_set_skin
instead. A fragment is not a path; handing one to a file-opening
tool fails confusingly. For skins, poses and ink_layers the
object_type ("Material", "Pose", "Other") says what the asset
is rather than naming an argument. pack is derived from a directory-name convention, not recorded by
MPFB. pack: null is ordinary for a hand-installed asset, and
pack_ambiguous: true means two packs claim the name and the reported
one is a coin toss. total_count can under-report too: MPFB's cache is
keyed by a label derived from the filename alone, so two assets whose
filenames differ only in case or underscores collapse into one entry.
|
| mpfb_list_docsA | Addresses for MPFB's developer documentation - one document per service
(HumanService, TargetService, ...), per file format (.mhclo,
.mhmat, .target, the preset and rig JSON) and for its object
property store. Use it to answer "how does MPFB actually do X" rather
than inferring it from a tool response. Changes nothing, needs no Blender and no MPFB, and fetches nothing:
it returns URLs for the client to retrieve. raw_url returns the
markdown; page_url is the rendered page for a person. Arguments, both optional: topic (general, services,
fileformats, entities, ui; exact, case-insensitive) and keyword
(case-insensitive substring over path, title, description and
keywords). With neither, returns everything it has. A curated subset, not the tree. curated is always true,
tree_document_count says how large the tree it was drawn from is, and
tree_url is the full listing - go there when what you need is not
here, rather than concluding it does not exist. Pinned to master
(ref), so a document may describe a newer MPFB than the installed one. result carries:
documents: each {path, raw_url, page_url, title, description, keywords, topic}, path being repo-relative
(docs/services/humanservice.md). Titles, descriptions and
keywords are mpfb-mcp's own text; MPFB publishes no index.
count, curated, curated_document_count, tree_document_count,
tree_url, ref, repository.
requested_topic, topic_recognized, known_topics,
requested_keyword. An unknown topic matches nothing rather than
failing, so check topic_recognized before reading an empty
documents as "no such documentation".
Not capped and not paged: under twenty entries, so no truncated or
total_count to check. |
| mpfb_list_expressionsA | List the saved expressions MPFB can apply - named, weighted
combinations of ARKit face units such as a smile - as
mpfb_apply_expressions takes them. Changes nothing. result's expressions is one entry each: fragment, the identifier
to pass (library-relative, portable across machines), path (the
absolute file, for checking), root, label, description, tags,
author, license and face_units (what the expression sets). Not
capped or paged.
roots lists the directories scanned, in MPFB's priority order,
whether or not anything was found. unreadable names files MPFB
skips because they do not parse. shadowed names files hidden behind a
same-named file in a higher-priority root: MPFB cannot apply them.
faceunits01_installed is always present: without that asset pack no
expression can be applied. refresh (default false) re-probes for the
pack; the file scan itself is never cached.
|
| mpfb_list_objectsA | List the MakeHuman objects in the connected Blender's current scene,
optionally filtered by MPFB object type. Changes nothing. Use this to find a subject for the other MPFB tools when you did not
create the character yourself, then pass a returned name to
mpfb_get_object_info to learn what that object actually is. object_type is one of MPFB's own type names ("Basemesh",
"Skeleton", "Subrig", "Proxymeshes", "Clothes", "Eyes",
"Eyelashes", "Eyebrows", "Teeth", "Tongue", "Hair"); omit it
to get every MakeHuman object. Matching is MPFB's own, a
case-insensitive substring test rather than equality: "rig" matches
Subrig, and "mesh" matches both Basemesh and Proxymeshes. That
is deliberate on MPFB's side and is not a bug here.
Only the current scene is searched, so results match what the user is
looking at. An object that exists in the .blend without being linked
into the scene is not listed - mpfb_get_object_info will still
resolve it by name and say so. result carries objects, one entry per match with name (the
Blender object name, which is how every other tool addresses it),
object_type (MPFB's type) and blender_type ("MESH", "ARMATURE",
...); count; requested_object_type, the filter as given or null;
object_type_recognized, whether it matched a type MPFB knows -
check this before concluding anything from an empty list, since
"no basemeshes in this scene" and "you asked for Basemseh" are
otherwise the same answer; and known_object_types, MPFB's full type
vocabulary read from MPFB itself, so a misspelling can be corrected
from this same response.
The result is an address other tools will act on. Re-call rather than
cache: loading another .blend, or the user deleting an object,
invalidates it entirely. |
| mpfb_list_presetsA | List the character presets saved in MPFB's user config directory -
MPFB's "save files", the same ones its own preset panel offers. Each
entry's name is what mpfb_save_preset and
mpfb_create_human_from_preset take; neither accepts a path. Not capped and not paged, unlike the other listing tools: a preset
collection is tens of files. No preset is parsed, so this says nothing
about what is in one; mpfb_create_human_from_preset reports that for
the one it loads. refresh=true rescans the directory through MPFB. MPFB caches the list
for the Blender session and rebuilds it only when a preset is saved, so
one written by hand, by another Blender or by an earlier session is
missing until then - but you do not need to pass refresh to find that
out: missing_from_mpfb_list already names any preset file the cache
does not hold, because this tool lists the directory itself as well.
result carries:
presets: per preset name, path, size_bytes, modified
(ISO 8601 with a UTC offset) and exists. size_bytes and
modified come from os.stat here, not from MPFB, which records
neither. exists: false means MPFB's cached list still names a
preset whose file has been deleted.
Per preset, addressable and not_addressable_reason. MPFB's own
panel accepts names these tools will not - anything that could
become a path - so a preset saved by hand can be listed here and
refused by the other two. Rare, and worth seeing here rather than
in a refusal. config_dir and config_dir_exists: the directory that was
scanned, reported whether or not anything was found, so an empty
list is an answer rather than an ambiguity.
count, files_in_config_dir, missing_from_mpfb_list,
refreshed, listing_failed (a sentence when MPFB could not read
the directory at all) and message.
|
| mpfb_list_rigsA | List every rig this Blender could add to a MakeHuman basemesh: MPFB's
bundled standard and Rigify rigs, plus custom rigs found in the user's
data directories. Adds nothing to the scene. Pass a rig's identifier, not its name, to mpfb_add_rig. The
two are not the same string: a standard rig is "default_no_toes", a
Rigify one "rigify.human", a custom one "custom.my_rig". The prefix
also picks between MPFB's two non-interchangeable adding functions -
add_function says which - and crossing them does not read as the
mistake it is: a built-in name handed to the custom function comes back
missing under a mangled one. refresh=true rescans the user data directories for custom rigs first.
MPFB caches that list for the lifetime of the Blender session, so a rig
installed after Blender started will not appear otherwise.
result carries:
rigs: one entry per rig, with name, identifier, family
("standard"/"rigify"/"custom"), path (absolute, or null),
label/description (MPFB's own UI text, null for custom rigs),
add_function, available and unavailable_reason.
Per entry, what adding it would do about weights: has_weights,
weights_path and weights_from. MPFB resolves weights through
a fallback table, not by filename, so weights_from differs from
name for default_no_toes (which borrows default's) and
rigify.human (which borrows rigify.human_toes's). That is
normal. has_weights: false is not: adding that rig produces a
character with no vertex weights. count, families, message, and rigify_available - whether
Rigify is enabled here. Rigify rigs are listed either way, carrying
available: false when it is not, since adding one then raises
rather than degrading.
rig_dirs: every directory looked in, each flagged with whether it
exists. MPFB scans its own data dir and the user data roots - not
the MakeHuman user data directory.
unrecognized_custom_rig_files: .json files in a scanned user
rigs directory that MPFB refused as rig definitions - a name
outside [A-Za-z0-9_], or no identifying_bones key. MPFB drops
these silently, which otherwise makes "I put the file there and it
does not show up" undiagnosable.
Do not expect this list to match mpfb_get_object_info's
rig_identified_as. That value comes from MPFB identifying an armature by its
bone names and can be rigify_generated.* or unknown, neither of
which names something addable. A character whose rig is not in this
list is ordinary, not an error. |
| mpfb_list_targetsA | Find the MakeHuman modeling targets available in this Blender - the
named morphs like nose-scale-depth-incr that shape a character - and
report each under the name that setting it will require. Changes
nothing. The phenotype (gender, age, weight, muscle, height, proportions) is
not here: they are attributes on the basemesh
rather than target files, and are mpfb_get_macro_details /
mpfb_set_macro_details territory. The answer is capped. Check truncated before concluding a target
does not exist; total_count says how many matched. Arguments, all optional: section (a section name from target.json
or synthesized from a user target directory, matched exactly and
case-insensitively; omit it for the overview), name_contains
(case-insensitive substring, applied to category and target names
alike), and limit (default 200, max 1000) with offset, which page
over a section's categories when it has them and over user_targets
otherwise. result carries:
sections: every section, each {name, label, source, category_count, target_count}. Around thirty entries, always
present. source is "system", "user", or "both" when a user
directory shares a bundled section's name - common, and MPFB merges
the two, so such a section returns both.
categories: present when section named one with bundled
categories, each {name, label, has_left_and_right, targets, opposites} from target.json. These are what mpfb_set_targets'
modifiers entries address, and opposites is the decr/incr
and left/right pairing behind MPFB's sliders. null when no
section was asked for, or the one asked for is only a user
directory.
user_targets: what the user data directories hold, filtered to
section when one was given, each with name, shapekey_name,
path and listed_in_mpfb_ui.
target_json_path/target_json_exists and system_targets_dir:
the bundled index is ~140 KB of JSON and is not returned here - a
client that can read the Blender host's filesystem should parse it
directly instead.
unindexed_system_target_dirs: bundled target directories with no
target.json section, each with a count. The index reads as the
complete list of bundled targets and is not.
user_target_dirs: the directories actually scanned, so a target
that did not appear can be looked for where it was expected.
requested_section/section_recognized/known_sections, count,
total_count, truncated, offset, limit.
How to name a target when setting it. Use shapekey_name, never
name. name is the filename with its extension stripped, for
display; shapekey_name is what MPFB calls the shape key and the only
string it accepts. The two are equal for most targets and not above
60 characters, where MPFB encodes the name - and a caller using name
there addresses nothing at all, silently. Inside a category, targets
and opposites are already in that form. Two differences from MPFB's own modeling panels, both real rather than
bugs here: this tool scans per call, so it reports a target installed
since Blender started, which the panels cannot show until it restarts;
and listed_in_mpfb_ui: false marks a *.target.gz outside the
custom section, loadable but skipped by MPFB's own scan. |
| mpfb_list_urlsA | Addresses for the MPFB and MakeHuman community sites: downloading MPFB,
asset packs, documentation, forum, issue tracker. Takes no arguments,
changes nothing, and fetches nothing - it hands back URLs for the
client to retrieve. Use it rather than composing a makehumancommunity.org address. Reach
for it when mpfb_list_assets finds little (URL_ASSET_PACKS) or
mpfb_get_status reports the system assets pack missing
(URL_SYSTEM_ASSETS). For MPFB's developer documentation, one
document per service and file format, use mpfb_list_docs instead. It answers even when MPFB or Blender is unreachable, which is when
these links matter most - so check source_of_truth before quoting a
URL: "mpfb" was read from the running MPFB, "builtin_fallback" is
mpfb-mcp's vendored copy with fallback_reason saying why. Neither is
an error. result carries:
urls: every link, each {key, url, title, description, keywords, source}. key is MPFB's own constant name (URL_ASSET_PACKS).
source is "mpfb" for one of MPFB's constants, "mpfb_mcp" for
an ecosystem link this package adds (MakeHuman itself, the
community asset repository). title, description and keywords
are mpfb-mcp's text rather than MPFB's, and are null for a
constant MPFB has added since.
source_of_truth, fallback_reason, blender_reachable, and
mpfb_status (state: ok, absent, not_initialized or
unreachable; plus package, version, weburls_module,
weburls_read).
fallback_stale and fallback_differences: whether the vendored
copy disagrees with the running MPFB, and per key how (changed,
added_by_mpfb, missing_from_mpfb). Both null when there was
nothing live to compare against, which is not agreement.
count, vendored_mpfb_key_count, skipped_keys.
Not capped and not paged: around twenty entries, all of them, every
call. No truncated or total_count to check. |
| mpfb_refit_humanA | Re-fit everything on a MakeHuman character to the current shape of its
basemesh: every mesh asset (garments, body parts, the body proxy), the
rig, and any sub-rigs. Call this after changing a character's shape with
mpfb_set_macro_details, mpfb_set_targets or
mpfb_symmetrize_targets while leaving their refit at its default of
false - those tools report assets_possibly_stale when they leave work
for this one. A refit re-runs the vertex fit per asset, so make a
series of modeling changes first and refit once at the end. It is
idempotent: refitting a character already in fit is safe and costs the
same. result carries refit_performed, basemesh_name, rig_object_name,
mesh_assets with mesh_asset_count, and subrigs.
Check refit_performed rather than assuming success; performed
is set from it, so the two cannot disagree. One case refits the mesh
assets but leaves the rig untouched: a rig generated by Rigify whose
meta rig is no longer in the scene cannot be refitted at all, and MPFB
reports this through a channel that does not reach an MCP tool.
refit_incomplete_reason then says so, and the fix - regenerating with
the meta rig kept - is the user's to make in Blender. A basemesh left
in edit mode answers with ready: false, and an unresolvable subject
with found: false and blocked_by: "subject_not_found". |
| mpfb_remove_assetA | Take one mesh asset - a garment, a body part or the body proxy - off
a MakeHuman character and clean up after it, the way MPFB's own
"unload" does. Use this rather than deleting the object. MPFB hides the body under
a garment with a mask modifier on the basemesh (and on the body proxy,
for garments), and a garment may have brought a sub-rig of its own.
Deleting the object with a generic Blender tool leaves both behind, and
the character keeps a hole in it with nothing visible to explain it. name is required and is the asset object's own Blender name, as
mpfb_list_objects reports it or as mpfb_add_asset returned it in
asset_object_name. There is no active-object fallback: this deletes
an object. Equipping two copies of one asset gives ...hat and
...hat.001, so check which you are naming. This is not undoable
across the socket: the object and its mesh data are gone when the
call returns.
On removed: true, result carries asset_object_name, object_type
and asset_source - all read before the deletion - plus
basemesh_name, objects_removed naming everything the call deleted,
mask_modifiers_removed naming the objects and modifiers that went,
subrig_removed, and two things MPFB leaves behind and never mentions:
vertex_groups_left_behind (the Delete.<name> groups themselves;
only the modifiers referencing them are removed) and
mesh_data_orphaned (the mesh datablock, which keeps no users until
the file is saved and reloaded). Both are harmless and both are
invisible unless reported. Refusals come back as removed: false (and so performed: false) with
a blocked_by and a sentence: subject_not_found, basemesh_not_found,
not_object_mode, asset_source_missing - without it the mask
modifier cannot be identified and removal would be silently partial -
and not_a_mesh_asset, which refuses a basemesh or a skeleton
outright, because the underlying MPFB function would happily delete
either. |
| mpfb_save_expressionA | Save a MakeHuman character's live face - every non-zero ARKit face unit expression_name is a name, never a path: the file is
<expression_name>.json in the expressions directory of MPFB's user
data, and path and fragment are in every answer. Same rule as preset
names: letters, digits, _, -, ., at most 64 characters, no leading
dot.
What is saved is the whole live face, including what applied
expressions contribute. To make it durable, call
mpfb_apply_expressions with mode: "replace" and the new fragment
at 1.0 - replace, not merge, or the stack counts twice. result's
apply_with holds exactly those arguments. overwrite (default false) refuses an existing file
(blocked_by: "expression_exists", file_before giving its size and
age); the directory is shared with installed asset packs. Other
refusals, nothing written: name_shadowed (a same-named file in a
higher-priority data root would hide this one from MPFB for good -
shadowed_by names it), empty_expression (every unit is 0.0),
subject_not_found.
Optional metadata, stored as given: description, tags (list of
strings), author, copyright, license (default "CC0", MPFB's
composer default), homepage. On success result also carries
face_units and metadata as read back from the file, overwrote,
and panel_synced (whether MPFB's library panel gained the slider). |
| mpfb_save_presetA | Save a character as an MPFB preset - phenotype, modeling targets, rig,
body parts, garments, skin and eye materials - to be rebuilt later with
mpfb_create_human_from_preset or from MPFB's own preset panel.
This writes a file outside the .blend, and nothing in Blender can
undo it. preset_name is a name, never a path: the file is always
human.<preset_name>.json in MPFB's user config directory, and path
in the response says which file that was. Letters, digits, _, - and .
only, at most 64 characters, no leading dot - stricter than MPFB's own
panel, which rejects only a space, so that a name cannot become a path.
basemesh_name says which character was actually serialized.
overwrite (default false) is the only thing standing between a call
and the loss of an existing preset. With it false and the preset
present, the tool refuses - blocked_by: "preset_exists", nothing
written - and file_before carries that file's size and age so the
decision can be made from the response.
A generated Rigify rig does not round-trip. MPFB stores the meta
rig it was generated from, so loading the preset back gives you the
meta rig and mpfb_generate_rigify_rig finishes the job. Nothing is
lost and nothing fails; rig_identified_as and rig_saved_as show the
substitution on the call where it happened. On saved: true (and so performed: true), result carries path,
size_bytes, modified, overwrote, file_before (the replaced
file's facts, or null), config_dir, basemesh_name, rig_object_name,
rig_identified_as/rig_saved_as, and contents - what the written
file actually holds, read back from it: rig, proxy, bodyparts,
clothes, skin_mhmat, skin_material_type, eyes_material_type,
target_count, expression_count, makeup_count. Refusals come back as saved: false with a blocked_by, having
written nothing: subject_not_found, preset_exists,
not_a_human_project (MPFB only serializes characters made within
MPFB, not imported meshes), rig_not_identifiable (an armature MPFB
cannot name - for a custom rig, its definition is no longer in your
user data), config_dir_missing and serialize_failed. |
| mpfb_set_asset_materialA | Replace the material on an equipped MHCLO asset with one of the
alternatives that ship beside it - a hat in another colour - or put the
asset's own material back. name is required and is the asset's own Blender object name,
as mpfb_list_objects reports it or as mpfb_add_asset returned it in
asset_object_name - not the character's. There is no active-object
fallback: this destroys that object's current material.
Name the material with either path or fragment, never both.
Both come from mpfb_list_asset_materials, the only catalogue for
them: alternative materials sit in the asset's own directory rather
than in an asset library section, so mpfb_list_assets does not know
about them. restore_default (default false) instead puts back the material named
by the asset's own MHCLO and clears the recorded
alternative_material. It cannot be combined with path or
fragment.
MPFB has no service-level "set an alternative material" - the logic
exists only in its asset library panel - and two of that panel's quirks
are reproduced here rather than tidied up, because tidying them would
make the result differ from what a user gets from the panel: the new
material is always a MakeSkin material named makeskinmaterial,
whatever the asset had before, and the slots are popped rather than
deleted, so node groups from the previous material survive. The
viewport display colour comes from MPFB's per-type table keyed on the
asset's object_type, so an asset mislabelled when it was equipped
gets the wrong colour here too; diffuse_color_from reports which type
was used and is null when the neutral grey fallback applied. On applied: true, result carries asset_object_name,
object_type, asset_subdir, path_resolved_by/resolved_path,
alternative_material (the fragment now recorded on the object, empty
when the default was restored) beside alternative_material_before,
materials_destroyed, material_name and diffuse_color_from. Refusals come back as applied: false (and so performed: false) with
a blocked_by and a sentence: subject_not_found, not_an_mpfb_object,
material_not_found, not_object_mode, asset_source_missing and
default_material_not_found (both for restore_default on an asset
whose own MHCLO cannot be found or names no material on disk), and
type_not_supported for a Basemesh, Proxymeshes or Skeleton -
MPFB's own panel refuses all three, and the first two have a skin
rather than an asset material, which is mpfb_set_skin's job. |
| mpfb_set_face_unitsA | Compose a MakeHuman character's face from ARKit face units - the same
52-unit vocabulary mpfb_get_face_units reads and MPFB's own composer
panel edits, applied directly to the !ex- shape keys. Send the whole expression as one call. face_units is a list of
{face_unit, value}, value in 0.0-1.0. Call mpfb_get_face_units
first if you need the exact 52 legal names, grouped by region in
known_face_units. Nothing is written unless every name resolves. Every face_unit is
checked against MPFB's own vocabulary before anything is touched; one
misspelled name refuses the whole call and unknown_face_units names
it together with the closest legal spellings. This tool also refuses
outright when the faceunits01 asset pack is not installed, since
every target file would then be missing - check
mpfb_get_face_units' faceunits01_installed first if unsure. mode is "merge" by default, matching MPFB: a face unit not
mentioned in face_units is left exactly as it was. "replace" zeroes
every one of the 52 units before applying this call's entries, which is
the difference between "smile a bit more" and "make this face and
nothing else"; removed_by_replace names what it zeroed.
refit (default true, unlike every other refitting tool here:
composing is normally one call) re-fits the mesh assets and the rig afterwards.
A composed face is transient. MPFB has two mechanisms over one set
of shape keys: this tool writes them directly, while saved expressions
live on a stack (mpfb_get_expression) that mpfb_apply_expressions
and preset loads rebuild the face from, discarding anything composed
here. result's matches_stack is false when the face now differs
from the stack, and unexplained_face_units lists what the next rebuild
would overwrite. mpfb_save_expression keeps a composed face. result carries changes - one entry per unit actually written, with
previous_value and new_value - plus loaded_from_disk (units whose
shape key had to be created from a target file on this call),
could_not_load (a unit whose target file was missing even though the
pack passed its own install probe - a partially installed pack), and
skipped_absent_at_zero (a unit requested at 0.0 with no shape key
yet, which is left alone rather than created). basemesh_name names
the object actually changed. A subject that cannot be resolved
(found: false, subject_not_found) and a basemesh in edit mode
(ready: false) are answers, not errors.
|
| mpfb_set_macro_detailsA | Change a MakeHuman character's macro details - its phenotype sliders -
and rebuild the shape from them, exactly as MPFB's own sliders do. Every slider is optional and an omitted one is left alone, so a
relative change is one call: read the character with
mpfb_get_macro_details, then pass only what should differ. Passing a
slider its current value is not the same as omitting it - it is
reported in changes with previous_value equal to new_value. Sliders are 0.0-1.0, and 0.5 is neutral for all but the three race
weights, whose neutral is 0.33 each. age runs 0.0 = baby, 0.1875 =
child, 0.5 = young adult, 1.0 = old; gender 0.0 = fully female, 1.0 =
fully male. The three race weights are independent and MPFB does not
normalize them: setting race_asian to 1.0 does not reduce the other
two, and the default sums to 0.99. Set all three when changing one, or
read race_sum in the response and decide. prune (default true, MPFB's own) deletes macro shape keys whose
weight falls to zero, keeping the shape key list from growing as
sliders move. refit (default false, MPFB's own) re-fits the mesh
assets and the rig to the new body shape. The default is false because a refit
is expensive, not because it is unnecessary: leave it false, read
assets_possibly_stale, and call mpfb_refit_human once after a
series of changes rather than paying for a refit per slider.
result carries changes (one {name, previous_value, new_value}
per slider named), the full macro_details after the change,
race_sum, macro_shapekeys_before/_after with shapekeys_removed
and shapekeys_added - all four naming shape keys as the mesh stores
them ($md-$as-$fe-$yn), so a name from here can be looked up rather
than only read - plus recalculated, refit_performed,
assets_possibly_stale and basemesh_name.
Two situations answer rather than fail, both with changes: []: a
subject that resolves to no basemesh (found: false,
subject_not_found), and a basemesh that is not ready to be modified -
left in edit mode, or with no shape keys at all (ready: false,
blocked_by naming which). A call that
names no slider also does nothing, deliberately, rather than paying for
a shape rebuild that would change nothing; it comes back performed: false. |
| mpfb_set_material_settingsA | Change a MakeHuman character's procedural material settings - iris
colours, the LAYERED skin, the tint of hair and garments - as one
all-or-nothing batch that survives mpfb_save_preset and
mpfb_create_human_from_preset. Take section, group and socket names
from mpfb_get_material_settings. eyes: {socket, value | color}
skin: {group, socket, value | color}, group as the read keys it
color_adjustments: {object_name, socket, value | color}
Exactly one of value (a float socket) and color (a colour socket).
A color is four scene-linear RGBA numbers, like the read's
settings, not sRGB: a colour picked by eye comes out too light
unless converted. Nothing is written unless every entry resolves; resolution_errors
gives each failure's reason: section not applicable, unknown group
or socket (with closest), wrong key for the socket's kind, a float
outside its range, or a linked socket, which a write cannot change.
Most layered region colours are linked from the color group, and
write_instead names the socket to set. On the layered skin, color's SkinColor shows fully with no diffuse
texture and over one only as far as SkinOverride raises it; each
region colour has its own *Override. A colour adjustment mixes
Color1 with the texture by Factor, so a low Factor is flat
colour without texture detail. mpfb_set_skin, mpfb_set_asset_material and re-adding the eyes
rebuild a material from MPFB's defaults, discarding these settings.
result's changes lists each socket in request order with
previous_value/new_value and previous_srgb_hex/new_srgb_hex;
materials_written names other objects sharing a written material,
which changed too.
|
| mpfb_set_skinA | Give a MakeHuman character a skin, the way MPFB's own skin library
panel does. This destroys every material already on the character. MPFB deletes
all materials on the basemesh and on the body proxy, node groups
included, before building the new one, and there is no undo across the
socket. materials_destroyed names what went, per object. Name the skin with either path or fragment, never both;
mpfb_list_assets reports both for every entry whose object_type is
Material (the skins subdir). A fragment is resolved by
basename, so resolved_path always reports which file was actually
loaded. Give neither only with skin_type="LAYERED", the one type
that builds a material from nothing. skin_type is MAKESKIN (default), GAMEENGINE, ENHANCED,
ENHANCED_SSS or LAYERED: five entirely different node trees built
from the same MHMAT - MakeSkin's own, a plain PBR material for export,
the enhanced one without and with subsurface scattering, and the
multilayered one, which MPFB warns is expensive to render rather than
to build. All five cost about the same to build, so pick on the look
you want. The default follows MPFB's settings panel, not
set_character_skin()'s own signature, which defaults to
ENHANCED_SSS.
material_instances (default true) asks for the per-vertex-group
material slots - fingernails, lips, ears, nipples, toenails, genitals.
MPFB's UI forces it off for LAYERED, GAMEENGINE and MAKESKIN,
and so does this tool, so the default call creates no instances at
all. material_instances_requested comes back beside
material_instances_used, with a sentence when they differ.
On applied: true, result carries basemesh_name and
bodyproxy_name - MPFB applies the skin to the body proxy too, and
nothing else would tell you - plus resolved_path, material_source
(the fragment MPFB recorded, written only when an MHMAT was given,
so a LAYERED skin with no file leaves the previous value in place,
which material_source_before makes visible), skin_type_used,
material_instances_requested/_used, materials_destroyed,
material_slots per object, material_identified_as,
active_body_slot, and two facts nothing in Blender would show you:
settings_file_created, true when the enhanced skin types copied
enhanced_settings.default.json into your user config directory - the
only file mpfb-mcp ever writes outside the .blend - and
scale_assumption (METER/DECIMETER/CENTIMETER), which the
enhanced types derive from the character's scale_factor and which
changes the subsurface radii. It is null for the three types that do
not use it, and METER for an ordinary MPFB character. Refusals come back as applied: false (and so performed: false) with
a blocked_by and a sentence, and change nothing on the way to finding
out: subject_not_found, unknown_skin_type (with
known_skin_types), no_material_given, skin_not_found,
not_object_mode, and skin_failed for a failure inside MPFB itself -
reported rather than raised precisely because the materials are already
gone by then. |
| mpfb_set_targetsA | Change a MakeHuman character's modeling targets - one modifier (a
per-category slider), one raw target, or fifty of them in one call. Send the whole change as one call. A round trip costs about half a
second and the work inside costs milliseconds. modifiers is the level to use normally. Each entry is {section, category, value, side}, naming a target.json section and one of its
categories exactly as mpfb_list_targets reports them:
value runs -1.0..+1.0 for a category that has opposites - the
sign picks which of the opposing pair is loaded, and the other is
driven to zero - and 0.0..1.0 for one that does not.
side is "left", "right" or "unsided". Required for a
category with has_left_and_right: true, and omitted or
"unsided" for one without.
targets is the escape hatch, for a user-installed target that
belongs to no category. Each entry is {shapekey_name, value} with
value in 0.0..1.0, the range Blender clamps a shape key to. Use the
shapekey_name mpfb_list_targets reports, not the filename:
above 60 characters MPFB encodes the name, and a filename then
addresses nothing at all, silently.
Both lists are optional and either may be empty; a call naming neither
does nothing and says so. Nothing is applied unless everything resolves. Every entry is
checked inside Blender first - the section and category exist, the side
fits the category, the value is in that category's range, the target
file can be found - and if any entry fails, resolution_errors names
which and zero changes are made. Fix them and resend the whole
batch; known_sections and known_categories_in_section come back
with the error. symmetry (default false, MPFB's own) also applies a sided change to
the other side, so one entry touches up to four shape keys. prune
(default true, MPFB's own) deletes a target's shape key once its value
reaches zero. refit (default false, MPFB's own) re-fits the mesh assets and
the rig afterwards; leave it false, read assets_possibly_stale, and
call mpfb_refit_human once when the modeling is done.
result carries changes - one entry per requested change, in request
order, each listing every target file touched with present_before,
previous_value, new_value, loaded_from (set when the target was
read off disk on this call) and pruned - plus shapekeys_added and
shapekeys_removed, refit_performed, assets_possibly_stale and
basemesh_name. An unresolvable subject answers found: false with
blocked_by: "subject_not_found", and a basemesh in edit mode or
without shape keys ready: false with blocked_by. performed is false whenever changes is empty, the
all-or-nothing resolution failure included.
|
| mpfb_symmetrize_targetsA | Make a MakeHuman character's modeling targets left/right symmetric, by
copying one side's modeling onto the other. MPFB itself cannot do this. Its symmetry setting only mirrors
changes made while it is on and leaves previously set values alone, so
a character that has already drifted asymmetric has no repair path in
MPFB's UI. Call mpfb_get_target_stack first: its asymmetries field
lists which categories differ and by how much. This is destructive and there is no undo across the socket. It
overwrites values the user may have set on purpose. direction is
required - "left_to_right" or "right_to_left" - because which half
of a face is the good one is not something a tool can guess. Run it
with dry_run: true first: the answer lists exactly the changes a
real run would make, and writes nothing. section restricts the operation to one target.json section, so
"make the eyes symmetric" does not also flatten deliberate asymmetry in
the hands; omit it to cover every section. Only categories with
has_left_and_right: true are considered, paired through
target.json's opposites table rather than by matching l-/r-
name prefixes, which would be a guess.
prune (default true, MPFB's own) deletes a target's shape key once
its value reaches zero. refit (default false, MPFB's own) re-fits
the mesh assets and the rig afterwards; read assets_possibly_stale and call
mpfb_refit_human when the modeling is done.
result carries changes - per category, both sides' values before,
the value after, and every target file touched, with targets being
null rather than [] under dry_run: true, because which files a
write would touch is only knowable by doing the write - plus
already_symmetric, basemesh_name, and skipped for a category
whose target file could not be found, since one unreachable target is
reported rather than abandoning the rest of the body.
Under dry_run: true, performed is false even though changes has
entries in it: those are the writes that would happen. A subject that
cannot be resolved (found: false, subject_not_found) and a basemesh
in edit mode or without shape keys (ready: false) are answers, not
errors. |