ひっさしぶりのCGの記事ですよ。誰が興味あんねんってな内容ですよ!

お仕事で、ある高分子をモデリングする必要があって、Avogadroと言うフリーソフトを見つけました。既知の分子構造はもちろん呼び出せますし、自分で分子をモデリングすることも出来、非常に興味深いのですが、残念なことに3Dの書き出しがPOV-Rayフォーマットしかありません。

つーことでpythonのお勉強を兼ねて読み込みスクリプトを書いてみました。

Tryptophan_trim

Avogadroの説明は省きます、分子は「File/Import」から呼び出せます。「File/Export/POV-ray…」で書き出したら次のスクリプトを実行してpovファイルを読み込むだけです。メッシュデータには対応していません、ファイル内のcylinderとsphereの情報を読み取るだけです。Maya2013 x64 Extension2で動作確認してます。

import pymel.core as pm
import pymel.core.datatypes as dt
import re
import math

def htAimY(vec):
    outAngle = []
    xyLength = dt.Vector(vec.x,vec.y,0).length()
    vecLength = vec.length()
    if xyLength == 0:
        zAngle = math.radians(90) if vec.x > 0 else math.radians(-90)
    else:
        zAngle = math.acos(vec.y/xyLength)
    xAngle = math.acos(xyLength/vecLength)
    xAngle = xAngle if vec.z > 0 else xAngle * -1
    outAngle.append(math.degrees(xAngle))
    zAngle = zAngle * -1 if vec.x > 0 else zAngle;
    outAngle.append(math.degrees(zAngle))
    return outAngle

basicFilter = "*.pov"
fileName = pm.system.fileDialog2(fileFilter = basicFilter, fileMode = 1, dialogStyle = 2,caption = "Open moleculer geometry")
if fileName:
    print("load file name: " + fileName[0])
    
    filePointer = open(fileName[0])
    line = filePointer.readline()
    
    while line:
        if re.search("cylinder",line):
            line = filePointer.readline()
            matchList = re.findall("-?[0-9]+\.[0-9]+[eE][-+]?[0-9]+|-?[0-9]+\.[0-9]+|-?[0-9]+",line)
            startcap = dt.Vector(float(matchList[0]),float(matchList[1]),float(matchList[2]))
            endcap = dt.Vector(float(matchList[3]),float(matchList[4]),float(matchList[5]))
            nodeList = pm.modeling.polyCylinder(radius=float(matchList[6]), height=((startcap - endcap).length()))
            nodeList[0].translate.set((endcap - startcap)/2 + startcap)
            angle = htAimY(startcap - endcap)
            nodeList[0].rotate.set([angle[0],0,angle[1]])
        if re.search("sphere",line):
            line = filePointer.readline()
            matchList = re.findall("-?[0-9]+\.[0-9]+[eE][-+]?[0-9]+|-?[0-9]+\.[0-9]+|-?[0-9]+",line)
            nodeList = pm.modeling.polySphere(radius=float(matchList[3]))
            nodeList[0].translate.set([float(matchList[0]),float(matchList[1]),float(matchList[2])])
        line = filePointer.readline()
    filePointer.close()

色も持って来たい場合は「pigment」がそれですのでゴニョゴニョやればいいと思います。POV-Rayのフォーマットも参照してください。Cylinderの記述が「底面の中心点、上面の中心点、半径」とか…、一番メンドイところです。

コード中の正規表現が適当な上、乱暴にパースしてます。Avogadro自体をPythonで呼び出せそうなことが書いてあるので、povファイル経由するのは遠回りなんですけどね。まぁ動きます。あとPythonの変数のスコープってどーなってるの?変数名とかかぶってたらゴメンナサイ。

ちなみに下の分子はカテキン、最初のレンダリングしたものはトリプトファン。

importPOVToMaya

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です