2023年09月11日

Pyside2を使ったカスタムUI modo16 その79

前回は「dist(p1,p2)」関数を追加して頂点選択する条件式で使えるようにしてみた。その時に引数として渡す頂点を調査する頂点は「p」で、もう一方の頂点は暫定的に「p0」を定数で設定していた。今回はこの「p0」部分をリストに取得済みの頂点の番号から指定できるようにしてみた。変更はいたってシンプルで、以下のように「calc()」メソッドを1行書き換えただけだ。

       :
       :
class MyModel(QAbstractTableModel):
	def __init__(self,parent=None):
		super(MyModel,self).__init__(parent)
		
       :
       :

	def calc(self,exp,n):
		v = self.__points
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)

       :
       :

例えば186番目の頂点であれば式の中で「v[186]」と表記する事で参照できる。

fig1

下のように式を書けばこの186番目の頂点から0.3未満の距離にある頂点が選択の条件を満たすことになる。

fig2

これが式を適用した結果。186の頂点を中心に頂点が選択されているのが確認できる。

fig3

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2023年09月04日

Pyside2を使ったカスタムUI modo16 その78

今回は頂点選択の式に距離関数「dist(p1,p2)」を追加してみた。式の中で使うので「self」とか付けたくないのでクラスの外で定義している。

import modo
import lx
import lxu
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

def dist(p1,p2):
	return ((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2 + (p1[2]-p2[2])**2 ) ** 0.5

class MyModel(QAbstractTableModel):
	def __init__(self,parent=None):
		super(MyModel,self).__init__(parent)
		
		self.__points = []
		self.__labels = ['x','y','z']
		
		self.update()

	def update(self):
		self.beginResetModel()
		self.mesh = modo.Mesh()
		self.__points = []
		if self.mesh:
			verts = self.mesh.geometry.vertices
			for v in verts:
				self.__points.append(list(v.position))
		else:
			print('No Mesh Selected')
		self.endResetModel()

	def rowCount(self,parent=None):
		return len(self.__points)
		
	def columnCount(self,parent):
		return 3
		
	def data(self,index,role):
		if role == Qt.DisplayRole:
			return self.__points[index.row()][index.column()]

	def setData(self,index,value):
		i = index.row()
		j = index.column()
		self.__points[i][j] = value
		lx.eval('vertMap.setVertex position position %s %s %s' % (j,i,value))
				
	def flags(self, index):
		if not index.isValid():
			return 0
		return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
		
	def headerData(self,section,orientation,role):
		if role == Qt.DisplayRole:
			if orientation == Qt.Horizontal:
				return self.__labels[section]
			else:
				return str(section)

	def calc(self,exp,n):
		p0 = [0.5,0,0]
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)
				
