Hi all,

The visualization part of pythonOCC was all contained in a Display3d class defined in the Display3d.cpp C++ class. The new GetHandle()/GetObject() pythonOCC feature for smart pointers handle allowed to port this C++ file to a pure Python script. The Display3d.cpp file is still necessary for the creation of GraphicDevice, Window, Context and Viewer, but everything else was ported to an OCCViewer.py script. It means that you can now customize this class to fit your needs, without waiting for a new pythonOCC build including your requests.

Best regards,

Thomas Paviot
#!/usr/bin/env python

##Copyright 2008 Thomas Paviot
##
[EMAIL PROTECTED]
##
##pythonOCC is a computer program whose purpose is to provide a complete set
##of python bindings for OpenCasacde library.
##
##This software is governed by the CeCILL license under French law and
##abiding by the rules of distribution of free software.  You can  use, 
##modify and/ or redistribute the software under the terms of the CeCILL
##license as circulated by CEA, CNRS and INRIA at the following URL
##"http://www.cecill.info";. 
##
##As a counterpart to the access to the source code and  rights to copy,
##modify and redistribute granted by the license, users are provided only
##with a limited warranty  and the software's author,  the holder of the
##economic rights,  and the successive licensors  have only  limited
##liability. 
##
##In this respect, the user's attention is drawn to the risks associated
##with loading,  using,  modifying and/or developing or reproducing the
##software by the user in light of its specific status of free software,
##that may mean  that it is complicated to manipulate,  and  that  also
##therefore means  that it is reserved for developers  and  experienced
##professionals having in-depth computer knowledge. Users are therefore
##encouraged to load and test the software's suitability as regards their
##requirements in conditions enabling the security of their systems and/or 
##data to be ensured and,  more generally, to use and operate it in the 
##same conditions as regards security. 
##
##The fact that you are presently reading this means that you have had
##knowledge of the CeCILL license and that you accept its terms.

import os, os.path
import OCC
import sys

class Texture(object):
    """
    This class encapsulates the necessary texture properties:
    Filename, toScaleU, etc.
    """
    def __init__(self, filename):
        if not os.path.isfile(filename):
            raise "File doesn't exist"
        self._filename = os.path._getfullpathname(filename) #required for OCC
        self._toScaleU = 1.0
        self._toScaleV = 1.0
        self._toRepeatU = 1.0
        self._toRepeatV = 1.0
        self._originU = 0.0
        self._originV = 0.0
        
    def TextureScale(self,toScaleU, toScaleV):
        self._toScaleU = toScaleU
        self._toScaleV = toScaleV
        
    def TextureRepeat(self,toRepeatU, toRepeatV):
        self._toRepeatU = toRepeatU
        self._toRepeatV = toRepeatV
        
    def TextureOrigin(self, originU, originV):
        self._originU = originU
        self._originV = originV
    
    def GetProperties(self):
        return (self._filename,\
                self._toScaleU,self._toScaleV,\
                self._toRepeatU, self._toRepeatV,\
                self._originU, self._originV)
        
