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