Shade3D 公式

スクリプトの要望・紹介


#1

Shade3Dでの作業効率化にはスクリプトを活用すると便利です。
が、プログラミング要素もあるため、自作するにはとっかかりにくい面もあると思います。

一方で、スクリプトはBasicグレードでも使えるので、便利なスクリプトが広まるといいなと思います。

そこで、いつもこんな操作をしているのだけれど、同様のことができるスクリプトはないでしょうか?
という場合に、公開されているスクリプトを紹介し合える場にできればと思い作ってみました。
もしかしたらスクリプト職人さんが作ってくれるかも!?

参考
Shade3D公式のスクリプト集
https://shade3d.jp/training/shallwecustomize/

StrangeDaysさんのサイト
http://strangedays2008.seesaa.net/

Shadeプラグイン・スクリプト検索サイト
http://shade-search.com/sts/


#2

早速なのですが、選択した稜線列を1列飛ばしごとに選択できる
スクリプトがあればいいなと思っています。
もし公開されているスクリプトをご存知の方がいたら教えていただけないでしょうか。
さらに、選択した稜線を法線方向に拡大/縮小できるとなお良いのですが。

これができると、服などのシワ付けやヒダを作るのが楽になるので。
いつもは手で1列ずつ選択して拡大・縮小しています。


ファブリック(布もの)の形状作成に付いて
#3

便乗ですみません。
みなさん、スクリプトの仕様は、この辺のページを参考にされているのでしょうか?
http://help.shade3d.jp/ja/support/PythonScriptRefDoc/
実は、このURLは昔から記録してあるのですが、Shade3Dのトップページからの入り方がわかりません。
どなたか、トップページからの入り方をご存じでしたら教えて下さい。


#4

回答になっていないかもしれませんが、Shade3Dのヘルプメニュー内に「Shade3D Python スクリプトリファレンス」があり、そこからの参照が正式ルートのようです。

私も公式サイトのオンラインヘルプ探してみましたが、リンクからたどれるのは一般的なリファレンスマニュアルまでしか見つけられませんでした。


#5

Shade3Dを起動して、そのhelpから・・ 確認しました。(^^)

てっきりサイトのtopページから入れるのかと思っていましたが、
まさかShade3Dのhelp経由だったとは・・・

ありがとうございます。


#6

sisioumaru さん、こんにちわ。


提示されている sample のように、対象を四角形ポリゴンとして作ってみました。

三面稜線 が存在する polygon mesh はサポート対象外ですが、エラーチェックは省略してます。( Shade がクラッシュすることはないとは思いますが、確認していません )


Shade python の polygon mesh に対する関数 select_ring_edges() に3つのオプションを追加したようなものです。


step 数に 0 を指定すれば、可能な全範囲を対象にします

     


     

     step 数 : 0 / 間隔 : 0
     step 数 : 4 / 間隔 : 1


上図の 中心極回りの 3角形ポリゴン対象範囲外 なのは select_ring_edges() と同じです。




あまり使い道はないかもしれませんが、5角形以上 のポリゴンもサポートしています。( select_ring_edges() は4角形のみ )

ただし、4, 5, 6, ‥角形ポリゴンが混ざり合っているような構成では、エラーにはなりませんが、期待するような選択にはならないと思います。

     


3角形ポリゴンをサポートして、極部分も処理対象とできるようなものも作れそうな気がします。
今週末に考えてみます。

#  入力 dialog を開く
def open_dialog() :	
	#  dialog uuid は Online GUID Generator により生成		https://www.guidgenerator.com
	dialog = xshade.create_dialog_with_uuid('c2ebb39e-c536-43e5-a79e-8a48a110fd2e')

	dialog.begin_group('')
	idx_1 = dialog.append_int('step 数   ','    ( 0 以上、  0 は無制限 )')
	idx_2 = dialog.append_int('間隔   ','    ( 0 以上 )')
	idx_3 = dialog.append_bool('初期選択稜線を選択')
	dialog.set_value(idx_3 , True)
	dialog.end_group()

	if not dialog.ask('稜線 step 選択'):
		return None	
	
	step = dialog.get_value(idx_1)
	if step < 0 :
		print 'step 数は 0 以上の整数にして下さい'
		return None
			
	interval =  dialog.get_value(idx_2)
	if interval < 0 :
		print '間隔は正の整数にして下さい'
		return None
			
	initial_edges = dialog.get_value(idx_3)
		
	return [step, interval, initial_edges]
		
		
		
		
#  polygonmesh object と 選択稜線 list を返す	[ob, active_edge_list]
def get_object() :
	ob = scene.active_shape()

	#	選択 object check
	if ob == None :
		print 'ポリゴンメッシュを選択して下さい'
		return None
	
	if not isinstance(ob, xshade.polygon_mesh) :
		print 'ポリゴンメッシュを選択して下さい'
		return None
	
	#	modify mode check
	if not scene.is_modify_mode :
		print 'modify mode に入って稜線を選択して下さい'
		return None
	
	if scene.selection_mode != 1 :
		print '稜線選択モードに切り替えて、稜線を選択して下さい'
		return None

	#   選択稜線 list 取得
	active_edge_list = ob.active_edge_indices
	if len(active_edge_list) == 0 :
		print '稜線を選択して下さい'
		return None

	return [ob, active_edge_list]

	

	
