tpaviot / pythonocc-demos

Examples and demos for the pythonocc CAD package
216 stars 115 forks source link

core_visualization_overpaint_viewer example crash #31

Open cylopa opened 3 years ago

cylopa commented 3 years ago

core_visualization_overpaint_viewer.py crashes at QtGui.QPainter(self)

Same for both Pyside2 5.15.1 and PyQt5 5.12.3.

tpaviot commented 3 years ago

Can you please elaborate (trace/os/pyocc version)

cylopa commented 3 years ago

Windows 10, pyocc 7.4.0

It prints this:

INFO:OCC.Display.backend:backend loaded: qt-pyqt5
 ###### 3D rendering pipe initialisation #####
Display3d class initialization starting ...
Aspect_DisplayConnection created.
Graphic_Driver created.
V3d_Viewer created.
AIS_InteractiveContext created.
V3d_View created
WNT window created.
Display3d class successfully initialized.
 ########################################

Process finished with exit code -1073740771 (0xC000041D)

It shows only the box, stays a couple seconds frozen then closes.

cylopa commented 3 years ago

I see the paintEngine solves the crash. But it still does not show any bubbles ?

Area zoom doesn't draw the selection box on top of the view.

cylopa commented 3 years ago

QRubberBand seems to be able to draw selection rectangle on top of the view. But any other shape we draw with QPainter in paintEvent does not shown.

Here the examples:

Current behaviour example

```python import sys from PySide2.QtWidgets import QApplication, QMainWindow, QRubberBand, QStyleFactory from PySide2.QtGui import QColor, QPainter, QBrush, QPaintEvent, QResizeEvent, QMouseEvent from PySide2.QtCore import Qt, QPoint, QRect, QSize from PySide2.QtOpenGL import QGLWidget from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB, Quantity_NOC_BLACK from OCC.Core.V3d import V3d_ZBUFFER, V3d_XposYnegZpos from OCC.Core.Aspect import Aspect_TOTP_RIGHT_LOWER from OCC.Core.AIS import AIS_Shaded from OCC.Core.Visualization import Display3d class OCCRubberBand(QRubberBand): def __init__(self, rubber_band_shape, parent=None): super().__init__(rubber_band_shape, parent) self.setStyle(QStyleFactory.create("windows")) def paintEvent(self, event: QPaintEvent): painter = QPainter(self) painter.drawRect(event.rect()) painter.end() class OCCWidget(QGLWidget): def __init__(self, parent=None): super().__init__(parent) self.origin = QPoint() self.rubber_band = OCCRubberBand(QRubberBand.Rectangle, self) self.setMouseTracking(True) self.setAutoFillBackground(False) self.setFocusPolicy(Qt.StrongFocus) self.setAttribute(Qt.WA_NativeWindow, True) self.setAttribute(Qt.WA_PaintOnScreen, True) self.setAttribute(Qt.WA_NoSystemBackground, True) display3d = Display3d() display3d.Init(self.winId()) self.display3d = display3d self.v3d_viewer = display3d.GetViewer() self.v3d_viewer.SetDefaultLights() self.v3d_viewer.SetLightOn() self.v3d_view = display3d.GetView() self.v3d_view.SetBackgroundColor(Quantity_TOC_RGB, 0.34, 0.34, 0.34) self.v3d_view.TriedronDisplay(Aspect_TOTP_RIGHT_LOWER, Quantity_Color(Quantity_NOC_BLACK), 0.1, V3d_ZBUFFER) self.v3d_view.SetProj(V3d_XposYnegZpos) self.ais_context = display3d.GetContext() self.ais_context.SetAutomaticHilight(True) self.ais_context.SetDisplayMode(AIS_Shaded, False) self.prs3d_drawer = self.ais_context.DefaultDrawer() self.prs3d_drawer.SetFaceBoundaryDraw(True) self.is_resized = False def paintEngine(self): return None def resizeEvent(self, event: QResizeEvent): self.is_resized = True def paintEvent(self, event: QPaintEvent): if self.is_resized: self.is_resized = False self.v3d_view.MustBeResized() else: self.v3d_view.Redraw() # Does not draw ! self.makeCurrent() painter = QPainter(self) self.swapBuffers() # This should draw a white filled rectangle. rect = QRect(QPoint(100, 100), QPoint(painter.device().width()-100, painter.device().height()-100)) brush = QBrush() brush.setColor(QColor(255, 255, 255)) brush.setStyle(Qt.SolidPattern) painter.fillRect(rect, brush) painter.end() self.doneCurrent() # Does not draw ! def mousePressEvent(self, event: QMouseEvent): self.origin = event.pos() self.rubber_band.setGeometry(QRect(self.origin, QSize())) self.rubber_band.show() def mouseMoveEvent(self, event: QMouseEvent): if self.rubber_band.isVisible(): self.rubber_band.setGeometry(QRect(self.origin, event.pos()).normalized()) self.update() def mouseReleaseEvent(self, event: QMouseEvent): if self.rubber_band.isVisible(): self.rubber_band.hide() class MainWindow(QMainWindow): def __init__(self, parent=None): self.q_app = QApplication.instance() if self.q_app is None: self.q_app = QApplication(sys.argv) super().__init__(parent=parent) self.setWindowTitle("PyOCC - Overprint example") self.resize(1024, 768) self.occ_widget = OCCWidget() self.setCentralWidget(self.occ_widget) def event_loop(self): self.show() return self.q_app.exec_() if __name__ == "__main__": window = MainWindow() sys.exit(window.event_loop()) ```