class MyItemDelegate(QItemDelegate):
	def __init__(self, parent=None):
		super(MyItemDelegate, self).__init__(parent)
		
	def createEditor(self, parent, option, index):
		return QLineEdit(parent)

	def setEditorData(self, editor, index):
		value = str(index.model().data(index, Qt.DisplayRole))
		editor.setText(value)

	def setModelData(self, editor, model, index):
		try:
			value = float(editor.text())
			model.setData(index, value)
		except ValueError:
			pass
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.model = MyModel()
		self.tableView = QTableView(self)
		self.tableView.setModel(self.model)
		self.delegate = MyItemDelegate(self.tableView)
		self.tableView.setItemDelegate(self.delegate)
		
		self.leExpression = QLineEdit()
		
		self.pbClrSelect = QPushButton('Select')
		self.pbAddSelect = QPushButton('Add')
		self.pbSubSelect = QPushButton('Sub')
		self.pbClrSelect.clicked.connect(self.clrSelect)
		self.pbAddSelect.clicked.connect(self.addSelect)
		self.pbSubSelect.clicked.connect(self.subSelect)
		
		self.pbNewPick = QPushButton('New Set')
		self.pbRmvPick = QPushButton('Remove Set')
		self.pbClrPick = QPushButton('Select Set')
		self.pbAddPick = QPushButton('Add Set')
		self.pbSubPick = QPushButton('Sub Set')
		self.pbNewPick.clicked.connect(self.newPick)
		self.pbRmvPick.clicked.connect(self.removePick)
		self.pbClrPick.clicked.connect(self.selectPick)
		self.pbAddPick.clicked.connect(self.addPick)
		self.pbSubPick.clicked.connect(self.subPick)
		
		self.cbPick = QComboBox()
		self.cbUpdate()
		
		self.cbAxis = QComboBox()
		self.cbAxis.addItems(['X','Y','Z'])
		self.leValue = QDoubleSpinBox()
		self.leValue.setDecimals(3)
		self.leValue.setRange(-sys.float_info.max,sys.float_info.max)
		self.leValue.setSingleStep(0.1)
		self.pbSetValues = QPushButton('Set Value')
		self.pbSetValues.clicked.connect(self.setValues)
		
		self.updatetable = True
		
		self.tableView.selectionModel().selectionChanged.connect(self.updateSelect)
		
		mainlayout = QVBoxLayout(self)
		sublayout1 = QHBoxLayout()
		sublayout2 = QHBoxLayout()
		sublayout3 = QHBoxLayout()

		mainlayout.addWidget(self.tableView)
		sublayout1.addWidget(self.leExpression)
		sublayout1.addWidget(self.pbClrSelect)
		sublayout1.addWidget(self.pbAddSelect)
		sublayout1.addWidget(self.pbSubSelect)
		
		gbExSelection = QGroupBox('Expression')
		gbExSelection.setLayout(sublayout1)

		sublayout2.addWidget(self.cbPick)
		sublayout2.addWidget(self.pbNewPick)
		sublayout2.addWidget(self.pbRmvPick)
		sublayout2.addWidget(self.pbClrPick)
		sublayout2.addWidget(self.pbAddPick)
		sublayout2.addWidget(self.pbSubPick)
		
		gbSelectionSet = QGroupBox('Selection Set')
		gbSelectionSet.setLayout(sublayout2)
		
		sublayout3.addWidget(self.cbAxis)
		sublayout3.addWidget(self.leValue)
		sublayout3.addWidget(self.pbSetValues)
		
		gbSetValue = QGroupBox('Set Value')
		gbSetValue.setLayout(sublayout3)

		mainlayout.addWidget(gbExSelection)
		mainlayout.addWidget(gbSelectionSet)
		mainlayout.addWidget(gbSetValue)
		
		self.parent = self.tableView.currentIndex()

		self.resize(320, 230)
		self.setWindowFlags(Qt.WindowStaysOnTopHint)
		self.updateTable()
		
	def cbUpdate(self):
		self.cbPick.clear()
		lx.eval('query layerservice layer.index ? main')
		vn = lx.eval('query layerservice vmap.N ? all')
		for i in range(vn):
			if lx.eval('query layerservice vmap.type ? %d' % i) == 'pick':
				pickName = lx.eval('query layerservice vmap.name ? %d' % i)
				self.cbPick.addItem(pickName)

	def clrSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.tableView.selectionModel().clear()
		lx.command('select.clear',type='vertex')
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def addSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def subSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Deselect
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='remove',index=i)

	def updateTable(self):
		self.updatetable = False
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.model.update()
		self.tableView.update()
		layer_index = lx.eval('query layerservice layers ? main')
		self.tableView.selectionModel().clear()
		for i in range(self.model.rowCount()):
			if lx.eval('query layerservice vert.selected ? %s' % i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
		self.updatetable = True
				
	def updateSelect(self):
		if self.updatetable :
			lx.command('select.clear',type='vertex')
			layer_index = lx.eval('query layerservice layers ? main')
			for index in self.tableView.selectionModel().selectedRows():
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=index.row())

	def newPick(self):
		lx.command('select.editSet')
		self.cbUpdate()
		
	def removePick(self):
		lx.eval('select.deleteSet %s' % self.cbPick.currentText())
		self.cbUpdate()
				
	def selectPick(self):
		lx.eval('select.useSet %s replace' % self.cbPick.currentText())
		self.updateTable()
		
	def addPick(self):
		lx.eval('select.useSet %s select' % self.cbPick.currentText())
		self.updateTable()
		
	def subPick(self):
		lx.eval('select.useSet %s deselect' % self.cbPick.currentText())
		self.updateTable()
		
	def setValues(self):
		axis = self.cbAxis.currentText()
		value = self.leValue.value()
		lx.command('vert.set',axis = axis,value = value)
		self.updateTable()

	def keyPressEvent(self, event):
		super().keyPressEvent(event)
		if (event.modifiers() & Qt.ControlModifier) and event.key() == Qt.Key_Z:
			if event.modifiers() & Qt.ShiftModifier :
				lx.command('!app.redo')
			else:				
				lx.command('!app.undo')
			self.updateTable()
			
	def paintEvent(self,event):
		if not self.isActiveWindow():
			self.updateTable()
		
