ひっさしぶりの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の変数のスコープってどーなってるの?変数名とかかぶってたらゴメンナサイ。
ちなみに下の分子はカテキン、最初のレンダリングしたものはトリプトファン。