Desired behaviour example

```python import sys from PySide2.QtWidgets import QApplication, QMainWindow, QRubberBand, QStyleFactory from PySide2.QtGui import QColor, QPainter, QBrush, QPaintEvent, QResizeEvent, QMouseEvent from PySide2.QtCore import Qt, QPoint, QRect, QSize from PySide2.QtOpenGL import QGLWidget class OCCRubberBand(QRubberBand): def __init__(self, rubber_band_shape, parent=None): super().__init__(rubber_band_shape, parent) self.setStyle(QStyleFactory.create("windows")) def paintEvent(self, event: QPaintEvent): painter = QPainter(self) painter.drawRect(event.rect()) painter.end() class OCCWidget(QGLWidget): def __init__(self, parent=None): super().__init__(parent=parent) self.origin = QPoint() self.rubber_band = OCCRubberBand(QRubberBand.Rectangle, self) self.setMouseTracking(True) self.setAutoFillBackground(False) self.setFocusPolicy(Qt.StrongFocus) self.setAttribute(Qt.WA_NativeWindow, True) self.setAttribute(Qt.WA_PaintOnScreen, True) self.setAttribute(Qt.WA_NoSystemBackground, True) # # If we override this method it will not draw the filled rectangles in paintEvent. # # But if we do not override while using Display3d then at "painter = QPainter(self)" it crashes. # def paintEngine(self): # return None def paintEvent(self, event): painter = QPainter(self) device = painter.device() w = device.width() h = device.height() brush = QBrush() brush.setColor(QColor(0, 0, 200)) brush.setStyle(Qt.SolidPattern) painter.fillRect(QRect(QPoint(), QPoint(w, h)), brush) rect = QRect(QPoint(100, 100), QPoint(painter.device().width()-100, painter.device().height()-100)) brush = QBrush() brush.setColor(QColor(255, 255, 255)) brush.setStyle(Qt.SolidPattern) painter.fillRect(rect, brush) painter.end() def mousePressEvent(self, event): self.origin = event.pos() self.rubber_band.setGeometry(QRect(self.origin, QSize())) self.rubber_band.show() def mouseMoveEvent(self, event): if self.rubber_band.isVisible(): self.rubber_band.setGeometry(QRect(self.origin, event.pos()).normalized()) self.update() def mouseReleaseEvent(self, event): if self.rubber_band.isVisible(): self.rubber_band.hide() class MainWindow(QMainWindow): def __init__(self, parent=None): self.q_app = QApplication.instance() if self.q_app is None: self.q_app = QApplication(sys.argv) super().__init__(parent=parent) self.setWindowTitle("PyOCC - Overprint example") self.resize(1024, 768) self.occ_widget = OCCWidget() self.setCentralWidget(self.occ_widget) def event_loop(self): self.show() return self.q_app.exec_() if __name__ == "__main__": window = MainWindow() sys.exit(window.event_loop()) ```