Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cq_editor/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import signal
import sys
import argparse

Expand All @@ -18,7 +19,10 @@ def main():

args = parser.parse_args(app.arguments()[1:])

signal.signal(signal.SIGINT, signal.SIG_DFL) # handle Ctrl+C

win = MainWindow(filename=args.filename if args.filename else None)

win.show()
sys.exit(app.exec_())

Expand Down
12 changes: 11 additions & 1 deletion cq_editor/main_window.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys

from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtWidgets import (QLabel, QMainWindow, QToolBar, QDockWidget, QAction)
from logbook import Logger
import cadquery as cq
Expand Down Expand Up @@ -30,6 +31,9 @@ def __init__(self,parent=None, filename=None):
super(MainWindow,self).__init__(parent)
MainMixin.__init__(self)

self.toolbar = None
self.status_label = None

self.setWindowIcon(icon('app'))

# Windows workaround - makes the correct task bar icon show up.
Expand Down Expand Up @@ -199,7 +203,13 @@ def prepare_menubar_component(self,menus,comp_menu_dict):

def prepare_toolbar(self):

self.toolbar = QToolBar('Main toolbar',self,objectName='Main toolbar')
self.toolbar = QToolBar('Main toolbar', self, objectName='Main toolbar')

p = self.toolbar.palette()
if p.color(QPalette.Background).lightnessF() < 0.5: # dark theme is active
p.setColor(QPalette.Button, QColor(120, 120, 120))
p.setColor(QPalette.Background, QColor(170, 170, 170))
self.toolbar.setPalette(p)

for c in self.components.values():
add_actions(self.toolbar,c.toolbarActions())
Expand Down
97 changes: 57 additions & 40 deletions cq_editor/widgets/occt_widget.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,55 @@
import math
from sys import platform


from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QEvent

import OCP

from OCP.AIS import AIS_InteractiveContext, AIS_DisplayMode
from OCP.Aspect import Aspect_DisplayConnection, Aspect_TypeOfTriedronPosition
from OCP.OpenGl import OpenGl_GraphicDriver
from OCP.V3d import V3d_Viewer
from OCP.AIS import AIS_InteractiveContext, AIS_DisplayMode
from OCP.Quantity import Quantity_Color
from OCP.V3d import V3d_Viewer
from OCP.gp import gp_Trsf, gp_Ax1, gp_Dir
from PyQt5.QtCore import pyqtSignal, Qt, QPoint
from PyQt5.QtWidgets import QWidget


ZOOM_STEP = 0.9


class OCCTWidget(QWidget):

sigObjectSelected = pyqtSignal(list)

def __init__(self,parent=None):
def __init__(self, parent=None, *,
turntable_rotation: bool = True,
rotate_step: float = 0.008,
zoom_step: float = 0.1):

super(OCCTWidget,self).__init__(parent)
super(OCCTWidget, self).__init__(parent)

self.setAttribute(Qt.WA_NativeWindow)
self.setAttribute(Qt.WA_PaintOnScreen)
self.setAttribute(Qt.WA_NoSystemBackground)

self._initialized = False
self._needs_update = False
self._old_pos = QPoint(0, 0)
self._rotate_step = rotate_step
self._zoom_step = zoom_step
self._turntable_rotation = turntable_rotation

#OCCT secific things
# OCCT secific things
self.display_connection = Aspect_DisplayConnection()
self.graphics_driver = OpenGl_GraphicDriver(self.display_connection)

self.viewer = V3d_Viewer(self.graphics_driver)
self.view = self.viewer.CreateView()
self.context = AIS_InteractiveContext(self.viewer)

#Trihedorn, lights, etc
# Trihedorn, lights, etc
self.prepare_display()


def set_turntable_rotation(self, new_value: bool):
if self._turntable_rotation != new_value:
self._turntable_rotation = new_value
if self._turntable_rotation:
self.view.SetUp(0, 0, 1)

def prepare_display(self):

view = self.view
Expand All @@ -65,49 +73,58 @@ def prepare_display(self):
ctx.DefaultDrawer().SetFaceBoundaryDraw(True)