w = MyDialog()
w.show()

今のところ調べる側の頂点の座標値は式内で「p」と表現できるけど、もう一方の座標値は無いので暫定的にプログラムの中で「p0」を定義している。

	def calc(self,exp,n):
		p0 = [0.5,0,0]
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)

これを使って下のように式を書いて球体表面の頂点を選択してみた。

fig1

これがその結果。

fig2

p0(0.5,0,0)の座標から半径 0.3以内の頂点が選択された。

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2023年07月24日

Pyside2を使ったカスタムUI modo16 その77

ダイアログにコントロールが増えて来たのでグループボックスにまとめてみた。

import modo
import lx
import lxu
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyModel(QAbstractTableModel):
	def __init__(self,parent=None):
		super(MyModel,self).__init__(parent)
		
		self.__points = []
		self.__labels = ['x','y','z']
		
		self.update()

	def update(self):
		self.beginResetModel()
		self.mesh = modo.Mesh()
		self.__points = []
		if self.mesh:
			verts = self.mesh.geometry.vertices
			for v in verts:
				self.__points.append(list(v.position))
		else:
			print('No Mesh Selected')
		self.endResetModel()

	def rowCount(self,parent=None):
		return len(self.__points)
		
	def columnCount(self,parent):
		return 3
		
	def data(self,index,role):
		if role == Qt.DisplayRole:
			return self.__points[index.row()][index.column()]

	def setData(self,index,value):
		i = index.row()
		j = index.column()
		self.__points[i][j] = value
		lx.eval('vertMap.setVertex position position %s %s %s' % (j,i,value))
				
	def flags(self, index):
		if not index.isValid():
			return 0
		return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
		
	def headerData(self,section,orientation,role):
		if role == Qt.DisplayRole:
			if orientation == Qt.Horizontal:
				return self.__labels[section]
			else:
				return str(section)

	def calc(self,exp,n):
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)
				
