import Blender from Blender import * from Blender.Mathutils import * try: import psyco # psyco.log() # psyco.profile() psyco.full() except ImportError: pass # ******************************************************************************** # for convenience: # ---------------- def show_matrix4x4 (pos_x, pos_y, matrix, comment = ""): BGL.glColor3f(0, 0, 0) BGL.glRasterPos2i(pos_x, pos_y) Draw.Text(comment) BGL.glRasterPos2i(pos_x, pos_y - 20) Draw.Text(str(matrix[0][0])+","+str(matrix[0][1])+","+str(matrix[0][2])+","+str(matrix[0][3])) BGL.glRasterPos2i(pos_x, pos_y - 40) Draw.Text(str(matrix[1][0])+","+str(matrix[1][1])+","+str(matrix[1][2])+","+str(matrix[1][3])) BGL.glRasterPos2i(pos_x, pos_y - 60) Draw.Text(str(matrix[2][0])+","+str(matrix[2][1])+","+str(matrix[2][2])+","+str(matrix[2][3])) BGL.glRasterPos2i(pos_x, pos_y - 80) Draw.Text(str(matrix[3][0])+","+str(matrix[3][1])+","+str(matrix[3][2])+","+str(matrix[3][3])) def show_vector (pos_x, pos_y, vector, comment = ""): BGL.glColor3f(0, 0, 0) BGL.glRasterPos2i(pos_x, pos_y) Draw.Text(comment) BGL.glRasterPos2i(pos_x, pos_y - 20) Draw.Text(str(vector[0])+","+str(vector[1])+","+str(vector[2])) # ******************************************************************************** def get_win3d (screen_x, screen_y): # DESCRIPTION: # ------------ # return the 3d-window at given screencoords (or {}) # ---------------------------------------------------------------------------- for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): min_x, min_y, max_x, max_y = win3d.get('vertices') if (max_x >screen_x > min_x) and (max_y > screen_y > min_y): return win3d return {} # ******************************************************************************** def displace_vertices (screen_x, screen_y): # DESCRIPTION: # ------------ # a do-it-all function (just for speed tests...) # needs tweaking: the backface culling is still not working correctly in all situations # ...and is only for convev meshes so far... # ---------------------------------------------------------------------------- global selection global selection_size global selected_object global displacement_direction selection = {} selection_size2 = selection_size * selection_size displacement = 0.1 *displacement_direction # so far i use a constant displacement only # ...no falloff with distance for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): win_min_x, win_min_y, win_max_x, win_max_y = win3d.get('vertices') if (win_max_x > screen_x > win_min_x) and (win_max_y > screen_y > win_min_y): win_mid_x = (win_max_x + win_min_x) * 0.5 win_mid_y = (win_max_y + win_min_y) * 0.5 win_size_x = (win_max_x - win_min_x) * 0.5 win_size_y = (win_max_y - win_min_y) * 0.5 acceptable_min_x = screen_x - selection_size acceptable_min_y = screen_y - selection_size acceptable_max_x = screen_x + selection_size acceptable_max_y = screen_y + selection_size Window.QHandle(win3d.get('id')) # otherwise the perspective matrix might be wrong # for more than one 3dwin matrix = selected_object.getMatrix()*Window.GetPerspMatrix() mesh = selected_object.getData() for face in mesh.faces: gfn = VecMultMat(Vector(list(face.normal[:3])+[1.0]), selected_object.getMatrix()) gfn = Vector(list(gfn[:3])) if DotVecs(gfn, Vector(Window.GetViewVector()) ) > 0: # simple backface-culling for vertex in face.v: if vertex.index not in selection: hvs = VecMultMat(Vector(list(vertex.co[:3])+[1.0]), matrix) if hvs[2] > 1e-2: # scaling for perspective view hvs[0] /= hvs[2] hvs[1] /= hvs[2] vs = [win_mid_x + (hvs[0] * win_size_x), win_mid_y + (hvs[1] * win_size_y)] if (acceptable_max_x >= vs[0] >= acceptable_min_x) and (acceptable_max_y >= vs[1] >= acceptable_min_y): dx = screen_x - vs[0] dy = screen_y - vs[1] size2 = (dx * dx) + (dy * dy) if size2 <= selection_size2: print vertex.co print vertex.no vertex.co[0] += vertex.no[0] * displacement vertex.co[1] += vertex.no[1] * displacement vertex.co[2] += vertex.no[2] * displacement print vertex.co print vertex.no selection[vertex.index]=size2 old_mode = Window.EditMode() Window.EditMode(0) mesh.update() Window.EditMode(old_mode) # ******************************************************************************** def displacement_loop (): while (Window.GetMouseButtons() == 4): # ... and do our own ... displace_vertices(Window.GetMouseCoords()[0], Window.GetMouseCoords()[1]) Blender.Window.Redraw(Window.Types.VIEW3D) #Blender.Draw.Register(draw, event, button_event) # ... only until we're done ... #Switched over to using Window, for two reasons #Draw.Register segfaults, which isn't very nice #Draw.Register only catches key events when in the text window area # ******************************************************************************** global selection global selection_size global mouse_x # global mouse_x_old global mouse_y # global mouse_y_old global displacement_direction mouse_buttons = Window.GetMouseButtons() # ******************************************************************************** # ******************************************************************************** # globals: # -------- mouse_buttons = 0 mouse_x = 0 #mouse_x_old = 0 # not used mouse_y = 0 #mouse_y_old = 0 # not used selection = {} selection_size = 50 displacement_direction = +1 # +1 = out # -1 = in radiusIncremet = 5 max_selection_size = 50 min_selection_size = 5 selected_object = Blender.Object.GetSelected()[0] done = False # main: # ----- while not done: win3d = get_win3d (Window.GetMouseCoords()[0], Window.GetMouseCoords()[1]) mouse_buttons = Window.GetMouseButtons() if (win3d != {}) and (mouse_buttons == 4): if Window.GetKeyQualifiers() == 0: displacement_loop() elif Window.GetKeyQualifiers() != 0: if displacement_direction == +1: displacement_string = "out" if displacement_direction == -1: displacement_string = "in" menu_result = Draw.PupMenu("Interactive Paint%t|%l|Selection Size: "+str(selection_size)+"%x1|Displacement: "+displacement_string+"%x2|%l|Quit%x3") if (menu_result == 1): selection_size = Draw.PupIntInput("Selection Size:", selection_size, 1, 100) if (menu_result == 2): displacement_direction *= -1 if (menu_result == 3): done = True Draw.Redraw (Window.QTest()) else: evt, val = Window.QRead() if evt in [Draw.ESCKEY, Draw.QKEY]: done = True elif evt in [Draw.LEFTARROWKEY] and val: #shrink radius selection_size -= radiusIncrement if selection_size < min_selection_size: selection_size = min_selection_size elif evt in [Draw.RIGHTARROWKEY] and val: #grow radius selection_size += radiusIncrement if selection_size > max_selection_size: selection_size = max_selection_size elif evt in [Draw.UPARROWKEY] and val: #grow displacementHeight displacement += .01 elif evt in [Draw.DOWNARROWKEY] and val: #shrink displacementHeight displacement -= .01 else: #otherwise pass the event back and let Blender handle it #id = Window.GetAreaID() there appears to be a bug in this, it always gets the textwindow id? #so we'll assume the 3d window for simplicity right now... id = Window.GetScreenInfo(Window.Types.VIEW3D)[0].get('id') Window.QAdd(id, evt, val) #Window.QHandle(id) # ******************************************************************************** # ********************************************************************************