class Viewer3d(OCC.Display3d):
    def __init__(self, window_handle = 0):
        OCC.Display3d.__init__(self)
        self._window_handle = window_handle
        self._inited = False
        self.AISContext_handle = None
        self.V3dViewer_handle = None
        self.V3dView_handle = None
        self.AISContext = None
        self.V3dViewer = None
        self.V3dView = None
        
    def Create(self):
        try:
            os.environ["CSF_GraphicShr"]
        except KeyError:
            raise "Please set the CSF_GraphicShr environment variable."
        self.Init(self._window_handle)
        self.AISContext_handle = self.GetContext()
        self.V3dViewer_handle = self.GetV3dViewer()
        self.V3dView_handle = self.GetV3dView()
        self.AISContext = self.AISContext_handle.GetObject()
        self.V3dViewer = self.V3dViewer_handle.GetObject()
        self.V3dView = self.V3dView_handle.GetObject()
        self._inited = True
    
    def MoveTo(self,X,Y):
        self.AISContext.MoveTo(X,Y,self.V3dView_handle)
        
    def OnResize(self):
        print "Resize!!"
        self.V3dView.MustBeResized()

    def ResetView(self):
        self.V3dView.Reset()
        
    def FitAll(self):
        self.V3dView.ZFitAll()
        self.V3dView.FitAll()
    
    def Repaint(self):
        self.V3dViewer.Redraw()
        
    def SetModeWireFrame(self):
        self.V3dView.SetComputedMode(False)
        self.AISContext.SetDisplayMode(OCC.AIS_WireFrame)

    def SetModeShaded(self):
        self.V3dView.SetComputedMode(False)
        self.V3dView.SetAntialiasingOff()
        self.AISContext.SetDisplayMode(OCC.AIS_Shaded)
     
    def SetModeQuickHLR(self):
        self.V3dView.SetComputedMode(True)
        self.AISContext.SetDisplayMode(OCC.AIS_QuickHLR)
    
    def SetModeExactHLR(self):
        self.V3dView.SetComputedMode(True)
        self.AISContext.SetDisplayMode(OCC.AIS_ExactHLR)
    
    def DisplayShape(self,shape,material=None,texture=None):
        if material:#careful: != operator segfaults
            self.V3dView.SetSurfaceDetail(OCC.V3d_TEX_ALL)
            shape_to_display = OCC.AIS_TexturedShape(shape)
            shape_to_display.SetMaterial(material)
            if texture:
                filename, toScaleU, toScaleV, toRepeatU, toRepeatV, originU, 
originV = texture.GetProperties()
                
shape_to_display.SetTextureFileName(OCC.TCollection_AsciiString(filename))
                shape_to_display.SetTextureMapOn()
                shape_to_display.SetTextureScale(True, toScaleU, toScaleV)
                shape_to_display.SetTextureRepeat(True, toRepeatU, toRepeatV)
                shape_to_display.SetTextureOrigin(True, originU, originV)
                shape_to_display.SetDisplayMode(3);
        else:
            shape_to_display = OCC.AIS_Shape(shape)
        self.AISContext.Display(shape_to_display.GetHandle())
        self.FitAll()
    
    def DisplayTriedron(self):
        self.V3dView.TriedronDisplay(OCC.Aspect_TOTP_RIGHT_LOWER, 
OCC.Quantity_NOC_WHITE, 0.08,  OCC.V3d_WIREFRAME)
        self.Repaint()
    
    def EnableAntiAliasing(self):
        self.V3dView.SetAntialiasingOn()
        self.Repaint()

    def EnableAntiAliasing(self):
        self.V3dView.SetAntialiasingOff()
        self.Repaint()
        
    def Tumble(self,NumImages,Animation = True):
        self.V3dView.Tumble(NumImages, Animation)
        
    def Pan(self,Dx,Dy):
        self.V3dView.Pan(Dx,Dy)
    
    def SetSelectionMode(self,mode = OCC.TopAbs_FACE):
        self.AISContext.CloseAllContexts()
        self.AISContext.OpenLocalContext()
        self.AISContext.ActivateStandardMode(mode)
        
    def Select(self,X,Y):
        self.AISContext.Select()
        self.AISContext.InitSelected()
        print self.AISContext.MoreSelected()
        if self.AISContext.MoreSelected():
            if self.AISContext.HasSelectedShape():
                print "Something selected"
                selected_shape = self.AISContext.SelectedShape()
                print selected_shape
        else:
            print "Nothing selected"
            selected_shape = None
        
    def Rotation(self,X,Y):
        self.V3dView.Rotation(X,Y)
    
    def DynamicZoom(self,X1,Y1,X2,Y2):
        self.V3dView.Zoom(X1,Y1,X2,Y2)
    
    def ZoomArea(self,X1,Y1,X2,Y2):
        self.V3dView.WindowFit(X1,Y1,X2,Y2)
    
    def Zoom(self,X,Y):
        self.V3dView.Zoom(X,Y)
    
    def StartRotation(self,X,Y):
        self.V3dView.StartRotation(X,Y)

if __name__=="__main__":
    import wx
    class AppFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, -1, "wxDisplay3d sample", 