class MyItemDelegate(QItemDelegate):
	def __init__(self, parent=None):
		super(MyItemDelegate, self).__init__(parent)
		
	def createEditor(self, parent, option, index):
		return QLineEdit(parent)

	def setEditorData(self, editor, index):
		value = str(index.model().data(index, Qt.DisplayRole))
		editor.setText(value)

	def setModelData(self, editor, model, index):
		try:
			value = float(editor.text())
			model.setData(index, value)
		except ValueError:
			pass
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.model = MyModel()
		self.tableView = QTableView(self)
		self.tableView.setModel(self.model)
		self.delegate = MyItemDelegate(self.tableView)
		self.tableView.setItemDelegate(self.delegate)
		
		self.leExpression = QLineEdit()
		
		self.pbClrSelect = QPushButton('Select')
		self.pbAddSelect = QPushButton('Add')
		self.pbSubSelect = QPushButton('Sub')
		self.pbClrSelect.clicked.connect(self.clrSelect)
		self.pbAddSelect.clicked.connect(self.addSelect)
		self.pbSubSelect.clicked.connect(self.subSelect)
		
		self.pbNewPick = QPushButton('New Set')
		self.pbRmvPick = QPushButton('Remove Set')
		self.pbClrPick = QPushButton('Select Set')
		self.pbAddPick = QPushButton('Add Set')
		self.pbSubPick = QPushButton('Sub Set')
		self.pbNewPick.clicked.connect(self.newPick)
		self.pbRmvPick.clicked.connect(self.removePick)
		self.pbClrPick.clicked.connect(self.selectPick)
		self.pbAddPick.clicked.connect(self.addPick)
		self.pbSubPick.clicked.connect(self.subPick)
		
		self.cbPick = QComboBox()
		self.cbUpdate()
		
		self.cbAxis = QComboBox()
		self.cbAxis.addItems(['X','Y','Z'])
		self.leValue = QDoubleSpinBox()
		self.leValue.setDecimals(3)
		self.leValue.setRange(-sys.float_info.max,sys.float_info.max)
		self.leValue.setSingleStep(0.1)
		self.pbSetValues = QPushButton('Set Value')
		self.pbSetValues.clicked.connect(self.setValues)
		
		self.updatetable = True
		
		self.tableView.selectionModel().selectionChanged.connect(self.updateSelect)
		
		mainlayout = QVBoxLayout(self)
		sublayout1 = QHBoxLayout()
		sublayout2 = QHBoxLayout()
		sublayout3 = QHBoxLayout()

		mainlayout.addWidget(self.tableView)
		sublayout1.addWidget(self.leExpression)
		sublayout1.addWidget(self.pbClrSelect)
		sublayout1.addWidget(self.pbAddSelect)
		sublayout1.addWidget(self.pbSubSelect)
		
		gbExSelection = QGroupBox('Expression')
		gbExSelection.setLayout(sublayout1)

		sublayout2.addWidget(self.cbPick)
		sublayout2.addWidget(self.pbNewPick)
		sublayout2.addWidget(self.pbRmvPick)
		sublayout2.addWidget(self.pbClrPick)
		sublayout2.addWidget(self.pbAddPick)
		sublayout2.addWidget(self.pbSubPick)
		
		gbSelectionSet = QGroupBox('Selection Set')
		gbSelectionSet.setLayout(sublayout2)
		
		sublayout3.addWidget(self.cbAxis)
		sublayout3.addWidget(self.leValue)
		sublayout3.addWidget(self.pbSetValues)
		
		gbSetValue = QGroupBox('Set Value')
		gbSetValue.setLayout(sublayout3)

		mainlayout.addWidget(gbExSelection)
		mainlayout.addWidget(gbSelectionSet)
		mainlayout.addWidget(gbSetValue)
		
		self.parent = self.tableView.currentIndex()

		self.resize(320, 230)
		self.setWindowFlags(Qt.WindowStaysOnTopHint)
		self.updateTable()
		
	def cbUpdate(self):
		self.cbPick.clear()
		lx.eval('query layerservice layer.index ? main')
		vn = lx.eval('query layerservice vmap.N ? all')
		for i in range(vn):
			if lx.eval('query layerservice vmap.type ? %d' % i) == 'pick':
				pickName = lx.eval('query layerservice vmap.name ? %d' % i)
				self.cbPick.addItem(pickName)

	def clrSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.tableView.selectionModel().clear()
		lx.command('select.clear',type='vertex')
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def addSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def subSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Deselect
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='remove',index=i)

	def updateTable(self):
		self.updatetable = False
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.model.update()
		self.tableView.update()
		layer_index = lx.eval('query layerservice layers ? main')
		self.tableView.selectionModel().clear()
		for i in range(self.model.rowCount()):
			if lx.eval('query layerservice vert.selected ? %s' % i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
		self.updatetable = True
				
	def updateSelect(self):
		if self.updatetable :
			lx.command('select.clear',type='vertex')
			layer_index = lx.eval('query layerservice layers ? main')
			for index in self.tableView.selectionModel().selectedRows():
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=index.row())

	def newPick(self):
		lx.command('select.editSet')
		self.cbUpdate()
		
	def removePick(self):
		lx.eval('select.deleteSet %s' % self.cbPick.currentText())
		self.cbUpdate()
				
	def selectPick(self):
		lx.eval('select.useSet %s replace' % self.cbPick.currentText())
		self.updateTable()
		
	def addPick(self):
		lx.eval('select.useSet %s select' % self.cbPick.currentText())
		self.updateTable()
		
	def subPick(self):
		lx.eval('select.useSet %s deselect' % self.cbPick.currentText())
		self.updateTable()
		
	def setValues(self):
		axis = self.cbAxis.currentText()
		value = self.leValue.value()
		lx.command('vert.set',axis = axis,value = value)
		self.updateTable()

	def keyPressEvent(self, event):
		super().keyPressEvent(event)
		if (event.modifiers() & Qt.ControlModifier) and event.key() == Qt.Key_Z:
			if event.modifiers() & Qt.ShiftModifier :
				lx.command('!app.redo')
			else:				
				lx.command('!app.undo')
			self.updateTable()
			
	def paintEvent(self,event):
		if not self.isActiveWindow():
			self.updateTable()
		
