The SimpleGLX control can be used visualize 3D information in a Scorpion system.
SimpleGLX is a control to visualize simple 3D polygons and points, based on the
OpenGL standard. It has a very simple programming interface (accessible
via Python in Scorpion), and a simple but effective GUI mouse interface.
The scene display
The display shows a scene where the camera is pointing towards the
point (CenterX,CenterY,CenterZ).
- The distance to this point -- Radius, and
angles Alpha and Beta define the relative camera position.
- Beta is the
rotation around the Y axis,
- Beta=0 means the camera points along the
Z axis.
- Alpha is the rotation around a line located in the X-Z plane,
- Alpha=0 means the camera points parallel to this plane.
- The Y axis
is "up" when -90<Alpha<90, otherwise "down".
- When Alpha=0, Beta=0 and Center=(0,0,0),
- the camera is located on the Z
axis, pointing towards the origin with Y "up" and X
"right".
- The focal length of the camera can be adjusted.
API (programming interface):
The control is inserted using the Scorpion Central ActiveX container.
In the following, the Scorpion panel PluginPanel1 is assumed.
- To add a 3D polygon, send a string formatted using the StrArr
format:
- PluginPanel1.AddPolygon('Points="((x1;y1;z1)(x2;y2;z2)...)";Closed=0|1')
- Closed=0 to leave polygons open, 1 to connect the last point
back to the first
- Note the use of double quotes to allow semicolons (;) in the
points string
- To add a set of 3D points, send a string formatted using the StrArr
format:
- PluginPanel1.AddPoints('Points="((x1;y1;z1)(x2;y2;z2)...)"')
- Note the use of double quotes to allow semicolons (;) in the
points string
- You can add several 3D polygons (or point sets) simultaneously by concatenating
the strings:
- PluginPanel1.AddPolygon('Points="((x1;y1;z1)(x2;y2;z2)...)((x11;y11;z11)(x12;y12;z12)...)";Closed=0|1')
- To set the line color for subsequent lines:
- PluginPanel1.SetLineColor('Value=<c>')
where c is an integer.
- The color components red, green and
blue each use 8 bits in this number, in that order from
"right" (least significant bit).
- For example, pure red
is 255, pure green is 65280 and pure blue is 16711680.
- To set the color for subsequent points:
- PluginPanel1.SetPointColor('Value=<c>')
where c is an integer.
- To remove all polygons and points:
- To set camera position,
- call PluginPanel1.SetCenterX('Value=<x>');
similar for SetCenterY, SetCenterZ, SetRadius, SetAlpha,
SetBeta, SetFocalLength.
- To query the camera settings, use X=GetSenterX() and
similar.
Note that the background is always black; the polygons are by default rendered in red
and points in cyan (aqua).
See Example 4 : Python Wrapper Class
GUI Mouse Interface:
- Left+move to set view angles (up/down: alpha, left/right: Beta)
- Shift+Left+up/down to set view distance (radius)
- Mouse wheel to set view distance (radius)
- Middle+up/down to adjust perspective (radius+focal length
adjusted simultaneously)
- Ctrl+Leftclick to set new center
- Ctrl+Shift+Leftclick to reset center to (0,0,0)
Example 1: Making a simple box
PluginPanel1.DeleteAll()
PluginPanel1.AddPolygon(
'Points="((-1;-1;-1)(1;-1;-1)(1;1;-1)(-1;1;-1))";Closed=1')
PluginPanel1.AddPolygon(
'Points="((-1;-1;1)(1;-1;1)(1;1;1)(-1;1;1))";Closed=1')
PluginPanel1.AddPolygon(
'Points="((-1;-1;-1)(-1;-1;1))((1;-1;-1)(1;-1;1))";Closed=0')
PluginPanel1.AddPolygon(
'Points="((1;1;-1)(1;1;1))((-1;1;-1)(-1;1;1))";Closed=0')
Note that the point strings must be enclosed in quotes ("")
since they contain semicolons.
Example 2: Moving the camera further away from the scene
R = float(PluginPanel1.GetRadius().replace('PluginPanel1.GetRadiusResponse;Result=',''))
PluginPanel1.SetRadius('Value='+str(R*2))
# Note the string replace operation to convert the response to a number. You are interested in the value returned after "Result=".
Example 3: Set
default Visualization parameters
def OpenGL_ResetParameters():
Visualization.SetCenterX('Value=0')
Visualization.SetCenterY('Value=0')
Visualization.SetCenterZ('Value=80')
Visualization.SetRadius('Value=7500')
Visualization.SetFocalLength('Value=2500')
Visualization.SetAlpha('Value=-70')
Visualization.SetBeta('Value=0')
Example 4:
Python Wrapper Class
def CreateSimpleGLX(name):
class SimpleGLX:
def __init__(self,rows=0,cols=0):
self.object = name
def DrawPolygon(self,pts,closed=1,color=-1):
if color > -1 :
self.object.SetLineColor('Value=%d' % color)
#print pts
s = '('
for p in pts:
s = s+'(%f;%f;%f)'%(p[0],p[1],p[2])
s = s+')'
self.object.AddPolygon('Points="'+s+'";Closed=%d' % closed)
def DrawPoints(self,pts,color=-1):
if color > -1 :
self.object.SetPointColor('Value=%d' % color)
#print pts
s = '('
for p in pts:
s = s+'(%f;%f;%f)'%(p[0],p[1],p[2])
s = s+')'
self.object.AddPoints('Points="'+s+'"')
def DrawAxis(self,lengthX,lengthZ=0,lengthY=0,color=-1):
def DrawArrow(x,y,z,length,color):
if x > 0 :
self.DrawLine(x,y,z,x-length,y,z-length,color)
self.DrawLine(x,y,z,x-length,y,z+length,color)
if y > 0 :
self.DrawLine(x,y,z,x,y-length,z-length,color)
self.DrawLine(x,y,z,x,y-length,z+length,color)
if z > 0 :
self.DrawLine(x,y,z,x-length,y,z-length,color)
self.DrawLine(x,y,z,x+length,y,z-length,color)
if lengthY == 0:
lengthY = lengthX
if lengthZ == 0:
lengthZ = lengthX
arrow = lengthX / 40
self.DrawLine(0,0,0,lengthX,0,0,color)
DrawArrow(lengthX,0,0,arrow,color)
arrow = lengthY / 40
self.DrawLine(0,0,0,0,lengthY,0,color)
DrawArrow(0,lengthY,0,arrow,color)
arrow = lengthZ / 40
self.DrawLine(0,0,0,0,0,lengthZ,color)
DrawArrow(0,0,lengthZ,arrow,color)
def DrawPoint(self,x1,z1,y1,color=-1):
pts = []
pts.append((x1,y1,z1))
self.DrawPoints(pts,color)
def DrawLine(self,x1,z1,y1,x2,z2,y2,color=-1):
pts = []
pts.append((x1,y1,z1))
pts.append((x2,y2,z2))
self.DrawPolygon(pts,0,color)
def DrawSquare(self,x1,z1,y1,x2,z2,y2,x3,z3,y3,x4,z4,y4,color=-1):
import math
def Distance3D(x1,y1,z1,x2,y2,z2):
return math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
def SwapPoint3D(x1,y1,z1,x2,y2,z2):
return x2,y2,z2,x1,y1,z1
# sorts corner points
d12 = Distance3D(x1,y1,z1,x2,y2,z2)
d13 = Distance3D(x1,y1,z1,x3,y3,z3)
d14 = Distance3D(x1,y1,z1,x4,y4,z4)
if d12 > d14:
x2,y2,z2,x4,y4,z4 = SwapPoint3D(x2,y2,z2,x4,y4,z4)
d12 = Distance3D(x1,y1,z1,x2,y2,z2)
d14 = Distance3D(x1,y1,z1,x4,y4,z4)
if d12 > d13:
x2,y2,z2,x3,y3,z3 = SwapPoint3D(x2,y2,z2,x3,y3,z3)
d12 = Distance3D(x1,y1,z1,x2,y2,z2)
d13 = Distance3D(x1,y1,z1,x3,y3,z3)
d23 = Distance3D(x2,y2,z2,x3,y3,z3)
d24 = Distance3D(x2,y2,z2,x4,y4,z4)
if d23 > d24:
x3,y3,z3,x4,y4,z4 = SwapPoint3D(x3,y3,z3,x4,y4,z4)
d23 = Distance3D(x2,y2,z2,x3,y3,z3)
d24 = Distance3D(x2,y2,z2,x4,y4,z4)
pts = []
pts.append((x1,y1,z1))
pts.append((x2,y2,z2))
pts.append((x3,y3,z3))
pts.append((x4,y4,z4))
self.DrawPolygon(pts,1,color)
def Reset(self):
self.object.DeleteAll()
self.SetDefault()
def SetCenter(self,x,y,z):
self.object.SetCenterX('Value=%d' % x)
self.object.SetCenterY('Value=%d' % y)
self.object.SetCenterZ('Value=%d' % z)
def SetRadius(self,radius):
self.object.SetRadius('Value=%d' % radius)
def SetFocalLength(self,fLength):
self.object.SetFocalLength('Value=%d' % fLength)
def SetAlpha(self,alpha):
self.object.SetAlpha('Value=%d' % alpha)
def SetBeta(self,beta):
self.object.SetBeta('Value=%d' % beta)
def SetDefault(self):
self.SetCenter(70,10,40) # order: right,up,towards
self.SetRadius(350)
self.SetFocalLength(100)
self.SetAlpha(10)
self.SetBeta(0)
return SimpleGLX(nam
e)
Example
5: Using Python Wrapper
simpleGLX = CreateSimpleGLX(PluginPanel1)
simpleGLX.Reset()
simpleGLX.DrawAxis(100,65000)
zAv = (z+z2+z3+z4)/4
if zAv < 0 :
zAv = 1
simpleGLX.DrawSquare(x,y,zAv,x2,y2,zAv,x4,y4,zAv,x3,y3,zAv,255)
simpleGLX.DrawSquare(x,y,0,x2,y2,0,x4,y4,0,x3,y3,0)
simpleGLX.DrawLine(x2,y2,0,x2,y2,zAv)
simpleGLX.DrawLine(x3,y3,0,x3,y3,zAv)
simpleGLX.DrawLine(x,y,0,x,y,zAv)
simpleGLX.DrawLine(x4,y4,0,x4,y4,zAv)
|