Pri práci na komplexných 3D postavách sa často stretávame s potrebou preniesť výrazové kľúče (Shape Keys) z jedného modelu na druhý. Či už ide o optimalizovanú verziu modelu, alebo drobné úpravy topológie, ručné kopírovanie desiatok kľúčov je nočnou morou každého artistu. Práve preto sme pre vás pripravili tento šikovný Python skript.

Prečo používať skript?

V Blenderi síce existuje natívna funkcia "Join as Shapes", no tá vyžaduje, aby mali oba objekty identický počet vertexov a rovnaké poradie indexov. Náš skript pridáva dôležitú kontrolu a automatizuje proces vytvárania Basis kľúča a následné prekopírovanie presných pozícií vertexov pre každý existujúci morph target.

1. Kód skriptu pre kopírovanie

Skript jednoducho skopírujete do Text Editora v Blenderi a spustíte so zvolenými objektmi (prvý označený je cieľ, aktívny je zdroj):

import bpy

def copy_all_shape_keys():
    # Získame vybrané objekty
    selected = bpy.context.selected_objects
    active = bpy.context.active_object
    
    # Kontrola, či sú vybrané presne 2 objekty
    if len(selected) != 2:
        print("Chyba: Musia byť označené presne 2 objekty (Zdroj a Cieľ)!")
        return
        
    # Zdroj a cieľ (aktívny je zdroj)
    source = active
    target = [obj for obj in selected if obj != source][0]
    
    if not source.data.shape_keys:
        print(f"Chyba: Zdrojový objekt '{source.name}' nemá žiadne Shape Keys.")
        return
        
    # Ak cieľ nemá Basis, vytvoríme ho
    if not target.data.shape_keys:
        target.shape_key_add(name="Basis")
        
    print(f"Kopírujem Shape Keys z '{source.name}' do '{target.name}'...")
    
    for sk in source.data.shape_keys.key_blocks:
        if sk.name == "Basis":
            continue
            
        # Ak už cieľ má kľúč s týmto menom, preskočíme ho
        if target.data.shape_keys.key_blocks.get(sk.name):
            continue
            
        # Pridáme nový kľúč a prekopírujeme pozície
        new_sk = target.shape_key_add(name=sk.name)
        for i, v in enumerate(sk.data):
            new_sk.data[i].co = v.co
            
    print("Všetky Shape Keys boli úspešne prekopírované!")

copy_all_shape_keys()
        

2. Bonus: Resetovanie všetkých kľúčov na nulu

Po importe alebo kopírovaní sa niekedy stane, že sú kľúče nastavené na rôzne hodnoty. Tento pomocný skript rýchlo vynuluje všetky vplyvy na označených objektoch:

import bpy

def reset_shape_keys_to_zero():
    # Prejdeme všetky aktuálne označené objekty
    for obj in bpy.context.selected_objects:
        
        # Skontrolujeme, či má objekt nejaké shape keys
        if obj.data and hasattr(obj.data, "shape_keys") and obj.data.shape_keys:
            
            # Prejdeme všetky kľúče a nastavíme ich na 0.0
            for sk in obj.data.shape_keys.key_blocks:
                sk.value = 0.0
                
    print("Hotovo! Všetky Shape Keys na označených objektoch sú nastavené na 0.")

reset_shape_keys_to_zero()
        

3. Prenos Vertex Groups (Váh kostry)

Pre správnu deformáciu modelu pri animácii je kľúčové preniesť váhy (vertex groups) z pôvodného modelu na nový. Tento skript automatizuje vytvorenie skupín a prekopírovanie presných hodnôt pre každý vrchol:

import bpy

def transfer_vertex_groups():
    selected = bpy.context.selected_objects
    active = bpy.context.active_object

    # Kontrola výberu
    if len(selected) != 2:
        print("Chyba: Musia byť označené presne 2 objekty (Cieľ a Zdroj)!")
        return

    source = active
    target = [obj for obj in selected if obj != source][0]

    # Kontrola topológie
    if len(source.data.vertices) != len(target.data.vertices):
        print(f"Chyba: Modely nemajú rovnaký počet vertexov! (Zdroj: {len(source.data.vertices)}, Cieľ: {len(target.data.vertices)})")
        print("Pre modely s rôznou topológiou použi Data Transfer Modifier.")
        return

    print(f"Kopírujem Vertex Groups z '{source.name}' do '{target.name}'...")

    # 1. Vytvor chýbajúce skupiny vrcholov v cieli
    for vg in source.vertex_groups:
        if not target.vertex_groups.get(vg.name):
            target.vertex_groups.new(name=vg.name)

    # 2. Prekopíruj váhy (weights) pre každý vertex
    for i, v_src in enumerate(source.data.vertices):
        for g in v_src.groups:
            # Zistíme meno skupiny v zdroji podľa indexu
            group_name = source.vertex_groups[g.group].name
            vg_tgt = target.vertex_groups.get(group_name)
            
            # Priradíme rovnakú váhu vertexu v cieli
            if vg_tgt:
                vg_tgt.add([i], g.weight, 'REPLACE')
                
    print("Hotovo! Všetky Vertex Groups a váhy boli úspešne prenesené.")

transfer_vertex_groups()
        

Ako na to?

1. Označte cieľový objekt (target) ako prvý.
2. S podržaným SHIFT označte zdrojový objekt (source) – ten bude svietiť svetlejšie.
3. Prejdite do záložky "Scripting", vložte kód a stlačte "Run Script".

Vaša efektivita v Blenderi sa razom zvýši a vy sa môžete sústrediť na to dôležité – kreativitu.

Späť na blog