w = MyDialog()
w.show()

これが実行結果。

fig 1

続きはまた次回。

次回は9月4日になります。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2023年07月10日

Pyside2を使ったカスタムUI modo16 その76

頂点がまとめて選択出来るようになっているけど今のところ値は1つずつしか編集できないので、そろそろまとめて値を変更出来るようにしてみた。

変更したい座標軸を選んで変更後の値を入力して「Set Value」ボタンを押す方式にしてみた。

import modo
import lx
import lxu
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyModel(QAbstractTableModel):
	def __init__(self,parent=None):
		super(MyModel,self).__init__(parent)
		
		self.__points = []
		self.__labels = ['x','y','z']
		
		self.update()

	def update(self):
		self.beginResetModel()
		self.mesh = modo.Mesh()
		self.__points = []
		if self.mesh:
			verts = self.mesh.geometry.vertices
			for v in verts:
				self.__points.append(list(v.position))
		else:
			print('No Mesh Selected')
		self.endResetModel()

	def rowCount(self,parent=None):
		return len(self.__points)
		
	def columnCount(self,parent):
		return 3
		
	def data(self,index,role):
		if role == Qt.DisplayRole:
			return self.__points[index.row()][index.column()]

	def setData(self,index,value):
		i = index.row()
		j = index.column()
		self.__points[i][j] = value
		lx.eval('vertMap.setVertex position position %s %s %s' % (j,i,value))
				
	def flags(self, index):
		if not index.isValid():
			return 0
		return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
		
	def headerData(self,section,orientation,role):
		if role == Qt.DisplayRole:
			if orientation == Qt.Horizontal:
				return self.__labels[section]
			else:
				return str(section)

	def calc(self,exp,n):
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)
				
