Hi!

I'm writing a CAD application where I'm using an instance of
TDocStd_Document to manage my document. Now I'd like to add the
functionality of interactively deleting shapes from the document by
selecting them and pressing 'del' on the keyboard.

I have already had some success with that, though my solution is very
inelegant and does not work in all cases. I'm providing a minimal
example of my solution below. The interesting parts are the methods
"DocCtrl.add" and "DocCtrl.remove". What would be the "correct way" to
implement these? I have already tried other variations including using
"RemoveShape" instead of "RemoveComponent" but I couldn't get it to
work. The example needs Qt to be installed, if you want an example
based on wxWidgets, I can post that as well.

Thanks in advance!
Marko

PS: I'm writing an educational CAD program for use in schools as part
of my master thesis. This is one of the last problems I'm trying to
solve, and I will release my program as open source software in 1 or 2
months. Here's a screenshot: http://i.imgur.com/eILSL.png

example code
------------

import sys
from PyQt4 import QtCore, QtGui
from OCC.Display.qtDisplay import qtViewer3d
from OCC import BRepPrimAPI, gp, Quantity, TDocStd, TopAbs, TopLoc
from OCC import TPrsStd, XCAFApp, XCAFDoc, XCAFPrs, TCollection


class MainWindow(QtGui.QMainWindow):

    def __init__(self, *args):
        QtGui.QMainWindow.__init__(self, *args)
        self.resize(900, 640)
        self.viewer = Viewer(self)
        self.setCentralWidget(self.viewer)


class Viewer(qtViewer3d):

    def __init__(self, parent):
        qtViewer3d.__init__(self)

    def init2(self):
        """Perform the second initialization step."""
        self.InitDriver()

        self.doc_ctrl = DocCtrl()

        # switch selection mode to 'solid':
        h = self._display.Context.GetHandle()
        context = TPrsStd.TPrsStd_AISViewer().New(
                     self.doc_ctrl.top_label, h
                     ).GetObject().GetInteractiveContext().GetObject()
        context.OpenLocalContext()
        context.ActivateStandardMode(TopAbs.TopAbs_SOLID)

        self._ais_pres = TPrsStd.TPrsStd_AISPresentation().Set(
             self.doc_ctrl.top_label, XCAFPrs.XCAFPrs_Driver().GetID()
             ).GetObject()

    def repaint(self):
        self._ais_pres.Display(True)
        self._display.Repaint()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Delete:
            shape = self._display.GetSelectedShape()
            if shape:
                self.doc_ctrl.remove(shape)
                self.repaint()


class DocCtrl(object):
    """Controller for a document object.  The document itself
    can be accessed as 'self.document'. """

    def __init__(self):

        # list which associates each shape label with a component
        # label - this list is used for deleting shapes:
        self._label_list = []
        self._doc_handle = TDocStd.Handle_TDocStd_Document()
        self._xcaf_app = XCAFApp.GetApplication().GetObject()
        self._xcaf_app.NewDocument(
            TCollection.TCollection_ExtendedString(b'MDTV-CAF'),
            self._doc_handle)
        # The document itself:
        self.document = self._doc_handle.GetObject()
        self._color_tool = XCAFDoc.XCAFDoc_DocumentTool().ColorTool(
                           self.document.Main()).GetObject()
        self._shape_tool = XCAFDoc.XCAFDoc_DocumentTool().ShapeTool(
                           self.document.Main()).GetObject()
        self.top_label = self._shape_tool.NewShape()
        self._loc = TopLoc.TopLoc_Location(gp.gp_Trsf())

    def add(self, shape):
        """Add a shape to the document"""

        shape_label = self._shape_tool.AddShape(shape, False)
        comp_label = self._shape_tool.AddComponent(
                     self.top_label, shape_label, self._loc)
        self._color_tool.SetColor(shape_label,
                                  Quantity.Quantity_Color(0, 0, 1, 0),
                                  XCAFDoc.XCAFDoc_ColorGen)

        self._label_list.append([shape_label, comp_label])

    def remove(self, shape):
        """Remove a shape from the document"""

        # get the label of the shape which should be removed
        to_remove = self._shape_tool.FindShape(shape)

        # find the shape that corresponds to the label and remove the
        #   associated component
        for shape_label, comp_label in self._label_list:
            if shape_label.IsEqual(to_remove):
                self._shape_tool.RemoveComponent(comp_label)
                break


app = QtGui.QApplication(sys.argv)

win = MainWindow()
win.show()
win.viewer.init2()

# create and add shapes
box = BRepPrimAPI.BRepPrimAPI_MakeBox(60, 30, 10).Shape()
cyl = BRepPrimAPI.BRepPrimAPI_MakeCylinder(25, 40).Shape()

tr = gp.gp_Trsf()
tr.SetTranslation(gp.gp_Vec(0, 50, 0))
loc = TopLoc.TopLoc_Location(tr)
moved_box = box.Moved(loc)

# these shapes can be deleted by selecting them and pressing 'Del':
win.viewer.doc_ctrl.add(box)
win.viewer.doc_ctrl.add(cyl)
# this shape cannot be deleted in this implementation:
win.viewer.doc_ctrl.add(moved_box)
win.viewer.repaint()

app.exec_()

_______________________________________________
Pythonocc-users mailing list
Pythonocc-users@gna.org
https://mail.gna.org/listinfo/pythonocc-users

Reply via email to