Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View improvements #220

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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 @@

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

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

Check warning on line 22 in cq_editor/__main__.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/__main__.py#L22

Added line #L22 was not covered by tests

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 @@
super(MainWindow,self).__init__(parent)
MainMixin.__init__(self)

self.toolbar = None
self.status_label = None

self.setWindowIcon(icon('app'))

self.viewer = OCCViewer(self)
Expand Down Expand Up @@ -193,7 +197,13 @@

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)

Check warning on line 206 in cq_editor/main_window.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/main_window.py#L204-L206

Added lines #L204 - L206 were not covered by tests

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

Check warning on line 49 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L49

Added line #L49 was not covered by tests
if self._turntable_rotation:
self.view.SetUp(0, 0, 1)

Check warning on line 51 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L51

Added line #L51 was not covered by tests

def prepare_display(self):

view = self.view
Expand All @@ -65,49 +73,58 @@
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)

Check warning on line 81 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L79-L81

Added lines #L79 - L81 were not covered by tests

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())

Check warning on line 91 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L91

Added line #L91 was not covered by tests
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()

Check warning on line 100 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L100

Added line #L100 was not covered by tests

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)

Check warning on line 109 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L104-L109

Added lines #L104 - L109 were not covered by tests
else:
self.view.Rotation(x, y)

Check warning on line 111 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L111

Added line #L111 was not covered by tests

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)

Check warning on line 115 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L114-L115

Added lines #L114 - L115 were not covered by tests

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,

Check warning on line 118 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L118

Added line #L118 was not covered by tests
x, self._old_pos.y())

self.old_pos = pos
self._old_pos = pos

Check warning on line 121 in cq_editor/widgets/occt_widget.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/occt_widget.py#L121

Added line #L121 was not covered by tests

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 @@
'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 @@
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)

Check warning on line 98 in cq_editor/widgets/viewer.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/viewer.py#L98

Added line #L98 was not covered by tests
else:
raise ValueError(orbit_method)

Check warning on line 100 in cq_editor/widgets/viewer.py

View check run for this annotation

Codecov / codecov/patch

cq_editor/widgets/viewer.py#L100

Added line #L100 was not covered by tests

self.canvas.update()

ctx = self.canvas.context
Expand Down