def wheelEvent(self, event):

delta = event.angleDelta().y()
factor = ZOOM_STEP if delta<0 else 1/ZOOM_STEP


# dividing by 120 gets number of notches on a typical scroll wheel.
# See QWheelEvent documentation
delta_notches = event.angleDelta().y() / 120
direction = math.copysign(1, delta_notches)
factor = (1 + self._zoom_step * direction) ** abs(delta_notches)

self.view.SetZoom(factor)

def mousePressEvent(self,event):
def mousePressEvent(self, event):

pos = event.pos()

if event.button() == Qt.LeftButton:
self.view.StartRotation(pos.x(), pos.y())
if not self._turntable_rotation:
self.view.StartRotation(pos.x(), pos.y())
elif event.button() == Qt.RightButton:
self.view.StartZoomAtPoint(pos.x(), pos.y())

self.old_pos = pos
def mouseMoveEvent(self,event):
self._old_pos = pos

def mouseMoveEvent(self, event):

pos = event.pos()
x,y = pos.x(),pos.y()
x, y = pos.x(), pos.y()

if event.buttons() == Qt.LeftButton:
self.view.Rotation(x,y)

if self._turntable_rotation:
delta_x, delta_y = x - self._old_pos.x(), y - self._old_pos.y()
cam = self.view.Camera()
z_rotation = gp_Trsf()
z_rotation.SetRotation(gp_Ax1(cam.Center(), gp_Dir(0, 0, 1)), -delta_x * self._rotate_step)
cam.Transform(z_rotation)
self.view.Rotate(0, -delta_y * self._rotate_step, 0)
else:
self.view.Rotation(x, y)

elif event.buttons() == Qt.MiddleButton:
self.view.Pan(x - self.old_pos.x(),
self.old_pos.y() - y, theToStart=True)
delta_x, delta_y = x - self._old_pos.x(), y - self._old_pos.y()
self.view.Pan(delta_x, -delta_y, theToStart=True)

elif event.buttons() == Qt.RightButton:
self.view.ZoomAtPoint(self.old_pos.x(), y,
x, self.old_pos.y())
self.view.ZoomAtPoint(self._old_pos.x(), y,
x, self._old_pos.y())

self.old_pos = pos
self._old_pos = pos

def mouseReleaseEvent(self,event):
def mouseReleaseEvent(self, event):

if event.button() == Qt.LeftButton:
pos = event.pos()
x,y = pos.x(),pos.y()

self.context.MoveTo(x,y,self.view,True)

self.context.MoveTo(pos.x(), pos.y(), self.view, True)
self._handle_selection()

def _handle_selection(self):
Expand Down
12 changes: 11 additions & 1 deletion cq_editor/widgets/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class OCCViewer(QWidget,ComponentMixin):
'values': ['Orthographic', 'Perspective', 'Stereo', 'MonoLeftEye', 'MonoRightEye']},
{'name': 'Stereo Mode', 'type': 'list', 'value': 'QuadBuffer',
'values': ['QuadBuffer', 'Anaglyph', 'RowInterlaced', 'ColumnInterlaced',
'ChessBoard', 'SideBySide', 'OverUnder']}])
'ChessBoard', 'SideBySide', 'OverUnder']},
{'name': 'Orbit Method', 'type': 'list', 'value': 'Turntable', 'values': ['Turntable', 'Trackball']},
])
IMAGE_EXTENSIONS = 'png'

sigObjectSelected = pyqtSignal(list)
Expand Down Expand Up @@ -89,6 +91,14 @@ def updatePreferences(self,*args):
color2 = color1
self.canvas.view.SetBgGradientColors(color1,color2,theToUpdate=True)

orbit_method = self.preferences['Orbit Method']
if orbit_method == 'Turntable':
self.canvas.set_turntable_rotation(True)
elif orbit_method == 'Trackball':
self.canvas.set_turntable_rotation(False)
else:
raise ValueError(orbit_method)

self.canvas.update()

ctx = self.canvas.context
Expand Down