def draw_arrow(point, orientation, length=1.5, branch_length=0.4, angle=30, colour=[1, 0, 0]): left = Vector((sin(radians(angle)), -cos(radians(angle)), 0)) right = Vector((-sin(radians(angle)), -cos(radians(angle)), 0)) left.rotate(orientation) right.rotate(orientation) left.length = branch_length right.length = branch_length direction = Vector((0, 1, 0)) * length direction.rotate(orientation) render.drawLine(point, point + direction, colour) render.drawLine(point + direction, point + direction + right, colour) render.drawLine(point + direction, point + direction + left, colour)
def moveup(self): bfvec = Vector((0, 0, 1)) bfvec.length = self.addonprefs.Speed * self.addonprefs.Scale * self.runmulti / self.divi if self.scn.FPS_Walk: self.addonprefs.Height += bfvec.length * self.addonprefs.Scale else: self.rv3d.view_location += bfvec
def movedown(self): bfvec = Vector((0, 0, 1)) bfvec.length = self.addonprefs.Speed * self.addonprefs.Scale * self.runmulti / self.divi if self.scn.FPS_Walk: self.addonprefs.Height -= bfvec.length * self.addonprefs.Scale if self.addonprefs.Height <= 0: self.addonprefs.Height = 0.0001 else: self.rv3d.view_location -= bfvec
def updateSize(self, context): if not self.updating: if self.size_from_vectors: self.updating = True e1_vec3 = Vector(self.e1_vec3) e2_vec3 = Vector(self.e2_vec3) e3_vec3 = Vector(self.e3_vec3) e1_vec3.length = self.size_vec3[0] e2_vec3.length = self.size_vec3[1] e3_vec3.length = self.size_vec3[2] self.e1_vec3 = Vector(e1_vec3) self.e2_vec3 = Vector(e2_vec3) self.e3_vec3 = Vector(e3_vec3) self.updating = False
def _init_loop(self, region, rv3d, mtx, mtx_sr, backface_culling=False): bpy.ops.mesh.select_all(action='DESELECT') self._snap_edge.select = True bpy.ops.mesh.loop_multi_select() eye = Vector(rv3d.view_matrix[2][:3]) if not rv3d.is_perspective: eye.length = 10000 # change to clip_end else: eye.length = rv3d.view_distance eye_location = rv3d.view_location + eye if backface_culling: self._loop = [ e for e in self._get_bms_selected_edges() if not is_backface(e.verts[0], eye_location, mtx, mtx_sr) ] else: self._loop = [e for e in self._get_bms_selected_edges()] self._loop_2d = points_pairs_3d_to_region_2d( ((mtx @ e.verts[0].co, mtx @ e.verts[1].co) for e in self._loop), region, rv3d)
def onKeyPressed(self, keys): rot = self.obj.worldOrientation.to_euler() pos = Vector([0,0,0]) if key.W in keys: rot.x += 0.01 if key.S in keys: rot.x -= 0.01 if key.A in keys: rot.z += 0.01 if key.D in keys: rot.z -= 0.01 if key.WHEELUPMOUSE in keys: pos.z = -self.obj.worldPosition.z * 0.3 if key.WHEELDOWNMOUSE in keys: pos.z = self.obj.worldPosition.z * 0.3 #Max speed is dependent of the Tile sizes, ex (200m/s = size) / 50fps = 4m/tick #Since we are using an extra radius we can guarante a speed of 8m/tick without glitches: 8*60fps = 480m/s = 1728 km/h #if pos.length > 8: pos.length = 8 #But we don't care for now if pos.length > 50: pos.length = 50 pos.rotate(self.obj.worldOrientation) self.obj.worldPosition += pos self.obj.worldOrientation = rot
def onKeyPressed(self, keys): rot = self.obj.worldOrientation.to_euler() pos = Vector([0, 0, 0]) if key.W in keys: rot.x += 0.01 if key.S in keys: rot.x -= 0.01 if key.A in keys: rot.z += 0.01 if key.D in keys: rot.z -= 0.01 if key.WHEELUPMOUSE in keys: pos.z = -self.obj.worldPosition.z * 0.3 if key.WHEELDOWNMOUSE in keys: pos.z = self.obj.worldPosition.z * 0.3 #Max speed is dependent of the Tile sizes, ex (200m/s = size) / 50fps = 4m/tick #Since we are using an extra radius we can guarante a speed of 8m/tick without glitches: 8*60fps = 480m/s = 1728 km/h #if pos.length > 8: pos.length = 8 #But we don't care for now if pos.length > 50: pos.length = 50 pos.rotate(self.obj.worldOrientation) self.obj.worldPosition += pos self.obj.worldOrientation = rot
def select_front_facing(context): """ from: http://freespace.virgin.net/hugo.elias/routines/r_dot.htm When deciding if a polygon is facing the camera, you need only calculate the dot product of the normal vector of that polygon, with a vector from the camera to one of the polygon's vertices. - If the dot product is less than zero, the polygon is facing the camera. - If the value is greater than zero, it is facing away from the camera. """ region, rv3d, obj, vertlist = get_locals(context) # [ ] be in object mode # neat eye location code with the help of paleajed eye = Vector(rv3d.view_matrix[2][:3]) eye.length = rv3d.view_distance eye_location = rv3d.view_location + eye face_list = [] for idx, polygon in enumerate(obj.data.polygons): vert_index = polygon.vertices[0] pnormal = obj.matrix_world * polygon.normal world_coordinate = obj.matrix_world * vertlist[vert_index].co result_vector = eye_location-world_coordinate dot_value = pnormal.dot(result_vector.normalized()) if dot_value < 0.0: polygon.select = False else: polygon.select = True face_list.append(idx) return face_list
def draw_indices_2D(context, args): context = bpy.context region = context.region region3d = context.space_data.region_3d geom, settings = args vert_idx_color = settings['numid_verts_col'] edge_idx_color = settings['numid_edges_col'] face_idx_color = settings['numid_faces_col'] # vert_bg_color = settings['bg_verts_col'] # edge_bg_color = settings['bg_edges_col'] # face_bg_color = settings['bg_faces_col'] display_vert_index = settings['display_vert_index'] display_edge_index = settings['display_edge_index'] display_face_index = settings['display_face_index'] scale = settings['scale'] # draw_bg = settings['draw_bg'] draw_bface = settings['draw_bface'] font_id = 0 text_height = int(13.0 * scale) blf.size(font_id, text_height, 72) # should check prefs.dpi region_mid_width = region.width / 2.0 region_mid_height = region.height / 2.0 # vars for projection perspective_matrix = region3d.perspective_matrix.copy() def draw_index(index, vec): vec_4d = perspective_matrix @ vec.to_4d() if vec_4d.w <= 0.0: return x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w) y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w) # ---- draw text ---- index_str = str(index) txt_width, txt_height = blf.dimensions(0, index_str) level = 5 # 5 or 0 # blf.enable(0, blf.SHADOW) # blf.shadow(0, level, 0, 0, 0, 1) # blf.shadow_offset(0, 1, -1) blf.position(0, x - (txt_width / 2), y - (txt_height / 2), 0) blf.draw(0, index_str) # blf.disable(0, blf.SHADOW) if draw_bface: blf.color(font_id, *vert_idx_color) if geom.vert_data and geom.text_data: for text_item, (idx, location) in zip(geom.text_data, geom.vert_data): draw_index(text_item, location) else: for vidx in geom.vert_data: draw_index(*vidx) blf.color(font_id, *edge_idx_color) for eidx in geom.edge_data: draw_index(*eidx) blf.color(font_id, *face_idx_color) for fidx in geom.face_data: draw_index(*fidx) # if drawing all geometry, we end early. return eye = Vector(region3d.view_matrix[2][:3]) eye.length = region3d.view_distance eye_location = region3d.view_location + eye try: for obj_index, polygons in enumerate(geom.faces): edges = geom.edges[obj_index] if obj_index < len( geom.edges) else [] vertices = geom.verts[obj_index] bvh = BVHTree.FromPolygons(vertices, polygons, all_triangles=False, epsilon=0.0) cache_vert_indices = set() cache_edge_indices = set() blf.color(font_id, *face_idx_color) for idx, polygon in enumerate(polygons): # check the face normal, reject it if it's facing away. face_normal = geom.face_normals[obj_index][idx] world_coordinate = geom.face_medians[obj_index][idx] result_vector = eye_location - world_coordinate dot_value = face_normal.dot(result_vector.normalized()) if dot_value < 0.0: continue # reject # cast ray from eye towards the median of the polygon, the reycast will return (almost definitely..) # but if the return idx does not correspond with the polygon index, then it is occluded :) # bvh.ray_cast(origin, direction, distance=sys.float_info.max) : returns # if hit: (Vector location, Vector normal, int index, float distance) else all (None, ...) direction = world_coordinate - eye_location hit = bvh.ray_cast(eye_location, direction) if hit: if hit[2] == idx: if display_face_index: draw_index(idx, world_coordinate) if display_vert_index: for j in polygon: cache_vert_indices.add(j) # this could be woefully slow... if display_edge_index and edges: for j in range(len(polygon) - 1): cache_edge_indices.add( tuple(sorted([polygon[j], polygon[j + 1]]))) cache_edge_indices.add( tuple(sorted([polygon[-1], polygon[0]]))) blf.color(font_id, *vert_idx_color) for idx in cache_vert_indices: draw_index(idx, vertices[idx]) blf.color(font_id, *edge_idx_color) for idx, edge in enumerate(edges): sorted_edge = tuple(sorted(edge)) if sorted_edge in cache_edge_indices: idx1, idx2 = sorted_edge loc = vertices[idx1].lerp(vertices[idx2], 0.5) draw_index(idx, loc) cache_edge_indices.remove(sorted_edge) except Exception as err: print('---- ERROR in sv_idx_viewer28 Occlusion backface drawing ----') print(err) print(traceback.format_exc())
def moveback(self): bfvec = Vector(self.rv3d.view_matrix[2][:3]) bfvec.length = self.addonprefs.Speed * self.addonprefs.Scale * self.runmulti / self.divi self.rv3d.view_location += bfvec
def draw_indices_2D_wbg(context, args): context = bpy.context region = context.region region3d = context.space_data.region_3d geom, settings = args vert_idx_color = settings['numid_verts_col'] edge_idx_color = settings['numid_edges_col'] face_idx_color = settings['numid_faces_col'] vert_bg_color = settings['bg_verts_col'] edge_bg_color = settings['bg_edges_col'] face_bg_color = settings['bg_faces_col'] display_vert_index = settings['display_vert_index'] display_edge_index = settings['display_edge_index'] display_face_index = settings['display_face_index'] scale = settings['scale'] draw_bg = settings['draw_bg'] draw_bface = settings['draw_bface'] font_id = 0 text_height = int(13.0 * scale) blf.size(font_id, text_height, 72) # should check prefs.dpi region_mid_width = region.width / 2.0 region_mid_height = region.height / 2.0 # vars for projection perspective_matrix = region3d.perspective_matrix.copy() final_draw_data = {} data_index_counter = 0 def draw_all_text_at_once(final_draw_data): # build bg mesh and vcol data full_bg_Verts = [] add_vert_list = full_bg_Verts.extend full_bg_colors = [] add_vcol = full_bg_colors.extend for counter, (_, _, _, _, _, type_draw, pts) in final_draw_data.items(): col = settings[f'bg_{type_draw}_col'] add_vert_list(pts) add_vcol((col, ) * 6) # draw background shader = gpu.shader.from_builtin('2D_SMOOTH_COLOR') batch = batch_for_shader(shader, 'TRIS', { "pos": full_bg_Verts, "color": full_bg_colors }) batch.draw(shader) # draw text for counter, (index_str, pos_x, pos_y, txt_width, txt_height, type_draw, pts) in final_draw_data.items(): text_color = settings[f'numid_{type_draw}_col'] blf.color(font_id, *text_color) blf.position(0, pos_x, pos_y, 0) blf.draw(0, index_str) def gather_index(index, vec, type_draw): vec_4d = perspective_matrix @ vec.to_4d() if vec_4d.w <= 0.0: return x = region_mid_width + region_mid_width * (vec_4d.x / vec_4d.w) y = region_mid_height + region_mid_height * (vec_4d.y / vec_4d.w) # ---- draw text ---- index_str = str(index) txt_width, txt_height = blf.dimensions(0, index_str) # blf.position(0, x - (txt_width / 2), y - (txt_height / 2), 0) pos_x = x - (txt_width / 2) pos_y = y - (txt_height / 2) # blf.draw(0, index_str) pts = generate_points_tris(txt_width, txt_height, x, y - 1) data_index_counter = len(final_draw_data) final_draw_data[data_index_counter] = (index_str, pos_x, pos_y, txt_width, txt_height, type_draw, pts) # THIS SECTION IS ONLY EXECUTED IF BOTH FORWARD AND BACKFACING ARE DRAWN if draw_bface: # blf.color(font_id, *vert_idx_color) if geom.vert_data and geom.text_data: for text_item, (idx, location) in zip(geom.text_data, geom.vert_data): gather_index(text_item, location, 'verts') else: for vidx in geom.vert_data: gather_index(vidx[0], vidx[1], 'verts') # blf.color(font_id, *edge_idx_color) for eidx in geom.edge_data: gather_index(eidx[0], eidx[1], 'edges') # blf.color(font_id, *face_idx_color) for fidx in geom.face_data: gather_index(fidx[0], fidx[1], 'faces') draw_all_text_at_once(final_draw_data) # if drawing all geometry, we end early. return # THIS SECTION IS ONLY EXECUTED IF ONLY FORWARD FACING / NON OCCLUDED FACES ARE GOING TO BE DRAWN. eye = Vector(region3d.view_matrix[2][:3]) eye.length = region3d.view_distance eye_location = region3d.view_location + eye try: for obj_index, polygons in enumerate(geom.faces): edges = geom.edges[obj_index] if obj_index < len( geom.edges) else [] vertices = geom.verts[obj_index] bvh = BVHTree.FromPolygons(vertices, polygons, all_triangles=False, epsilon=0.0) cache_vert_indices = set() cache_edge_indices = set() # blf.color(font_id, *face_idx_color) for idx, polygon in enumerate(polygons): # check the face normal, reject it if it's facing away. face_normal = geom.face_normals[obj_index][idx] world_coordinate = geom.face_medians[obj_index][idx] result_vector = eye_location - world_coordinate dot_value = face_normal.dot(result_vector.normalized()) if dot_value < 0.0: continue # reject # cast ray from eye towards the median of the polygon, the reycast will return (almost definitely..) # but if the return idx does not correspond with the polygon index, then it is occluded :) # bvh.ray_cast(origin, direction, distance=sys.float_info.max) : returns # if hit: (Vector location, Vector normal, int index, float distance) else all (None, ...) direction = world_coordinate - eye_location hit = bvh.ray_cast(eye_location, direction) if hit: if hit[2] == idx: if display_face_index: gather_index(idx, world_coordinate, 'faces') if display_vert_index: for j in polygon: cache_vert_indices.add(j) # this could be woefully slow... if display_edge_index and edges: for j in range(len(polygon) - 1): cache_edge_indices.add( tuple(sorted([polygon[j], polygon[j + 1]]))) cache_edge_indices.add( tuple(sorted([polygon[-1], polygon[0]]))) # blf.color(font_id, *vert_idx_color) for idx in cache_vert_indices: gather_index(idx, vertices[idx], 'verts') # blf.color(font_id, *edge_idx_color) for idx, edge in enumerate(edges): sorted_edge = tuple(sorted(edge)) if sorted_edge in cache_edge_indices: idx1, idx2 = sorted_edge loc = vertices[idx1].lerp(vertices[idx2], 0.5) gather_index(idx, loc, 'edges') cache_edge_indices.remove(sorted_edge) draw_all_text_at_once(final_draw_data) except Exception as err: print('---- ERROR in sv_idx_viewer28 Occlusion backface drawing ----') print(err) print(traceback.format_exc())