Hi,
Complex and uncapped customization:
Summary
Personally I think that a much easier approach would be to make a custom overlay in d3/OpenGL.
it would allow you to easily and extensively customize your overlay.
An example would be this animated overlay (60fps), in Rhino you would be gutting your performance, by running a separate overlay you do not lose performance, It’s not computationally expensive and It’s not too hard to implement.
Personally I think that by going with the ETO path you will be having a harder time than just going straight for your own overlay in ogl/d3 when you will intend to further customize your UI.
Screen capture - b2830eb2edf9e214309e38e41d03ef14 - Gyazo
Simple and efficient
Summary
You could use otp to use PyQt5 if you’re going to be using Rhino8+
Here’s an example of overlay you can easily pull off inside of rhino and to interact with rhino, with a much better event handling and customization capabilities
There you have a sample script demostrating how to implement it :
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QPainter, QRegion, QCursor
import rhinoscriptsyntax as rs # Import Rhino's Python library
class CircularOverlay(QMainWindow):
def __init__(self):
super().__init__()
# Get mouse position
mouse_pos = QCursor.pos()
# Set window properties
self.setWindowTitle("Circular Overlay")
self.setGeometry(mouse_pos.x(), mouse_pos.y(), 200, 200) # Smaller dimensions and positioned at mouse
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
# Create a QWidget for the central widget
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
# Create buttons and connect them to Rhino commands
self.button1 = self.create_button("SuperMoveEdge", central_widget, 0, 0, 100, 100)
self.button2 = self.create_button("SuperCut", central_widget, 100, 0, 100, 100)
self.button3 = self.create_button("Isolate", central_widget, 0, 100, 100, 100)
self.button4 = self.create_button("View", central_widget, 100, 100, 100, 100)
def create_button(self, command, parent, x, y, w, h):
button = QPushButton(command, parent)
button.setGeometry(x, y, w, h)
button.clicked.connect(lambda: self.run_rhino_command(command))
return button
def run_rhino_command(self, command):
rs.Command(command) # Execute the Rhino command
def paintEvent(self, event):
# Create QPainter object
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# Draw circle
painter.setBrush(Qt.white)
painter.drawEllipse(0, 0, 200, 200) # Smaller circle
# Create a circular region and set it as a mask
region = QRegion(self.rect(), QRegion.Ellipse)
self.setMask(region)
if __name__ == "__main__":
app = QApplication([])
window = CircularOverlay()
window.show()
app.exec_()
Hope this sparks some inspiration,
Farouk