マリオネットかプラグインオブジェクトか
昨日書いた記事でマリオネットとプラグインオブジェクトとどっちが良いか、と考えてる時に、シンプルなマリオネットだといいとこ取りできるのでは、と思ったので検証してみました。
マリオネットオブジェクト シンプル版
考え方は単純で、
こういう風に、入力ポートと本体の単純な構造にしたら、オブジェクトを作ったり修正したりも早くできるし、データも多少軽くなるだろうし、ファイル自体にスクリプトが含まれるので環境に左右されないしで、いいとこどりな気がします。
コード(コードという言葉とスクリプトと言う言葉の使い分けが分かってませんが)は下記のもので動きました。現状はフォルダ名をpop-upノードのスクリプトに直書きしないといけませんが、操作も単純になりました。
#Revised 12/21/15 MFarrell
#Modified by MFarrell May 2017
@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
#Name
this = Marionette.Node( "Setubi" )
this.SetDescription( "設備配置 " )
#Input Ports
sym3d = Marionette.PortIn( "", 'sSymName' )
offset = Marionette.PortIn( "0", 'sOffset' )
Write_z = Marionette.PortIn( False, 'bWZ' )
symz = Marionette.PortIn( 200, 'intZ')
#OIP Controls
#Output Ports
h = Marionette.PortOut()
h.SetDescription('Handle to Symbol object')
#BEHAVIOR
this.SetLinksObjects()
def RunNode(self):
#inputs
sym3d = self.Params.sym3d.value
off = self.Params.offset.value
Write_z = self.Params.Write_z.value
symz = self.Params.symz.value
#----------------------------------------------------------
#script-----------------------------------------------------
#----------------------------------------------------------
offset = int(off)
sym2d = sym3d + '-2D'
#2d locus
p = [(60,-52.5),(40,-52.5),(-60,-52.5),(-40,-52.5)]
for pt in p:
vs.Locus(pt)
sym = vs.LNewObj()
rhh=vs.GetParent(sym)
#3d symbol
p = (0,-65)
vs.Symbol(sym3d, p, 0)
sym = vs.LNewObj()
vs.Move3DObj(sym, 0, 0, symz )
#2d symbol
p=(0,-65-250*offset)
vs.Symbol(sym2d, p, 0)
sym = vs.LNewObj()
cName = vs.GetClass(sym)
#Rcord
vs.SetRecord(rhh, 'setubi')
vs.SetRField(rhh, 'setubi', 'name', sym3d)
vs.SetRField(rhh, 'setubi', 'type', cName)
#write Z
if Write_z :
ztx = 'H='+str(symz)
vs.MoveTo(110,-215-250*offset )
vs.TextSize(7)
vs.CreateText(ztx)
#----------------------------------------------------------
#end script--------------------------------------------------
#----------------------------------------------------------
#outputs
self.Params.h.value = sym
データ量の比較
関連するシンボルが入っただけのファイルに、標準的なノードで組んだマリオネットオブジェクト、今回のマリオネットシンプル版、前回のプラグインオブジェクト版のオブジェクトを0,1,2,100個置いたファイルサイズを比較してみました。
予想通り、マリオネット標準版はそこそこのサイズになりました。
プラグインオブジェクトは明らかに軽いですね。
でもマリオネットのシンプル版も想像以上に軽くなりました。
100個配置してこのサイズなら、使い勝手とのバランス考えると、今回のマリオネットのシンプル版がベストかな、という気がします。(将来、古いファイルがうまく作動しないというのが一番怖いので・・・)
いや、プラグインオブジェクトの配置の時の操作の使いやすさも捨てがたいな・・・
ファイル内のスクリプトで1点型オブジェクトと同じ動作を再現できたら、使い勝手的にも、データ量的にもベストなんだけどなー
追記:popupノードについて
popupノードはその選択肢を入力ポートから受け取ればいいのに、と思うのですが、おそらく仕様的に、inputの項目に同じくinputの項目を反映できないのだと思います。
今回のpopupノードは指定のフォルダからシンボル名を取得して選択肢にするようにしていますが、フォルダ名はノードのスクリプトに直書きしています。(情報パレットから入力できるようにできればベストなのですが、できないんじゃないかな・・・どうなんだろ)
popupノードの内容は下記のものに置き換える必要があります。
@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
#Name
this = Marionette.Node( 'Popup enhanced' )
this.SetDescription('This node displays a popup window and returns the index and string from the selection. The default settings must be changed in the code itself. ')
#Options
#_________Enter your values in the line below.__________
folder = '設備配置用3D'
symid =vs.FInFolder(vs.GetObject(folder))
symnames=[]
while vs.GetTypeN(symid) ==16:
symname=vs.GetName(symid)
symnames.append(symname)
symid=vs.NextSymDef(symid)
options = symnames
#Input Ports
#OIP Controls
input = Marionette.OIPControl( 'Popup', Marionette.WidgetType.Popup, 0, options)
input.SetDescription('An OIP control representing the options designated within the script editor')
#Output Ports
int = Marionette.PortOut('i')
int.SetDescription('The zero-based index of the selection.')
str = Marionette.PortOut('s')
str.SetDescription('The string of the selection.')
#BEHAVIOR
def RunNode(self):
#inputs
int = self.Params.input.value
options = self.Params.options
#script
str = options[int]
#outputs
self.Params.int.value = int
self.Params.str.value = str
また、選択結果は何番目のアイテムか、という受け取り方をしているので、細かい検証はしていませんが、フォルダ内の構成が変わった場合(シンボルが増えて項目の順番が変わるなど)などは、高さを変えるなどして再描画した時に、シンボルが入れ替わる可能性がありそうなのでご注意ください。
追記2:入力ノード名とコントロールポイント
さっき分かったのですが、入力ノードの順番は記述した順番に並ぶとは限らないようなので、ノード名に番号をつけたらその順で並んでくれるかな、と試してみたら、その順番だけで並ぶだけでなく、番号は情報パレットに表示されないので、そういう仕様っぽいです。
また、マリオネットだとコントロールポイントがうまく作動するので、2Dの表示位置をオフセット値を指定するのではなく、コントロールポイントで動かせるように変えました。
#Revised 12/21/15 MFarrell
#Modified by MFarrell May 2017
@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
#Name
this = Marionette.Node( "Setubi" )
this.SetDescription( "設備配置 " )
#Input Ports
sym3d = Marionette.PortIn( "", 'sSymName' )
p2d = Marionette.PortIn( (0,-65), 'pCP2D' )
Write_z = Marionette.PortIn( False, 'bWZ' )
symz = Marionette.PortIn( 200, 'intZ')
#OIP Controls
#Output Ports
h = Marionette.PortOut()
h.SetDescription('Handle to Symbol object')
#BEHAVIOR
this.SetLinksObjects()
def RunNode(self):
#inputs
sym3d = self.Params.sym3d.value
Write_z = self.Params.Write_z.value
symz = self.Params.symz.value
(px,py)=self.Params.p2d.value
#----------------------------------------------------------
#script-----------------------------------------------------
#----------------------------------------------------------
sym2d = sym3d + '-2D'
#2d locus
p = [(60,-52.5),(40,-52.5),(-60,-52.5),(-40,-52.5),(0,-65)]
for pt in p:
vs.Locus(pt)
sym = vs.LNewObj()
rhh=vs.GetParent(sym)
#3d symbol
p = (0,-65)
vs.Symbol(sym3d, p, 0)
sym = vs.LNewObj()
vs.Move3DObj(sym, 0, 0, symz )
#2d symbol
p=(px,py)
vs.Symbol(sym2d, p, 0)
sym = vs.LNewObj()
cName = vs.GetClass(sym)
#Rcord
vs.SetRecord(rhh, 'setubi')
vs.SetRField(rhh, 'setubi', 'name', sym3d)
vs.SetRField(rhh, 'setubi', 'type', cName)
#write Z
if Write_z :
ztx = 'H='+str(symz)
vs.MoveTo(px+110,py-150 )
vs.TextSize(7)
vs.CreateText(ztx)
#----------------------------------------------------------
#end script--------------------------------------------------
#----------------------------------------------------------
#outputs
self.Params.h.value = sym
この記事が気に入ったらサポートをしてみませんか?