class MyItemDelegate(QItemDelegate):
	def __init__(self, parent=None):
		super(MyItemDelegate, self).__init__(parent)
		
	def createEditor(self, parent, option, index):
		return QLineEdit(parent)

	def setEditorData(self, editor, index):
		value = str(index.model().data(index, Qt.DisplayRole))
		editor.setText(value)

	def setModelData(self, editor, model, index):
		try:
			value = float(editor.text())
			model.setData(index, value)
		except ValueError:
			pass
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.model = MyModel()
		self.tableView = QTableView(self)
		self.tableView.setModel(self.model)
		self.delegate = MyItemDelegate(self.tableView)
		self.tableView.setItemDelegate(self.delegate)
		
		self.leExpression = QLineEdit()
		
		self.pbClrSelect = QPushButton('Select')
		self.pbAddSelect = QPushButton('Add')
		self.pbSubSelect = QPushButton('Sub')
		self.pbClrSelect.clicked.connect(self.clrSelect)
		self.pbAddSelect.clicked.connect(self.addSelect)
		self.pbSubSelect.clicked.connect(self.subSelect)
		
		self.pbNewPick = QPushButton('New Set')
		self.pbRmvPick = QPushButton('Remove Set')
		self.pbClrPick = QPushButton('Select Set')
		self.pbAddPick = QPushButton('Add Set')
		self.pbSubPick = QPushButton('Sub Set')
		self.pbNewPick.clicked.connect(self.newPick)
		self.pbRmvPick.clicked.connect(self.removePick)
		self.pbClrPick.clicked.connect(self.selectPick)
		self.pbAddPick.clicked.connect(self.addPick)
		self.pbSubPick.clicked.connect(self.subPick)
		
		self.cbPick = QComboBox()
		self.cbUpdate()
		
		self.cbAxis = QComboBox()
		self.cbAxis.addItems(['X','Y','Z'])
		self.leValue = QDoubleSpinBox()
		self.leValue.setDecimals(3)
		self.leValue.setRange(-sys.float_info.max,sys.float_info.max)
		self.leValue.setSingleStep(0.1)
		self.pbSetValues = QPushButton('Set Value')
		self.pbSetValues.clicked.connect(self.setValues)
		
		self.updatetable = True
		
		self.tableView.selectionModel().selectionChanged.connect(self.updateSelect)
		
		mainlayout = QVBoxLayout(self)
		sublayout1 = QHBoxLayout()
		sublayout2 = QHBoxLayout()
		sublayout3 = QHBoxLayout()

		mainlayout.addWidget(self.tableView)
		sublayout1.addWidget(self.leExpression)
		sublayout1.addWidget(self.pbClrSelect)
		sublayout1.addWidget(self.pbAddSelect)
		sublayout1.addWidget(self.pbSubSelect)

		sublayout2.addWidget(self.cbPick)
		sublayout2.addWidget(self.pbNewPick)
		sublayout2.addWidget(self.pbRmvPick)
		sublayout2.addWidget(self.pbClrPick)
		sublayout2.addWidget(self.pbAddPick)
		sublayout2.addWidget(self.pbSubPick)
		
		sublayout3.addWidget(self.cbAxis)
		sublayout3.addWidget(self.leValue)
		sublayout3.addWidget(self.pbSetValues)

		mainlayout.addLayout(sublayout1)
		mainlayout.addLayout(sublayout2)
		mainlayout.addLayout(sublayout3)
		
		self.parent = self.tableView.currentIndex()

		self.resize(320, 230)
		self.setWindowFlags(Qt.WindowStaysOnTopHint)
		self.updateTable()
		
	def cbUpdate(self):
		self.cbPick.clear()
		lx.eval('query layerservice layer.index ? main')
		vn = lx.eval('query layerservice vmap.N ? all')
		for i in range(vn):
			if lx.eval('query layerservice vmap.type ? %d' % i) == 'pick':
				pickName = lx.eval('query layerservice vmap.name ? %d' % i)
				self.cbPick.addItem(pickName)

	def clrSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.tableView.selectionModel().clear()
		lx.command('select.clear',type='vertex')
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def addSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def subSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Deselect
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='remove',index=i)

	def updateTable(self):
		self.updatetable = False
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.model.update()
		self.tableView.update()
		layer_index = lx.eval('query layerservice layers ? main')
		self.tableView.selectionModel().clear()
		for i in range(self.model.rowCount()):
			if lx.eval('query layerservice vert.selected ? %s' % i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
		self.updatetable = True
				
	def updateSelect(self):
		if self.updatetable :
			lx.command('select.clear',type='vertex')
			layer_index = lx.eval('query layerservice layers ? main')
			for index in self.tableView.selectionModel().selectedRows():
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=index.row())

	def newPick(self):
		lx.command('select.editSet')
		self.cbUpdate()
		
	def removePick(self):
		lx.eval('select.deleteSet %s' % self.cbPick.currentText())
		self.cbUpdate()
				
	def selectPick(self):
		lx.eval('select.useSet %s replace' % self.cbPick.currentText())
		self.updateTable()
		
	def addPick(self):
		lx.eval('select.useSet %s select' % self.cbPick.currentText())
		self.updateTable()
		
	def subPick(self):
		lx.eval('select.useSet %s deselect' % self.cbPick.currentText())
		self.updateTable()
		
	def setValues(self):
		axis = self.cbAxis.currentText()
		value = self.leValue.value()
		lx.command('vert.set',axis = axis,value = value)
		self.updateTable()

	def keyPressEvent(self, event):
		super().keyPressEvent(event)
		if (event.modifiers() & Qt.ControlModifier) and event.key() == Qt.Key_Z:
			if event.modifiers() & Qt.ShiftModifier :
				lx.command('!app.redo')
			else:				
				lx.command('!app.undo')
			self.updateTable()
			
	def paintEvent(self,event):
		if not self.isActiveWindow():
			self.updateTable()
		