style=wx.DEFAULT_FRAME_STYLE,size = (640,480))
            self.viewer3d = Viewer3d(self.GetHandle())
            menuBar = wx.MenuBar()
            menu = wx.Menu()
            menu.Append(101,"Test 1")
            self.Bind(wx.EVT_MENU,self.RunTest1,id = 101)
            menu.Append(102,"Test 2")
            self.Bind(wx.EVT_MENU,self.RunTest2,id = 102)
            menu.Append(103,"Test 3")
            self.Bind(wx.EVT_MENU,self.RunTest3,id = 103)
            menu.Append(104,"Test 4")
            self.Bind(wx.EVT_MENU,self.RunTest4,id = 104)
            menuBar.Append(menu, "&Tests")
            self.SetMenuBar(menuBar)
            
        def RunTest1(self, event):
            box = OCC.BRepPrimAPI_MakeBox(10,20,30)
            box_shape = box.Shape()
            self.viewer3d.DisplayShape(box_shape)
            
        def RunTest2(self, event):
            c = self.viewer3d.AISContext.NbCurrents()        
            print "NbCurrents:%i"%c
            
        def RunTest3(self, event):
            pass
        
        def RunTest4(self, event):
            pass
        
        def testTexure(self):
            material = OCC.Graphic3d_MaterialAspect(OCC.Graphic3d_NOM_GOLD)
            #
            # Creating Texture
            #
            texture = Texture("carrelage1.gif")
            box = OCC.BRepPrimAPI_MakeBox(10,20,30).Shape()
            self.viewer3d.DisplayShape(box_shape,material,texture)
    
    app = wx.PySimpleApp()
    wx.InitAllImageHandlers()
    frame = AppFrame(None)
    frame.Show(True)
    wx.SafeYield()
    frame.viewer3d.Create()
    frame.viewer3d.SetSelectionMode()
    app.SetTopWindow(frame)
    app.MainLoop()          
    
#!/usr/bin/env python

##Copyright 2008 Thomas Paviot
##
[EMAIL PROTECTED]
##
##pythonOCC is a computer program whose purpose is to provide a complete set
##of python bindings for OpenCasacde library.
##
##This software is governed by the CeCILL license under French law and
##abiding by the rules of distribution of free software.  You can  use, 
##modify and/ or redistribute the software under the terms of the CeCILL
##license as circulated by CEA, CNRS and INRIA at the following URL
##"http://www.cecill.info";. 
##
##As a counterpart to the access to the source code and  rights to copy,
##modify and redistribute granted by the license, users are provided only
##with a limited warranty  and the software's author,  the holder of the
##economic rights,  and the successive licensors  have only  limited
##liability. 
##
##In this respect, the user's attention is drawn to the risks associated
##with loading,  using,  modifying and/or developing or reproducing the
##software by the user in light of its specific status of free software,
##that may mean  that it is complicated to manipulate,  and  that  also
##therefore means  that it is reserved for developers  and  experienced
##professionals having in-depth computer knowledge. Users are therefore
##encouraged to load and test the software's suitability as regards their
##requirements in conditions enabling the security of their systems and/or 
##data to be ensured and,  more generally, to use and operate it in the 
##same conditions as regards security. 
##
##The fact that you are presently reading this means that you have had
##knowledge of the CeCILL license and that you accept its terms.

# Then loads OCC and wx
import os
from OCC import *
import sys
import wx
import OCCViewer

