3d Vpython Application
3d Vpython Application
9 VPython
# Basic 3D Editor Tool
# A POC that vpython resources could be explored further and used to create a 3D
editor tool
# Development inprogress
#############################################Program
Classes#########################################################
# Editor class
class editor:
def __init__(self,objInstance):
self.GRID_TOTAL_LENGTH = 10
self.GRID_STEP_SIZE = 0.5
self.GRID_HALF_LENGTH = self.GRID_TOTAL_LENGTH/2
self.gridLimit = self.GRID_HALF_LENGTH+self.GRID_STEP_SIZE
self.gridlines = [] # hold objects which makeup the grid
self.gridLineHeight = 0.02*self.GRID_STEP_SIZE; #height
self.gridLineWidth = 0.02*self.GRID_STEP_SIZE; #width
self.scene = canvas(background=color.black) # Setup scene default
background color
self.sceneColorSwitch = True # switch to enable scene background color
toggle
self.snapSwitch = False # snap to grid switch
self.rotateSwitch = False # rotate switch
self.groupSwitch = False # object grouping switch
self.currentMousePosition = None # track current mouse position on the
scene
self.lastMousePosition = None # track last mouse position on the scene
self.objInstance = objInstance # hold an instance of class object3D
self.read = None #Hold content of loaded file
self.objList = [] #Holds list of objects on the scene
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
axis=vector(0,1,0), color =
color.gray(.9),pickable = False)) #draw boxes and add to grindline list
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
axis=vector(1,0,0), color =
color.gray(.9),pickable = False)) #draw boxes and add to grindline list
####################################################show bottom
grid############################################################
for eachStraightLine_Bottom in range(-self.GRID_HALF_LENGTH,
self.gridLimit, self.GRID_STEP_SIZE):
self.gridlines.append(box( pos=vector(eachStraightLine_Bottom,-
self.GRID_HALF_LENGTH,0),
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
axis=vector(0,0,1), color =
color.gray(.9),pickable = False)) #draw boxes and add to grindline list
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
color = color.gray(.9),pickable = False))
#draw boxes and add to grindline list
####################################################show right
grid#############################################################
for eachStraightLine_Right in range(-self.GRID_HALF_LENGTH, self.gridLimit,
self.GRID_STEP_SIZE):
self.gridlines.append(box( pos=vector(self.GRID_HALF_LENGTH,0,eachStraightLine_Righ
t),
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
axis=vector(0,1,0), color =
color.gray(.9),pickable = False)) #draw boxes and add to grindline list
self.gridlines.append(box( pos=vector(self.GRID_HALF_LENGTH,eachCrossedLine_Bottom,
0),
size=vector(self.GRID_TOTAL_LENGTH,self.gridLineHeight,self.gridLineWidth),
axis=vector(0,0,1), color =
color.gray(.9),pickable = False)) #draw boxes and add to grindline list
#editor class method: toggle editor scene color between day & night
def toggleScene(self):
if self.sceneColorSwitch: #check if switch is set to true
self.scene.background= color.white #change editor scene color to white
self.sceneColorSwitch = False #change switch to false
self.sceneColorButton.text ="Night" #change displayed text on widget to
"Night"
else: #otherwise
self.scene.background= color.black #change editor scene color to black
self.sceneColorSwitch = True #change switch to true
self.sceneColorButton.text="Day" #change displayed text on widget to
"Day"
#editor class method: create user selected object from menu widget
def createObj(self):
self.objInstance.create(self.objMenu.index) #call create method of class
object3D to draw object
self.objMenu.index = 0 #reset widget menu
self.objInstance.objColor(self.getCurrentObj(),self.colorMenu.index)#call objColor
method of class object3D to change to selected color
self.colorMenu.index = 0 #reset widget menu
def lengthSlide(self):
self.getCurrentObj().length = self.length_slider.value #set object length
to length_slider value
def heightSlide(self):
self.getCurrentObj().height = self.height_slider.value #set object height
to height_slider value
def widthSlide(self):
self.getCurrentObj().width = self.width_slider.value #set object width to
width_slider value
# if (scene.mouse.pick!= None):
object.rotate(angle=(-self.move.mag)*0.1, axis=self.move.cross(vec(0,0,1)))
#rotate object
self.lastMousePosition = self.currentMousePosition #update last mouse
position
print("-------------------------------------------------------------------")
print("File Name: "+self.read.name) # The file name
print("File Size: "+self.read.size+"kb") # File size in bytes
print("File Type: "+self.read.type) # What kind of file
print("Creation Date: " + self.read.date) # Creation date if
available
print("-------------------------------------------------------------------")
print(self.read.text) # The file contents
print("################ End #################")
if self.fileMenu.index == 2:
self.fileMenu.index = 0 #reset menu
xfile = winput(prompt ="Import JavaScript File",
type = "string", text = "Enter directory") #create
a widget input allowing user to enter file directory
self.get_library(xfile) #import javascript file
#editor class method: resused method, points to actual called method for each
widget
def clickThrough(self, thisWidget):
eval(thisWidget.method)
self.compoundCheckBox = checkbox(bind=editor_object.clickThrough,
text='Group Objects',editor_object=editor_object,
self.rotateCheckBox = checkbox(bind=editor_object.clickThrough,
text='Rotate Object',editor_object=editor_object,
method="thisWidget.editor_object.checkRotate()")#Enable rotation
self.scene.append_to_caption('\n\n')
########################################################class
trackLine##########################################################################
#
class trackLine:
def __init__(self,editorInstance):
self.editorInstance = editorInstance
self.labelObjPosition = label( pos=scene.mouse.pos, text=scene.mouse.pos,
box = False,visible = False, opacity = 0)
############################################################Class
object3D##########################################################
class object3D:
if index==1:
return sphere(pos=vec(0,0,0), radius = self.objRadius, visible = True,
pickable = True)
if index==2:
return box(pos=vec(0,0,0), length=self.objLength,height=self.objHeight,
width=self.objWidth, visible = True, pickable = True) #display sphere on grid
if index==3:
return cylinder(pos=vec(0,0,0), radius = self.objRadius, axis=
vec(self.objLength,self.objHeight,self.objWidth), visible = True, pickable = True)
#display
if index==4:
return cone(pos=vector(0,0,0),radius = self.objRadius, axis=
vec(self.objLength,self.objHeight,self.objWidth), visible = True, pickable = True)
#display sphere on grid
######################################Program
Main########################################################
#Binding functions
thisEditor.scene.bind("mousemove",movemoveActions) # Call function to modify curent
object position using the mouse
thisEditor.scene.bind("mouseup",mouseupActions)
thisEditor.scene.bind("mousedown", mousedownActions)
thisEditor.scene.bind('keydown',keydownActions) # Call function to modify current
object position using the keyboard direction keys
thisEditor.scene.bind('keyup',mouseupActions) #Call dragFalse to disable object
position modification.
def mousedownActions():
global obj #allow modification to be made to object pointer
obj = thisEditor.getCurrentObj() #assign current object to object pointer
thisEditor.resetSliders() #adjust sliders to match current object properties
thisEditor.getObjSliderSet() #Adjust sliders to inhereit current object
dimension values
thisEditor.setLastMousePos() #get and project mouse position to xy plane when
user press right mouse button
def movemoveActions():
global obj #allow modification to be made to object pointer
temp=thisEditor.getMousePosition() #temproary hold mouse position
def mouseupActions():
global obj #allow modification to be made to object pointer
thisTrackLine.removeTrackLine() #remove object track lines
thisTrackLine.removeObjPos(obj) #remove object position label
def keydownActions():
global obj #allow modification to be made to object pointer
if obj != None: #check if object is selected
temp = obj.pos #assign object position to a temproary variable
dv = 0.05 #object move step value using keyboard
theKey = keysdown() #get the pressed key
if 'left' in theKey: #check if left directional key is pressed
temp.x-=dv #move object towards the left on thex-axis at step value of
0.05
if (temp.x < -thisEditor.getGridHalfLength()): #check grid boundaries
temp.x+=dv #if boundary value is surpassed modify to last value
within grid boundary
if 'right' in theKey: #check if right directional key is pressed
temp.x+=dv #move object towards the right on thex-axis at step value of
0.05
if (temp.x > thisEditor.getGridHalfLength()): #check grid boundaries
temp.x-=dv #if boundary value is surpassed modify to last value
within grid boundary
if 'alt' in theKey: #check if 'alt' key is pressed
if 'up' in theKey: #check if up directional key is pressed with the alt
key
temp.z-=dv #move object away from the user along z-axis at step
value of 0.05
if (temp.z < -thisEditor.getGridHalfLength()): #check grid
boundaries
temp.z+=dv #if boundary value is surpassed modify to last value
within grid boundary
if 'down' in theKey: #check if down directional key is pressed with the
alt key
temp.z+=dv #move object towards the user along z-axis at step value
of 0.05
if (temp.z > thisEditor.getGridHalfLength()): #check grid
boundaries
temp.z-=dv #if boundary value is surpassed modify to last value
within grid boundary
elif 'up' in theKey: #check if up directional key is pressed
temp.y+=dv #move object upwards on the y-axis at step value of 0.05
if (temp.y > thisEditor.getGridHalfLength()): #check grid boundaries
temp.y-=dv #if boundary value is surpassed modify to last value
within grid boundary
elif 'down' in theKey: #check if down directional key is pressed
temp.y-=dv #move object downwards on the y-axis at step value of 0.05
if (temp.y < -thisEditor.getGridHalfLength()): #check grid boundaries
temp.y+=dv #if boundary value is surpassed modify to last value
within grid boundary