ひっさしぶりのCGの記事ですよ。誰が興味あんねんってな内容ですよ!
お仕事で、ある高分子をモデリングする必要があって、Avogadroと言うフリーソフトを見つけました。既知の分子構造はもちろん呼び出せますし、自分で分子をモデリングすることも出来、非常に興味深いのですが、残念なことに3Dの書き出しがPOV-Rayフォーマットしかありません。
つーことでpythonのお勉強を兼ねて読み込みスクリプトを書いてみました。
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の変数のスコープってどーなってるの?変数名とかかぶってたらゴメンナサイ。
ちなみに下の分子はカテキン、最初のレンダリングしたものはトリプトファン。

