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]」と表記する事で参照できる。
下のように式を書けばこの186番目の頂点から0.3未満の距離にある頂点が選択の条件を満たすことになる。

これが式を適用した結果。186の頂点を中心に頂点が選択されているのが確認できる。
続きはまた次回。
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)
これを使って下のように式を書いて球体表面の頂点を選択してみた。
これがその結果。
p0(0.5,0,0)の座標から半径 0.3以内の頂点が選択された。
続きはまた次回。
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()
これが実行結果。
続きはまた次回。
次回は9月4日になります。
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()
これが実行結果。
x座標値が−0.3未満の頂点を選択しておいて、それらのx座標値を−0.3にしてみた。それで気が付いたんだけど−0.3にせっていしたけどリストに表示したらぴったりの数字になっていない。表現できる数値の精度を超えて表示しちゃってるのが原因なのかな。
;
続きはまた次回。
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()
続きはまた次回。