#  edge list 作成
def get_edge_list(ob, active_edge_list, check_fL) :
	fL = []								#  選択稜線に接続する面の list
	ob.setup_winged_edge()
	for e in active_edge_list :
		p = ob.edge(e).v0
		f = ob.fccwev(e, p, False)		#  三面稜線に対するチェックは省略	
		if f >= 0 :
			if not check_fL[f] :
				fL.append(f)
		f = ob.fcwev(e, p, False)		#  三面稜線に対するチェックは省略
		if f >= 0 :
			if not check_fL[f] :
				fL.append(f)

	if len(fL) == 0 :
		return None						#  探査終了

		
	eL = []								#  fL で与えられる面群に所属する 稜線 list
	for f in fL :
		pL = ob.face(f).vertex_indices
		for p in pL :
			e = ob.eccwfv(f, p, False)	#  三面稜線に対するチェックは省略				
			eL.append(e)				#  eL の要素には重複あり
	ob.clean_winged_edge()
	
	ob.active_edge_indices = active_edge_list
	ob.select_grow()
	eL2 = ob.active_edge_indices		#  選択稜線を拡張した 稜線 list
	eL3 = list(set(eL) - set(eL2))		#  eL と eL2 の差分 list

	for f in fL :
		check_fL[f] = True				#  処理対象外面情報を与える bool list の更新
		
	return eL3


	

def main() :
	#  入力
	data = open_dialog()
	if data == None :
		return
	else :
		[step, interval, initial_edges] = data		#  step 数, 間隔, 初期選択稜線の 選択 flag
		
		
	#   polygonmesh object と 選択稜線 list を取得	[ob, active_edge_list]
	L = get_object()
	if L == None :
		return
	else :
		[ob, active_edge_list] = L
		

		
	if initial_edges :
		aeL = list(active_edge_list	)			#  最終的に選択される 稜線 list
	else :
		aeL = []								#  最終的に選択される 稜線 list	
	count = 0
	k = 0
	nof = ob.number_of_faces
	check_fL = [False for i in range(nof)]		#  処理対象外面情報を与える bool list
	
	while True :
		eL = get_edge_list(ob, active_edge_list, check_fL)
		if (eL == None) or (len(eL) == 0) :
			break
	
		count += 1
		if count % (interval + 1) == 0 :
			k += 1
			aeL = aeL + eL
			if k == step :
				break

		active_edge_list = eL
		
	ob.active_edge_indices = aeL
	return
		

		
		
scene = xshade.scene()
main()

作りかけやテスト作品投稿スレッド
#7

早速作ってくださりありがとうございます!!

すごいですね、これ。
やりたかったことがどんぴしゃりでできるようになりました。
こんなにすぐに作っていただけたのは感激です。

布のシワ作りにすごく便利なので、さっそく活用させていただきます。


#8

いつも訊いてばかりで恐縮です。

(ポリゴンの)頂点をスムーズにする方法/スクリプトをご存知の方がいましたら、
紹介いただけないでしょうか。

Shade3D標準機能にも「スムーズ」があることは知っています。
例えば添付図の場合、使ってみると、理想とは違うスムーズがかかります。
本当は上下方向だけで滑らかな曲線にスムーズにしてほしいのに対して、
標準機能だと左右方向にも位置調整が入ってしまいます。

こういうのを数式で表すのは難しい(人間の感覚できまるため)のだろうと、薄々予想しています。
もしうまくスムーズできる手段がありましたら教えてくださいm(_ _)m


#9

3Dプリント向けフィギュアデータを作っていると、ポーズを付けたモデルのままボーン(バインド)を削除したいケースがありました。(ボーンに制限されずにポーズや大きさを微調整したかったため)

ちょうどナレッジベースでポーズを付けた後のスキンの削除方法が紹介されていました。
https://knowledge.shade3d.jp/?s=スキン&post_type=kbe_knowledgebase

しかし、この方法ですとパーツ1個1個ずつ削除操作をしなくてはいけないので、大量にあると大変です。
困っていたところ、masaさん


が便利なスクリプトを作ってくださったので紹介します。(ここでの紹介について承諾いただいています)

スキンを削除したい形状/パートを選択した状態で、下記のスクリプトを実行するだけで、選択した分に対してスキンが削除されます。
具体的には下記スクリプト(#ここから 以下)をコピー&ペーストし、「スクリプト」ウインドウに貼り付けて実行するだけです。
私はポーズ付け後はボーンを削除したケースがあるため、重宝しそうです。

#ここから
#!/usr/bin/python

-- coding: utf-8 --

This Python file uses the following encoding: utf-8

選択された形状のスキンをクリアする.

def clear_shapes_skin(shape):
if (0 < shape.number_of_skin_points) and (shape.skin_type != -1):
shape.select_all_control_points(True)
shape.clear_skin()
shape.select_all_control_points(False)
if shape.has_son:
son = shape.son.bro
while son.type != 0:
clear_all_shapes(son)
son = son.bro
xshade.scene().enter_modify_mode()
for s in xshade.scene().active_shapes:
clear_shapes_skin(s)
xshade.scene().exit_modify_mode()
#ここまで