Example #1
0
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)
Example #2
0
 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
Example #3
0
	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
Example #4
0
	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
Example #5
0
 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
Example #6
0
    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
Example #7
0
    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)
Example #8
0
	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
Example #9
0
    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
Example #10
0
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
Example #11
0
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())
Example #12
0
	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
Example #13
0
 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
Example #14
0
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())