w = MyDialog()
w.show()

これが実行結果。

fig 1

x座標値が−0.3未満の頂点を選択しておいて、それらのx座標値を−0.3にしてみた。それで気が付いたんだけど−0.3にせっていしたけどリストに表示したらぴったりの数字になっていない。表現できる数値の精度を超えて表示しちゃってるのが原因なのかな。

fig 2;

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2023年07月03日

Pyside2を使ったカスタムUI modo16 その75

前回追加したボタンに機能を割り当てた。これで頂点の選択セットを追加したり削除したり選択したり、追加選択したり、除外したり出来るようになった。

import modo
import lx
import lxu
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyModel(QAbstractTableModel):
	def __init__(self,parent=None):
		super(MyModel,self).__init__(parent)
		
		self.__points = []
		self.__labels = ['x','y','z']
		
		self.update()

	def update(self):
		self.beginResetModel()
		self.mesh = modo.Mesh()
		self.__points = []
		if self.mesh:
			verts = self.mesh.geometry.vertices
			for v in verts:
				self.__points.append(list(v.position))
		else:
			print('No Mesh Selected')
		self.endResetModel()

	def rowCount(self,parent=None):
		return len(self.__points)
		
	def columnCount(self,parent):
		return 3
		
	def data(self,index,role):
		if role == Qt.DisplayRole:
			return self.__points[index.row()][index.column()]

	def setData(self,index,value):
		i = index.row()
		j = index.column()
		self.__points[i][j] = value
		lx.eval('vertMap.setVertex position position %s %s %s' % (j,i,value))
				
	def flags(self, index):
		if not index.isValid():
			return 0
		return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
		
	def headerData(self,section,orientation,role):
		if role == Qt.DisplayRole:
			if orientation == Qt.Horizontal:
				return self.__labels[section]
			else:
				return str(section)

	def calc(self,exp,n):
		p = self.__points[n]
		x = p[0]
		y = p[1]
		z = p[2]
		return eval(exp)
				