class wxViewer3d(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
 
        self.Bind( wx.EVT_SIZE , self.OnSize)
        self.Bind( wx.EVT_IDLE , self.OnIdle)
        self.Bind( wx.EVT_MOVE , self.OnMove)
        self.Bind( wx.EVT_SET_FOCUS , self.OnFocus)
        self.Bind( wx.EVT_KILL_FOCUS , self.OnLostFocus)
        self.Bind( wx.EVT_MAXIMIZE , self.OnMaximize)

        self.Bind( wx.EVT_LEFT_DOWN , self.OnLeftDown)
        self.Bind( wx.EVT_RIGHT_DOWN , self.OnRightDown)
        self.Bind( wx.EVT_MIDDLE_DOWN , self.OnMiddleDown)
        self.Bind( wx.EVT_LEFT_UP , self.OnLeftUp)
        self.Bind( wx.EVT_RIGHT_UP , self.OnRightUp)
        self.Bind( wx.EVT_MIDDLE_UP , self.OnMiddleUp)
        self.Bind( wx.EVT_MOTION , self.OnMotion)
        self.Bind( wx.EVT_KEY_DOWN ,self.OnKeyDown)

        self._drawbox = False
        self._zoom_area = False
        self._select_area = False
        
        self._3dDisplay = None
        self._inited = False
        self._leftisdown = False
        self._middleisdown = False
        self._rightisdown = False
        self._selection = None
        if sys.platform=='win32':
            self.InitViewer3d()

    def InitViewer3d(self):
        try:
            os.environ["CSF_GraphicShr"]
        except KeyError:
            raise "Please set the CSF_GraphicShr environment variable."
        #self._3dDisplay = Display3d()
        print "Nouveau!!!"
        self._3dDisplay = OCCViewer.Viewer3d(self.GetHandle())
        self._3dDisplay.Create()
        #self._3dDisplay.Init(self.GetHandle())
        self._3dDisplay.DisplayTriedron()
        self._3dDisplay.SetModeShaded()
        #self._3dDisplay.SetDefaultLights(True)
        self._inited = True
       
    def OnKeyDown(self,evt):
        key_code = evt.GetKeyCode()
        print key_code
        if key_code==87:#"W"
            self._3dDisplay.SetModeWireFrame()
        elif key_code==83:#"S"
            self._3dDisplay.DisableAntiAliasing()
            self._3dDisplay.SetModeShaded()
        elif key_code==65:#"A"
            self._3dDisplay.EnableAntiAliasing()
        elif key_code==66:#"B"
            self._3dDisplay.DisableAntiAliasing()
        elif key_code==81:#"Q"
            self._3dDisplay.SetModeQuickHLR()
        elif key_code==69:#"E"
            self._3dDisplay.SetModeExactHLR()
        elif key_code == 70:#"F"
            self._3dDisplay.ExportToImage("essai.BMP")
        elif key_code == 71:#"G"
            self._3dDisplay.SetBackgroundImage("carrelage1.gif")
        elif key_code == 72:#"G"
            self._3dDisplay.SetSelectionModeVertex()
            
              
    def OnSize(self, event):
        if self._inited:
            self._3dDisplay.OnResize()

    def OnMaximize(self, event):
        if self._inited:
            self._3dDisplay.Repaint()
        
    def OnMove(self, event):
        if self._inited:
            self._3dDisplay.Repaint()
            
    def OnIdle(self, event):
        if self._drawbox:
            pass
        elif self._inited:
            self._3dDisplay.Repaint()

    def Test(self):
        if self._inited:
            self._3dDisplay.Test()
        
    def OnFocus(self, event):
        if self._inited:
            self._3dDisplay.Repaint()
        
    def OnLostFocus(self, event):
        if self._inited:
            self._3dDisplay.Repaint()

    def OnPaint(self, event):
        if self._inited:
            self._3dDisplay.Repaint()
            
    def ZoomAll(self, evt):
        self._3dDisplay.Zoom_FitAll()

    def Repaint(self, evt):
       if self._inited:
            self._3dDisplay.Repaint()
            
    def OnLeftDown(self, evt):
        self.SetFocus()
        self.dragStartPos = evt.GetPosition()
        self._3dDisplay.StartRotation(self.dragStartPos.x,self.dragStartPos.y) 

    def OnLeftUp(self,evt):
        pt = evt.GetPosition()
        if self._select_area:
            [Xmin, Ymin, dx, dy] = self._drawbox
            selected_shapes = self._3dDisplay.Select(Xmin,Ymin,Xmin+dx,Ymin+dy)
            self._select_area = False 
        else:
            if self._3dDisplay.Select(pt.x,pt.y):
                selected_shape = self._3dDisplay.GetSelectedShape()
                print selected_shape,selected_shape.ShapeType()
        
    def OnRightUp(self,evt):
        if self._zoom_area:
            [Xmin, Ymin, dx, dy] = self._drawbox
            self._3dDisplay.ZoomArea(Xmin, Ymin, Xmin+dx, Ymin+dy)
            self._zoom_area = False
           
    def OnMiddleUp(self,evt):
        pass
        
    def OnRightDown(self, evt):
        self.dragStartPos = evt.GetPosition()
        self._3dDisplay.StartRotation(self.dragStartPos.x,self.dragStartPos.y)
              
    def OnMiddleDown(self, evt):
        self.dragStartPos = evt.GetPosition()
        self._3dDisplay.StartRotation(self.dragStartPos.x,self.dragStartPos.y) 
        
    def DrawBox(self, event):
        tolerance = 2
        pt = event.GetPosition()
        dx = pt.x - self.dragStartPos.x
        dy = pt.y - self.dragStartPos.y
        if abs(dx) <= tolerance and abs(dy) <= tolerance:
            return
        dc = wx.ClientDC(self)
        dc.BeginDrawing()
        dc.SetPen(wx.Pen(wx.WHITE, 1, wx.DOT))
        dc.SetBrush(wx.TRANSPARENT_BRUSH)
        dc.SetLogicalFunction(wx.XOR)
        if self._drawbox:
            r = wx.Rect(*self._drawbox)
            dc.DrawRectangleRect(r)

        r = wx.Rect(self.dragStartPos.x, self.dragStartPos.y , dx, dy)
        dc.DrawRectangleRect(r)
        dc.EndDrawing()
        self._drawbox = [self.dragStartPos.x, self.dragStartPos.y , dx, dy]
        
    def OnMotion(self, evt):
        pt = evt.GetPosition()
        # ROTATE
        if (evt.LeftIsDown() and not evt.ShiftDown()):
            dx = pt.x - self.dragStartPos.x
            dy = pt.y - self.dragStartPos.y
            self._3dDisplay.Rotation(pt.x,pt.y)
            self._drawbox = False
        # DYNAMIC ZOOM
        elif (evt.RightIsDown() and not evt.ShiftDown()):
            self._3dDisplay.Repaint()
            self._3dDisplay.DynamicZoom(abs(self.dragStartPos.x), 
abs(self.dragStartPos.y), abs(pt.x), abs(pt.y))
            self.dragStartPos.x = pt.x 
            self.dragStartPos.y = pt.y
            self._drawbox = False
        # PAN
        elif evt.MiddleIsDown():
            dx = pt.x - self.dragStartPos.x
            dy = pt.y - self.dragStartPos.y
            self.dragStartPos.x = pt.x 
            self.dragStartPos.y = pt.y
            self._3dDisplay.Pan(dx,-dy)
            self._drawbox = False
        # DRAW BOX
        elif (evt.RightIsDown() and evt.ShiftDown()): # ZOOM WINDOW
            self._zoom_area = True
            self.DrawBox(evt)
        elif (evt.LeftIsDown() and evt.ShiftDown()): # SELECT AREA
            self._select_area = True
            self.DrawBox(evt) 
        else:
            self._drawbox = False
            self._3dDisplay.MoveTo(pt.x,pt.y)

if __name__=="__main__":
    class AppFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, -1, "wxDisplay3d sample", 
style=wx.DEFAULT_FRAME_STYLE,size = (640,480))
            self.canva = wxViewer3d(self)
            self.runTests()
        def runTests(self):
            self.canva._3dDisplay.Test()
    app = wx.PySimpleApp()
    wx.InitAllImageHandlers()
    frame = AppFrame(None)
    frame.Show(True)
    if sys.platform!='win32':
        wx.SafeYield() #under Linux, frame must be shown before Display3D is 
initialized
        self.canva.Init3dViewer()
    app.SetTopWindow(frame)
    app.MainLoop()            
_______________________________________________
Minerva-pythonocc mailing list
Minerva-pythonocc@gna.org
https://mail.gna.org/listinfo/minerva-pythonocc

Reply via email to