2017年3月23日木曜日

蘇るトラウマ

トイレは直りましたがだいぶ更新が滞っています。

理由は2つありまして、ひとつは去年の年末からやっていた親父の X60。
CMOS電池とマザーボードを取り寄せて換装するも、熱暴走と思われるシャットダウンを繰り返し、排気ファンにエアダスターを充て、放熱グリスを高級品で塗り直し、
使わないがやたら熱を出す無線LANとモデムをはずし、
フリーウェアのCPUIDでCPUの電圧を落としてリトライ。
CPU温度が55度以下で安定し、アップデートも無事完了…

しかし、翌日持っていく朝になって立ち上がらない。
マザーボードもCPUも排熱も疑いようが無いのに、なにが…
よく考えてみれば、それまでつけていなかった大容量バッテリーをつけていたような。

…こいつかよ。結局バッテリーによる過電圧でマザーボードにダメージを与えていたようです。
LENOVO だし、中国製バッテリーが爆発しなかっただけマシと考えるべきか。

せっかく載せ替えたマザーボードもダメージを受けたため長くても1時間でシャットダウンしてしまいますが、
さすがに再度マザーボードを取り寄せていられないのでこのまま親父に返しました。

先日退社後に続けていた仕事も引退した親父ですが、
このPCは退社時の祝いでもらった物。且つ、退社後の仕事で使用していた物だけに、
もう少し無事な形で返したかったです。

もうひとつは Python です。
以前手のモデリングをした際につなぎ目を青いマテリアルで繋いでいましたが、
これをいちいち隠したり出したりして編集するのが面倒になりまして、
「選択したエッジの中から、指定したマテリアルのみを含むエッジを隠す」
というアドオンを開発していました。

なのですが、プログラムなんて8年ぶり。
8年前にやったのは職業訓練校でやっていたPICマイコン(アセンブラ)だし、
まあ、それ以前はプログラマーだったのでオブジェクト指向言語っぽいなとはわかるのですが、そもそも Python なんて使ったことが無い。

アキバのヨドバシで本を買ってきて…
メインの「マテリアルを含むエッジを隠す」関数は参考書を読む前に、
ネットで拾ったソースをくっつけ合わせたら2時間ほどでできました。

更にネットを見ながら1日でツールボックスボタンを作って
押されたらマテリアルを選ぶ(予定)のリストボックスを表示する所までできまして、
参考書の3000円損したかなと思いましたが…

配列が作れない、選択されたリスト項目が反映されない、
メンバー変数が作れない、頼みの綱の Blender.jp フォーラムが閉鎖されていた…

え、なんでこんなにハマるの?の連続。C++止まりの自分には異次元すぎる。
これが時代という奴ですかね。

あと、久々にプログラムして気づいたのですが、以前PICマイコンを組んだ時はなかった微妙な頭痛がするんですよね。
アセンブラは書いたまんまの動作をするのであまり悩まないのですが、
オブジェクト指向言語って表面のメソッドの裏であれこれあったりするわけです、
氷山の下の氷みたいな物が。

なんか、そういった物を感じると吐き気がしてくるプログラマーだったなと8年ぶりに思い出しました。
というか、この手のトラウマって治らないんですね。

で、成果物が下記の通り

ツール項目に Hide by Material というツールが足されるので、ボタンを押して
マテリアルを選択…

ポップアップでOKを選択すると辺と面を隠してくれます

当然隠しただけなので Alt+H で元に戻ります。

以下ソース

import bpy
import bmesh
from bpy.props import *

##############################################

def hide_by_material(input_idx_mat):
    idx_mat = int(input_idx_mat)
    print('mode:',bpy.context.mode,'material:',idx_mat)

    if bpy.context.mode == 'EDIT_MESH':
        bm = bmesh.from_edit_mesh( bpy.context.active_object.data )

        idx_edge = 0

        for edge in bm.edges:
            if edge.select:
                print(idx_edge,':edgeno ',edge.index)

                # Serch Edges
                bl_hide = True
                idx_face = 0
                for face in edge.link_faces:
                    print(idx_face,':material_no ',face.material_index)
                    if face.material_index != idx_mat:
                        print('non_hide')
                        bl_hide = False
                        
                    idx_face = idx_face+1
                
                # Hide Edge & Faces
                if (bl_hide):
                    for face in edge.link_faces:
                        face.hide = True
                    edge.hide = True
                    
            idx_edge = idx_edge+1
            
        bmesh.update_edit_mesh( bpy.context.active_object.data )

##############################################

class UI(bpy.types.Panel):
    bl_label = "Hide by Material"
    
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Tools"

    def draw(self, context):
        self.layout.operator("my.button")

##############################################

class MyButton(bpy.types.Operator):
    bl_idname = "my.button"
    bl_label = "Select Material"
    
    def get_list_callback(scene, context):
        items = []
        
        mat_idx = 0
        for mat in bpy.data.materials:
            items.append((str(mat_idx),mat.name,"",mat_idx))
            mat_idx = mat_idx+1

        return items
    
    select_material = bpy.props.EnumProperty(items=get_list_callback)

    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        print("hide material",self.select_material)
        hide_by_material(self.select_material)
        return{'FINISHED'}

##############################################

bpy.utils.register_module(__name__)