Shade3D 公式

線形状と面の交点にコントロールポイントを追加するスクリプト


#1

線形状と面(XYZ軸と直角)の交点にコントロールポイントを追加するスクリプトです。
使い方

  1. 線形状を形状編集モードにする。
  2. コントロールポイントを追加したい区間の前のコントロールポイントを選択する。
  3. スクリプトを実行
  4. XYZ軸を選択
  5. 面の座標値を入力
  6. 交点が複数になる場合は何番目を選択するかを入力(0~)
  7. OKをクリック

注意事項
・自由曲面内の線形状の場合は兄弟の線形状も同じパラメータ位置にコントロールポイントを追加します。
・パートに変換が掛かっていると上手く行かないかも。(グローバル座標では計算している)
・UNDO出来ないので実行前に形状のコピーを取っておいた方が無難
・ローカル座標系ではうまく行かないでしょう。

from numpy.polynomial.polynomial import Polynomial

###############################################################################
def get_vec_x_mat (v, m, n=1):
	new_vec = []
	for i in xrange(3):
		new_vec.append(v[0]*m[0][i] + v[1]*m[1][i] + v[2]*m[2][i] + n*m[3][i])
	return new_vec

###############################################################################
def make_text(dialog, caption, text):
	text_index = dialog.append_text(caption, 1)
	dialog.set_value(text_index, text)
	dialog.set_default_value(text_index, text)
	return text_index

###############################################################################
def make_int(dialog, caption, value):
	int_index = dialog.append_int(caption, '')
	dialog.set_value(int_index, value)
	dialog.set_default_value(int_index, value)
	return int_index

###############################################################################
def make_double(dialog, caption, value):
	double_index = dialog.append_double(caption, '')
	dialog.set_value(double_index, value)
	dialog.set_default_value(double_index, value)
	return double_index

###############################################################################
def make_radio_button(dialog, caption, value):
	radio_button_index = dialog.append_radio_button(caption)
	dialog.set_value(radio_button_index, value)
	dialog.set_default_value(radio_button_index, value)
	return radio_button_index

###############################################################################
# ダイアログ設定 ##############################################################
###############################################################################
Xdialog = xshade.create_dialog()#dialogのインスタンス化
Xscene = xshade.scene()
Xshape = Xscene.active_shape()

if Xshape.type == 4:#線形状
	if Xscene.is_modify_mode == True:
		if Xshape.number_of_active_control_points == 1:
			axis_index = make_radio_button(Xdialog, '軸/X/Y/Z', 0)
			co_index = make_double(Xdialog, '面の座標', 0)
			skip_index = make_int(Xdialog, '交点位置', 0)

			if Xdialog.ask('コントロールポイント追加'):#OKボタン
				axis = Xdialog.get_value(axis_index)
				co = Xdialog.get_value(co_index)

				start_vi = Xshape.active_vertex_indices[0]
				start_cp = Xshape.control_point(start_vi)
				oh = start_cp.position
				if start_cp.has_out_handle == True:
					oh = start_cp.out_handle
				end_vi = start_vi + 1
				if end_vi < Xshape.number_of_control_points or Xshape.closed:
					if end_vi >= Xshape.number_of_control_points:
						end_vi = 0
					end_cp = Xshape.control_point(end_vi)
					ih = end_cp.position
					if end_cp.has_in_handle == True:
						ih = end_cp.in_handle

					pos0 = get_vec_x_mat(start_cp.position, Xshape.local_to_world_matrix)
					pos1 = get_vec_x_mat(oh, Xshape.local_to_world_matrix)
					pos2 = get_vec_x_mat(ih, Xshape.local_to_world_matrix)
					pos3 = get_vec_x_mat(end_cp.position, Xshape.local_to_world_matrix)

					f = Polynomial([pos0[axis] - co, (pos1[axis] - pos0[axis]) * 3, (pos2[axis] - pos1[axis] * 2 + pos0[axis]) * 3, pos3[axis] - (pos2[axis] - pos1[axis]) * 3 - pos0[axis]])
					r = f.roots()
					skip = Xdialog.get_value(skip_index)
					for p in r:
						if p.imag == 0 and p.real > 0 and p.real < 1:
							if skip > 0:
								skip = skip - 1
							else:
								at = start_vi + p.real
								dad = Xshape.dad
								if dad.type == 2:#パート
									if dad.part_type == 1:#自由曲面
										shape = dad.son
										while shape.has_bro:
											shape = shape.bro
											shape.insert_control_point(at)
									else:
										Xshape.insert_control_point(at)
								break
#	else:
#		TODO: 交差する区間を検索
#if Xshape.type == 2:#パート
#	if Xshape.part_type == 1:#自由曲面
#		TODO: 線形状それぞれと交差?