Blenderで分子モデルに自動でマテリアル設定するやつ(molファイルを直接読み込めるよう修正)
前に作ったやつはmolファイルを手作業で整形しなければいけなくてめんどくさかったので、molファイルを直接読み込めるように直しました。 多分動くと思います。動かなかったらすみません。
10行目の mol_file="hogehoge.mol" のところに、読み込みたいmolファイルのパスを指定してください。
#for stick-model import bpy import csv import re #-------------------------------------------- #読み込むmolファイルを指定する mol_file="hogehoge.mol" #---------------------------------------------------------- #delete all materials and material_slots # あらかじめマテリアルとマテリアルスロットを全部消す # これを入れないと実行するたびにマテリアルが増殖する for mats in bpy.data.materials: bpy.data.materials.remove(mats) for o in range(len(bpy.data.objects)): bpy.context.view_layer.objects.active = bpy.data.objects[o] for ms in range(len(bpy.data.objects[o].material_slots)): bpy.ops.object.material_slot_remove(ms) bpy.context.view_layer.objects.active = None #---------------------------------------------------------- # 貼り付けるマテリアルを設定しておく # どれにも該当しない場合はmaのマテリアルが割り当てられる # makematerial("名前", 色(RGBA), 発光(省略可)) # 作ったらmlistとmdictの末尾に付け加える def make_material(name, color, emit = 1): ma = bpy.data.materials.new(name) ma.use_nodes = True bsdf = ma.node_tree.nodes["Principled BSDF"] bsdf.inputs[0].default_value = color bsdf.inputs[4].default_value = 0.2 bsdf.inputs[7].default_value = 0.3 bsdf.inputs[18].default_value = emit ma.diffuse_color = color return ma ma = make_material("Others",(0.9,0.9,0.9,1)) mc = make_material("Carbon",(0,0,0,1)) mh = make_material("Hydrogen",(0.2,0.5,0.9,1)) mn = make_material("Nitrogen",(0,0.05,0.95,1)) mo = make_material("Oxygen",(1,0.05,0.05,1)) mb = make_material("Boron",(0.05,0.75,0.05,1)) mf = make_material("Fluorine",(0.5,0.95,0.5,1)) mcl = make_material("Chlorine",(0.3,1,0.1,1)) mbr = make_material("Bromine",(0.5,0.15,0.1,1)) mi = make_material("Iodine",(0.4,0.1,0.7,1)) mp = make_material("Phosphorus",(1,0.4,0.7,1)) ms = make_material("Sulfur",(1,0.9,0,1)) mlist = [ma, mc, mh, mn, mo, mb, mf, mcl, mbr, mi, mp, ms] mdict = {'C' : 1, 'H': 2, 'N': 3, 'O': 4, 'B': 5, 'F': 6, 'Cl': 7, 'Br': 8, 'I': 9, 'P': 10, 'S': 11} #---------------------------------------------------------- # molファイルから、3Dモデルのマテリアルに対応する原子を読み込む---------- #molファイルをテキストとして開いて、行ごとにリストrlmに格納 with open(mol_file, 'r') as fm: rlm = fm.readlines() #データのヘッダを探し、その行番号を記録する #1つ目と2つ目の要素がそれぞれ原子数と結合数を表しているので、それらを記録する for l in rlm: rlmhead=re.search('[0-9]+ +[0-9]+ + [0-9 ]+(V2000)',l) if not rlmhead is None: headnum=rlm.index(l) abnum=re.search('[0-9]+ [0-9]+', rlmhead.group()).group() atomnum=int(abnum.split()[0]) bondnum=int(abnum.split()[1]) break elif rlm.index(l)==len(rlm)-1: print("ERROR:FILE FORMAT UNAVAILABLE") #ヘッダ行の次の行から原子数分の行を読み込み、元素記号をリストに格納する atomlist=[] for al in range(headnum+1,headnum+1+atomnum): at = re.search('[a-zA-Z]+',rlm[al]) atomlist.append(at.group()) print("Atoms: ",atomlist,"\n") #molファイル上の原子のブロックの次が結合のブロックになるので、結合数分だけ読み込む #1番目の要素と2番目の要素は原子の番号を表しており、どの原子とどの原子が結合しているかを示している #blender上で結合部分を結合している原子のマテリアルと合わせるために、結合している原子の元素記号を記録する bondlist = [] for bl in range(headnum+1+atomnum,headnum+1+atomnum+bondnum): bntmp = re.finditer('\d+',rlm[bl]) tmp1=int(next(bntmp).group())-1 tmp2=int(next(bntmp).group())-1 bondlist.append(atomlist[tmp1]) bondlist.append(atomlist[tmp2]) print("Bonds: ", bondlist,"\n") # オブジェクト番号と対応した並びの原子(マテリアル)リストを作る # これをもとにマテリアルを割り当てていく alllist=[] alllist = bondlist + atomlist print("Set Materials in this order:", alllist, "\n") #-------------------------------------------------------------------------- # set materials ---------------------- # マテリアルを割り当てる cnt=0 for o in range(len(bpy.data.objects)): if bpy.data.objects[o].type == "MESH" : if mdict.get(alllist[cnt]) == None: matmp = ma else: matmp = mlist[mdict.get(alllist[cnt])] bpy.data.objects[o].data.materials.append(matmp) for m in bpy.data.objects[o].material_slots: m.material = matmp cnt += 1
関連記事
Blenderで読み込んだ分子モデルにマテリアルを自動設定したかったパワポに直接挿入可能な3D分子モデルを作る
Blenderで芳香環に面を張るやつ
コメント
コメントを投稿