class MyItemDelegate(QItemDelegate):
	def __init__(self, parent=None):
		super(MyItemDelegate, self).__init__(parent)
		
	def createEditor(self, parent, option, index):
		return QLineEdit(parent)

	def setEditorData(self, editor, index):
		value = str(index.model().data(index, Qt.DisplayRole))
		editor.setText(value)

	def setModelData(self, editor, model, index):
		try:
			value = float(editor.text())
			model.setData(index, value)
		except ValueError:
			pass
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.model = MyModel()
		self.tableView = QTableView(self)
		self.tableView.setModel(self.model)
		self.delegate = MyItemDelegate(self.tableView)
		self.tableView.setItemDelegate(self.delegate)
		
		self.leExpression = QLineEdit()
		
		self.pbClrSelect = QPushButton('Select')
		self.pbAddSelect = QPushButton('Add')
		self.pbSubSelect = QPushButton('Sub')
		self.pbClrSelect.clicked.connect(self.clrSelect)
		self.pbAddSelect.clicked.connect(self.addSelect)
		self.pbSubSelect.clicked.connect(self.subSelect)
		
		self.pbNewPick = QPushButton('New Set')
		self.pbRmvPick = QPushButton('Remove Set')
		self.pbClrPick = QPushButton('Select Set')
		self.pbAddPick = QPushButton('Add Set')
		self.pbSubPick = QPushButton('Sub Set')
		self.pbNewPick.clicked.connect(self.newPick)
		self.pbRmvPick.clicked.connect(self.removePick)
		self.pbClrPick.clicked.connect(self.selectPick)
		self.pbAddPick.clicked.connect(self.addPick)
		self.pbSubPick.clicked.connect(self.subPick)
		
		self.cbPick = QComboBox()
		self.cbUpdate()
		
		self.updatetable = True
		
		self.tableView.selectionModel().selectionChanged.connect(self.updateSelect)
		
		mainlayout = QVBoxLayout(self)
		sublayout1 = QHBoxLayout()
		sublayout2 = QHBoxLayout()

		mainlayout.addWidget(self.tableView)
		sublayout1.addWidget(self.leExpression)
		sublayout1.addWidget(self.pbClrSelect)
		sublayout1.addWidget(self.pbAddSelect)
		sublayout1.addWidget(self.pbSubSelect)

		sublayout2.addWidget(self.cbPick)
		sublayout2.addWidget(self.pbNewPick)
		sublayout2.addWidget(self.pbRmvPick)
		sublayout2.addWidget(self.pbClrPick)
		sublayout2.addWidget(self.pbAddPick)
		sublayout2.addWidget(self.pbSubPick)

		mainlayout.addLayout(sublayout1)
		mainlayout.addLayout(sublayout2)
		
		self.parent = self.tableView.currentIndex()

		self.resize(320, 230)
		self.setWindowFlags(Qt.WindowStaysOnTopHint)
		self.updateTable()
		
	def cbUpdate(self):
		self.cbPick.clear()
		lx.eval('query layerservice layer.index ? main')
		vn = lx.eval('query layerservice vmap.N ? all')
		for i in range(vn):
			if lx.eval('query layerservice vmap.type ? %d' % i) == 'pick':
				pickName = lx.eval('query layerservice vmap.name ? %d' % i)
				self.cbPick.addItem(pickName)

	def clrSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.tableView.selectionModel().clear()
		lx.command('select.clear',type='vertex')
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def addSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=i)

	def subSelect(self):
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Deselect
		layer_index = lx.eval('query layerservice layers ? main')
		for i in range(self.model.rowCount()):
			if self.model.calc(self.leExpression.text(),i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
				lx.command('select.element',layer=layer_index,type='vertex',mode='remove',index=i)

	def updateTable(self):
		self.updatetable = False
		flag = QItemSelectionModel.Rows|QItemSelectionModel.Select
		self.model.update()
		self.tableView.update()
		layer_index = lx.eval('query layerservice layers ? main')
		self.tableView.selectionModel().clear()
		for i in range(self.model.rowCount()):
			if lx.eval('query layerservice vert.selected ? %s' % i):
				index = self.model.index(i,0)
				self.tableView.selectionModel().select(index,flag)
		self.updatetable = True
				
	def updateSelect(self):
		if self.updatetable :
			lx.command('select.clear',type='vertex')
			layer_index = lx.eval('query layerservice layers ? main')
			for index in self.tableView.selectionModel().selectedRows():
				lx.command('select.element',layer=layer_index,type='vertex',mode='add',index=index.row())

	def newPick(self):
		lx.command('select.editSet')
		self.cbUpdate()
		
	def removePick(self):
		lx.eval('select.deleteSet %s' % self.cbPick.currentText())
		self.cbUpdate()
				
	def selectPick(self):
		lx.eval('select.useSet %s replace' % self.cbPick.currentText())
		self.updateTable()
		
	def addPick(self):
		lx.eval('select.useSet %s select' % self.cbPick.currentText())
		self.updateTable()
		
	def subPick(self):
		lx.eval('select.useSet %s deselect' % self.cbPick.currentText())
		self.updateTable()

	def keyPressEvent(self, event):
		super().keyPressEvent(event)
		if (event.modifiers() & Qt.ControlModifier) and event.key() == Qt.Key_Z:
			if event.modifiers() & Qt.ShiftModifier :
				lx.command('!app.redo')
			else:				
				lx.command('!app.undo')
			self.updateTable()
			
	def paintEvent(self,event):
		if not self.isActiveWindow():
			self.updateTable()
		
w = MyDialog()
w.show()

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG
Archives