예제 #1
0
 def execute(self, context):
     props = context.scene.quicker_props
     if bpy.ops.object.mode_set.poll():
         bpy.ops.object.mode_set(mode='OBJECT')
     sx, sy = self.strokes[0]["mouse"]
     ex, ey = self.strokes[-1]["mouse"]
     mouse = (sx, sy)
     ori = region_2d_to_location_3d(context.region,
                                    context.space_data.region_3d,
                                    mouse, self.cursor)
     mouse = (ex, ey)
     rad = region_2d_to_location_3d(context.region,
                                    context.space_data.region_3d,
                                    mouse, self.cursor)
     bpy.ops.curve.primitive_bezier_circle_add(radius=(rad - ori).magnitude,
                                               view_align=True,
                                               location=ori)
     context.object.data.dimensions = '2D'
     context.object.data.bevel_depth = props.bevel_depth
     context.object.data.resolution_u = 24
     if not props.fill:
         context.object.data.fill_mode = 'NONE'
     mat = bpy.data.materials.new('Material')
     context.object.data.materials.append(mat)
     mat.use_shadeless = props.shadeless
     mat.diffuse_color = props.color
     context.space_data.cursor_location = self.cursor
     self.strokes = []
     return {'FINISHED'}
예제 #2
0
def CreateCylinder(self, context):
    me = bpy.data.meshes.new('C_Cylinder')

    ob = bpy.data.objects.new('C_Cylinder', me)
    self.CurrentObj = ob

    scene = context.scene
    region = context.region
    rv3d = context.region_data
    coord = self.mouse_path[0][0], self.mouse_path[0][1]
    depthLocation = region_2d_to_vector_3d(region, rv3d, coord)
    self.ViewVector = depthLocation
    loc = region_2d_to_location_3d(region, rv3d, coord, depthLocation)
    mat = context.space_data.region_3d.view_matrix.transposed().to_3x3(
    ).to_4x4()

    ob.matrix_world = mat
    ob.location = loc

    bpy.context.scene.objects.link(ob)

    t_bm = bmesh.new()
    t_bm.from_mesh(me)

    x0 = self.mouse_path[0][0]
    y0 = self.mouse_path[0][1]
    x1 = self.mouse_path[1][0]
    y1 = self.mouse_path[1][1]

    v0 = mathutils.Vector((self.mouse_path[0][0], self.mouse_path[0][1], 0))
    v1 = mathutils.Vector((self.mouse_path[1][0], self.mouse_path[1][1], 0))
    v0 -= v1
    radius = self.mouse_path[1][0] - self.mouse_path[0][0]
    DEG2RAD = 3.14159 / (180 / self.stepAngle[self.step])
    if (self.ctrl):
        shift = (3.14159 /
                 (360 / self.stepAngle[self.step])) * self.stepRotation
    else:
        shift = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 50

    # Passe en revue tous les points du cercle pour les convertir
    FacesList = []
    for i in range(0, int(360 / self.stepAngle[self.step])):
        degInRad = i * DEG2RAD
        v0 = x0 + self.xpos + int(
            math.cos(degInRad + shift) * radius), y0 + self.ypos + int(
                math.sin(degInRad + shift) * radius)
        vec = region_2d_to_vector_3d(region, rv3d, v0)
        loc0 = region_2d_to_location_3d(region, rv3d, v0, vec) - loc
        loc0 = loc0 * mat

        t_v0 = t_bm.verts.new(loc0)

        FacesList.append(t_v0)

    t_bm.verts.index_update()

    t_face = t_bm.faces.new(FacesList)

    t_bm.to_mesh(me)
    def get_factor(self, context, edges_orig):
        """get the length in the space of edited object
        which correspond to 1px of 3d view. This method
        is used to convert the distance of mouse movement
        to offsetting width in interactive mode.
        """
        ob = context.edit_object
        mat_w = ob.matrix_world
        reg = context.region
        reg3d = context.space_data.region_3d  # Don't use context.region_data
                                              # because this will cause error
                                              # when invoked from header menu.

        co_median = Vector((0, 0, 0))
        for e in edges_orig:
            co_median += e.verts[0].co
        co_median /= len(edges_orig)
        depth_loc = mat_w * co_median  # World coords of median point

        win_left = Vector((0, 0))
        win_right = Vector((reg.width, 0))
        left = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_left, depth_loc)
        right = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_right, depth_loc)
        vec_width = mat_w.inverted_safe() * (right - left)  # width vector in the object space
        width_3d = vec_width.length   # window width in the object space

        return width_3d / reg.width
예제 #4
0
def CreatePolygon(self, context):
    me = bpy.data.meshes.new('C_Poly')

    ob = bpy.data.objects.new('C_Poly', me)
    self.CurrentObj = ob

    scene = context.scene
    region = context.region
    rv3d = context.region_data
    coord = self.mouse_path[0][0], self.mouse_path[0][1]
    depthLocation = region_2d_to_vector_3d(region, rv3d, coord)
    self.ViewVector = depthLocation
    loc = region_2d_to_location_3d(region, rv3d, coord, depthLocation)
    mat = context.space_data.region_3d.view_matrix.transposed().to_3x3().to_4x4()

    ob.matrix_world = mat
    ob.location = loc

    bpy.context.scene.objects.link(ob)

    t_bm = bmesh.new()
    t_bm.from_mesh(me)

    # Parcours tous les points et les convertit avant de les sauvegarder
    FacesList = []
    NbVertices = 0
    for x, y in self.mouse_path:
        v0 = x + self.xpos, y + self.ypos
        vec = region_2d_to_vector_3d(region, rv3d, v0)
        loc0 = region_2d_to_location_3d(region, rv3d, v0, vec) - loc

        loc0 = loc0 * mat

        x0 = loc0[0]
        y0 = loc0[1]
        z0 = loc0[2]

        NbVertices += 1
        if(NbVertices == 1):
            t_v0 = t_bm.verts.new((x0, y0, z0))
            t_init = t_v0
            xInit = x0
            yInit = y0
            zInit = z0
            t_bm.verts.index_update()
            FacesList.append(t_v0)
        else:
            t_v1 = t_bm.verts.new((x0, y0, z0))
            t_edges = t_bm.edges.new([t_v0, t_v1])
            FacesList.append(t_v1)
            NbVertices = 1
            t_v0 = t_v1

    if(self.Closed):
        t_v1 = t_bm.verts.new((xInit, yInit, zInit))
        t_edges = t_bm.edges.new([t_v0, t_v1])
        FacesList.append(t_v1)
        t_face = t_bm.faces.new(FacesList)

    t_bm.to_mesh(me)
예제 #5
0
파일: mouse.py 프로젝트: zpv5/BsMax_2_80
def get_click_point_info(x, y, ctx):
    cp = ClickPoint()
    view_orient, view_type = get_view_orientation(ctx)
    region = ctx.region
    region_data = ctx.space_data.region_3d
    if view_type in ['PERSP', 'CAMERA']:
        view_matrix = region_data.view_matrix.inverted()
        ray_start = view_matrix.to_translation()
        ray_depth = view_matrix @ Vector((0, 0, -100000))  #TODO from view
        ray_end = region_2d_to_location_3d(region, region_data, (x, y),
                                           ray_depth)
        p = get_triface_from_orient(view_orient)
        cp.view = mathutils.geometry.intersect_ray_tri(p[0], p[1], p[2],
                                                       ray_end, ray_start,
                                                       False)
        if cp.view == None:
            cp.view = Vector((0, 0, 0))
    else:
        cp.view = region_2d_to_location_3d(region, region_data, (x, y),
                                           (0, 0, 0))
    cp.screen = region_2d_to_location_3d(region, region_data, (x, y),
                                         (0, 0, 0))
    cp.local = switch_axis_by_orient(view_orient, cp.view)
    cp.orient = Vector(get_rotation_from_orient(view_orient))
    if view_type == 'ORTHO' and view_orient == 'USER':
        # TODO in orthografic user view not work correctly
        r3d = ctx.area.spaces.active.region_3d
        view_rot = r3d.view_matrix.to_euler()
    cp.view_name = view_orient
    return cp
예제 #6
0
파일: utils.py 프로젝트: Zuorion/bwrappers
def get_zoom_factor(mxw, coords, multiply=10, debug=False):
    """
    create factor based on distance to given location and region width for zoom independet scaling
    based on work by Hidesato Ikeya from offset edges addon
    upgraded to 2.8x by Machin3
    """

    # get center/average location of coords
    center = mxw @ average_locations(coords)

    region = bpy.context.region
    r3d = bpy.context.space_data.region_3d

    win_left = Vector((0, 0))
    win_right = Vector((region.width, 0))

    # project window borders into world space to the center of the selection
    left = region_2d_to_location_3d(region, r3d, win_left, center)
    right = region_2d_to_location_3d(region, r3d, win_right, center)

    # width = (right - left).length  # region with vector length in world space
    width = ((right - left)
             @ mxw.inverted()).length  # also compensate for object scaling

    factor = width / region.width

    if debug:
        print("zoom factor:", factor)

    return factor * multiply
예제 #7
0
    def modal(self, context, event):
        if event.type == 'LEFTMOUSE':
            if event.value == 'PRESS':
                x, y = event.mouse_region_x, event.mouse_region_y
                loc = region_2d_to_location_3d(context.region,
                                               context.space_data.region_3d,
                                               (x, y), self.obj.location)
                self.pre_loc = loc

                bones = context.active_object.pose.bones
                min_dist = sys.float_info.max
                for bone in bones:
                    dist = LA.norm(
                        np.array((loc - bone.center - self.obj.location)), 2)
                    if dist < min_dist:
                        min_dist = dist
                        self.bone = bone
                        # bone.select = True
                self.left_pressed = True
                return {'RUNNING_MODAL'}

            if event.value == 'RELEASE':
                if self.counter > context.scene.frame_block_nb:
                    context.scene.frame_block_nb = self.counter
                return {'FINISHED'}
        if (event.type == 'MOUSEMOVE') and (self.left_pressed == True):
            x, y = event.mouse_region_x, event.mouse_region_y
            loc = region_2d_to_location_3d(context.region,
                                           context.space_data.region_3d,
                                           (x, y), self.obj.location)
            self.bone.rotation_mode = 'QUATERNION'

            pivot_loc = self.bone.head + self.obj.location
            vec1 = loc - pivot_loc
            vec2 = self.pre_loc - pivot_loc
            angle = vec1.angle(vec2)
            normal = -np.cross(np.array(vec1), np.array(vec2))

            cam = bpy.data.objects['Camera']
            axis = Vector((normal[0], normal[1], normal[2])).normalized()
            quat = mathutils.Quaternion(axis, angle)
            # print(quat)

            mat = (Matrix.Translation(pivot_loc) * quat.to_matrix().to_4x4() *
                   Matrix.Translation(-pivot_loc))

            self.bone.matrix = self.obj.matrix_world.inverted(
            ) * mat * self.obj.matrix_world * self.bone.matrix

            self.pre_loc = loc

            self.bone.keyframe_insert(data_path="rotation_quaternion",
                                      frame=(self.current_frame +
                                             self.counter))

            self.counter += 1

            return {'RUNNING_MODAL'}

        return {'PASS_THROUGH'}
예제 #8
0
 def fromTopView(context):
     '''Create a 2D BBOX from Blender 3dview if the view is top left ortho else return None'''
     scn = context.scene
     area = context.area
     if area.type != 'VIEW_3D':
         return None
     reg = context.region
     reg3d = context.region_data
     if reg3d.view_perspective != 'ORTHO' or tuple(
             reg3d.view_matrix.to_euler()) != (0, 0, 0):
         print("View3d must be in top ortho")
         return None
     #
     w, h = area.width, area.height
     coords = (w, h)
     vec = region_2d_to_vector_3d(reg, reg3d, coords)
     loc_ne = region_2d_to_location_3d(reg, reg3d, coords, vec)
     xmax, ymax = loc_ne.x, loc_ne.y
     #
     coords = (0, 0)
     vec = region_2d_to_vector_3d(reg, reg3d, coords)
     loc_sw = region_2d_to_location_3d(reg, reg3d, coords, vec)
     xmin, ymin = loc_sw.x, loc_sw.y
     #
     return BBOX(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax)
예제 #9
0
    def get_factor(self, context, edges_orig):
        """get the length in the space of edited object
        which correspond to 1px of 3d view. This method
        is used to convert the distance of mouse movement
        to offsetting width in interactive mode.
        """
        ob = context.edit_object
        mat_w = ob.matrix_world
        reg = context.region
        reg3d = context.space_data.region_3d  # Don't use context.region_data
        # because this will cause error
        # when invoked from header menu.

        co_median = Vector((0, 0, 0))
        for e in edges_orig:
            co_median += e.verts[0].co
        co_median /= len(edges_orig)
        depth_loc = mat_w * co_median  # World coords of median point

        win_left = Vector((0, 0))
        win_right = Vector((reg.width, 0))
        left = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_left,
                                                     depth_loc)
        right = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_right,
                                                      depth_loc)
        vec_width = mat_w.inverted_safe() * (
            right - left)  # width vector in the object space
        width_3d = vec_width.length  # window width in the object space

        return width_3d / reg.width
예제 #10
0
 def execute(self, context):
     props = context.scene.quicker_props
     if bpy.ops.object.mode_set.poll():
         bpy.ops.object.mode_set(mode='OBJECT')
     bpy.ops.curve.primitive_bezier_curve_add(enter_editmode=True,
                                              view_align=True)
     bpy.ops.curve.select_all(action='SELECT')
     bpy.ops.curve.delete(type='VERT')
     context.object.data.dimensions = '2D'
     context.object.data.bevel_depth = props.bevel_depth
     context.object.data.resolution_u = 24
     if not props.fill:
         context.object.data.fill_mode = 'NONE'
     mat = bpy.data.materials.new('Material')
     context.object.data.materials.append(mat)
     mat.use_shadeless = props.shadeless
     mat.diffuse_color = props.color
     context.space_data.cursor_location = self.cursor
     sx, sy = self.strokes[0]["mouse"]
     ex, ey = self.strokes[-1]["mouse"]
     o = math.atan2(ey-sy, ex-sx)
     m = props.star_num
     d = props.star_depth
     strokes = []
     for n in range(int(m)):
         ang = 2 * PI/m * n
         bet = 2 * PI/m * (n+0.5)
         rad = math.sqrt((ex-sx) ** 2 + (ey-sy) ** 2)
         x = rad * math.cos(ang + o) + sx
         y = rad * math.sin(ang + o) + sy
         mouse = (x, y)
         loc = region_2d_to_location_3d(context.region,
                                        context.space_data.region_3d,
                                        mouse, self.cursor)
         strokes.append({"name": "", "location": loc,
                         "mouse": mouse, "pressure": 1,
                         "pen_flip": False, "time": 0,
                         "is_start": False, "size": 0})
         x = d * rad * math.cos(bet + o) + sx
         y = d * rad * math.sin(bet + o) + sy
         mouse = (x, y)
         loc = region_2d_to_location_3d(context.region,
                                        context.space_data.region_3d,
                                        mouse, self.cursor)
         strokes.append({"name": "", "location": loc,
                         "mouse": mouse, "pressure": 1,
                         "pen_flip": False, "time": 0,
                         "is_start": False, "size": 0})
     if bpy.ops.curve.draw.poll() and len(strokes) > 0:
         bpy.ops.curve.draw(error_threshold=0.0,
                            use_cyclic=True,
                            stroke=strokes)
         tool_setting = context.scene.tool_settings
         if not tool_setting.curve_paint_settings.curve_type == 'BEZIER':
             bpy.ops.curve.cyclic_toggle()
     self.strokes = []
     if bpy.ops.object.editmode_toggle.poll():
         bpy.ops.object.editmode_toggle()
     return {'FINISHED'}
예제 #11
0
def get_np_region_cos(coords, region, region_data, depth=1.5):
    #
    # Use numpy to get coords in region space
    # Bottom Left of region is 0,0
    #

    m = np.array(region_data.view_matrix)
    pmat = m[:3, :3].T  # rotates backwards without T
    loc = m[:3, 3]

    cent_reg_co = pmat @ Vector(np.array([0, 0, -depth])-loc)
    bl_reg_co = view3d_utils.region_2d_to_location_3d(
        region, region_data, [0, 0], cent_reg_co)
    br_reg_co = view3d_utils.region_2d_to_location_3d(
        region, region_data, [region.width, 0], cent_reg_co)
    tl_reg_co = view3d_utils.region_2d_to_location_3d(
        region, region_data, [0, region.height], cent_reg_co)

    loc_arr = np.array(coords)
    loc_arr.shape = [len(coords), 3]

    view_vec = np.array(view3d_utils.region_2d_to_vector_3d(
        region, region_data, [region.width/2, region.height/2]))
    view_vecs = np.tile(view_vec, (loc_arr.shape[0], 1))

    if region_data.view_perspective == 'PERSP':
        scale_center = np.array(view3d_utils.region_2d_to_origin_3d(
            region, region_data, [region.width/2, region.height/2]))
        dir_vecs = loc_arr - scale_center

        dot_offsets = np.sum((loc_arr - scale_center) * view_vec, axis=1)

        scale_3d = depth/dot_offsets

        flat_locs = scale_center + dir_vecs*scale_3d[:, None]

    elif region_data.view_perspective == 'ORTHO':
        scale_center = np.array(bl_reg_co)
        dir_vecs = view_vecs

        dot_offsets = np.sum((loc_arr - scale_center) * view_vec, axis=1)

        flat_locs = loc_arr - dir_vecs*dot_offsets[:, None]

    vec_w = np.array((br_reg_co-bl_reg_co).normalized())
    vec_h = np.array((tl_reg_co-bl_reg_co).normalized())

    h_offsets = (flat_locs - np.array(bl_reg_co)) @ vec_w
    v_offsets = (flat_locs - np.array(bl_reg_co)) @ vec_h

    r_cos = np.zeros(loc_arr.size)
    r_cos.shape = loc_arr.shape

    r_cos[:, 0] = h_offsets
    r_cos[:, 1] = v_offsets

    r_cos *= region.width/(br_reg_co-bl_reg_co).length

    return r_cos
예제 #12
0
 def handles_to_screen(self,context):
     
     region = context.region  
     rv3d = context.space_data.region_3d
     
     
     self.head.world_position = region_2d_to_location_3d(region, rv3d, (self.head.x, self.head.y),self.plane_pt)
     self.tail.world_position = region_2d_to_location_3d(region, rv3d, (self.tail.x, self.tail.y),self.plane_pt)
예제 #13
0
    def handles_to_screen(self, context):

        region = context.region
        rv3d = context.space_data.region_3d

        self.head.world_position = region_2d_to_location_3d(
            region, rv3d, (self.head.x, self.head.y), self.plane_pt)
        self.tail.world_position = region_2d_to_location_3d(
            region, rv3d, (self.tail.x, self.tail.y), self.plane_pt)
예제 #14
0
def CreateCylinder(self, context):
    me = bpy.data.meshes.new('C_Cylinder')

    ob = bpy.data.objects.new('C_Cylinder', me)
    self.CurrentObj = ob

    scene = context.scene
    region = context.region
    rv3d = context.region_data
    coord = self.mouse_path[0][0], self.mouse_path[0][1]
    depthLocation = region_2d_to_vector_3d(region, rv3d, coord)
    self.ViewVector = depthLocation
    loc = region_2d_to_location_3d(region, rv3d, coord, depthLocation)
    mat = context.space_data.region_3d.view_matrix.transposed().to_3x3().to_4x4()

    ob.matrix_world = mat
    ob.location = loc

    bpy.context.scene.objects.link(ob)

    t_bm = bmesh.new()
    t_bm.from_mesh(me)

    x0 = self.mouse_path[0][0]
    y0 = self.mouse_path[0][1]
    x1 = self.mouse_path[1][0]
    y1 = self.mouse_path[1][1]

    v0 = mathutils.Vector((self.mouse_path[0][0], self.mouse_path[0][1], 0))
    v1 = mathutils.Vector((self.mouse_path[1][0], self.mouse_path[1][1], 0))
    v0 -= v1
    radius = self.mouse_path[1][0] - self.mouse_path[0][0]
    DEG2RAD = 3.14159 / (180 / self.stepAngle[self.step])
    if(self.ctrl):
        shift = (3.14159 / (360 / self.stepAngle[self.step])) * self.stepRotation
    else:
        shift = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 50

    # Passe en revue tous les points du cercle pour les convertir
    FacesList = []
    for i in range(0, int(360 / self.stepAngle[self.step])):
        degInRad = i * DEG2RAD
        v0 = x0 + self.xpos + int(math.cos(degInRad + shift) * radius), y0 + self.ypos + int(math.sin(degInRad + shift) * radius)
        vec = region_2d_to_vector_3d(region, rv3d, v0)
        loc0 = region_2d_to_location_3d(region, rv3d, v0, vec) - loc
        loc0 = loc0 * mat

        t_v0 = t_bm.verts.new(loc0)

        FacesList.append(t_v0)

    t_bm.verts.index_update()

    t_face = t_bm.faces.new(FacesList)

    t_bm.to_mesh(me)
예제 #15
0
 def ray(self, xy): # 0,0 means region's bottom left corner
     region = self.region
     rv3d = self.region_data
     
     view_dir = self.forward
     near, far, origin = self.zbuf_range
     near = origin + view_dir * near
     far = origin + view_dir * far
     
     # Just to be sure (sometimes scene.ray_cast sayid that ray start/end aren't 3D)
     a = region_2d_to_location_3d(region, rv3d, Vector(xy).to_2d(), near).to_3d()
     b = region_2d_to_location_3d(region, rv3d, Vector(xy).to_2d(), far).to_3d()
     return a, b
예제 #16
0
def CreateCutSquare(self, context):
    """ Create a rectangle mesh """
    far_limit = 10000.0
    faces = []

    # Get the mouse coordinates
    coord = self.mouse_path[0][0], self.mouse_path[0][1]

    # New mesh
    me = bpy.data.meshes.new('CMT_Square')
    bm = bmesh.new()
    bm.from_mesh(me)

    # New object and link it to the scene
    ob = bpy.data.objects.new('CMT_Square', me)
    self.CurrentObj = ob
    context.collection.objects.link(ob)

    # Scene information
    region = context.region
    rv3d = context.region_data
    depth_location = region_2d_to_vector_3d(region, rv3d, coord)
    self.ViewVector = depth_location

    # Get a point on a infinite plane and its direction
    plane_normal = depth_location
    plane_direction = plane_normal.normalized()

    if self.snapCursor:
        plane_point = context.scene.cursor.location
    else:
        plane_point = self.OpsObj.location if self.OpsObj is not None else Vector(
            (0.0, 0.0, 0.0))

    # Find the intersection of a line going thru each vertex and the infinite plane
    for v_co in self.rectangle_coord:
        vec = region_2d_to_vector_3d(region, rv3d, v_co)
        p0 = region_2d_to_location_3d(region, rv3d, v_co, vec)
        p1 = region_2d_to_location_3d(region, rv3d, v_co,
                                      vec) + plane_direction * far_limit
        faces.append(
            bm.verts.new(
                intersect_line_plane(p0, p1, plane_point, plane_direction)))

    # Update vertices index
    bm.verts.index_update()
    # New faces
    t_face = bm.faces.new(faces)
    # Set mesh
    bm.to_mesh(me)
예제 #17
0
 def ray(self, xy, coords='REGION'):
     region = self.region
     rv3d = self.region_data
     
     xy = self.convert_ui_coord(xy, coords, 'REGION')
     
     view_dir = self.forward
     near, far, origin = self.zbuf_range
     near = origin + view_dir * near
     far = origin + view_dir * far
     
     # Just to be sure (sometimes scene.ray_cast said that ray start/end aren't 3D)
     a = region_2d_to_location_3d(region, rv3d, xy.to_2d(), near).to_3d()
     b = region_2d_to_location_3d(region, rv3d, xy.to_2d(), far).to_3d()
     return a, b
예제 #18
0
    def ray(self, xy):  # 0,0 means region's bottom left corner
        region = self.region
        rv3d = self.region_data

        view_dir = self.forward
        near, far, origin = self.zbuf_range
        near = origin + view_dir * near
        far = origin + view_dir * far

        # Just to be sure (sometimes scene.ray_cast sayid that ray start/end aren't 3D)
        a = region_2d_to_location_3d(region, rv3d,
                                     Vector(xy).to_2d(), near).to_3d()
        b = region_2d_to_location_3d(region, rv3d,
                                     Vector(xy).to_2d(), far).to_3d()
        return a, b
예제 #19
0
    def ray(self, xy, coords='REGION'):
        region = self.region
        rv3d = self.region_data

        xy = self.convert_ui_coord(xy, coords, 'REGION')

        view_dir = self.forward
        near, far, origin = self.zbuf_range
        near = origin + view_dir * near
        far = origin + view_dir * far

        # Just to be sure (sometimes scene.ray_cast said that ray start/end aren't 3D)
        a = region_2d_to_location_3d(region, rv3d, xy.to_2d(), near).to_3d()
        b = region_2d_to_location_3d(region, rv3d, xy.to_2d(), far).to_3d()
        return a, b
예제 #20
0
    def raycast(self, context, event):
        # Get the mouse position thanks to the event
        self.mouse_pos = event.mouse_region_x, event.mouse_region_y
        # Contextual active object, 2D and 3D regions
        scene = context.scene
        region = context.region
        region3D = context.space_data.region_3d

        viewlayer = viewlayer_fix_291(self, context)

        # The direction indicated by the mouse position from the current view
        self.view_vector = view3d_utils.region_2d_to_vector_3d(
            region, region3D, self.mouse_pos)
        # The view point of the user
        self.view_point = view3d_utils.region_2d_to_origin_3d(
            region, region3D, self.mouse_pos)
        # The 3D location in this direction
        self.world_loc = view3d_utils.region_2d_to_location_3d(
            region, region3D, self.mouse_pos, self.view_vector)

        result, self.loc, normal, index, object, matrix = scene.ray_cast(
            viewlayer, self.view_point, self.view_vector)

        self.camera.data.dof.use_dof = True
        if result:
            self.dis = measure(self.camera.location, self.loc)
            self.camera.data.dof.focus_distance = self.dis
예제 #21
0
    def handle_mouse_move(self, mouse_pos_2d, mouse_pos_3d, event, context):

        if self.is_extruding():

            dir = self.get_dir()
            region = context.region
            rv3d = context.space_data.region_3d

            mxy = event.mouse_region_x, event.mouse_region_y
            mpos_3d = region_2d_to_location_3d(region, rv3d, mxy,
                                               self._vertices[0])

            isect_pt, length = intersect_point_line(mpos_3d, self._vertices[0],
                                                    self._vertices[0] + dir)

            self._extrusion = length

            self.extrude_vertices(context)
            return True

        if self._vertex_moving is not None:
            self._vertices[self._vertex_moving] = mouse_pos_3d
            return True

        if self.is_created() and self._is_moving:
            diff = mouse_pos_3d - self._move_offset
            self._vertices = [vertex + diff for vertex in self._vertices]
            self._vertices_extruded = [
                vertex + diff for vertex in self._vertices_extruded
            ]
            self._move_offset = mouse_pos_3d
            return True

        return False
    def raycast(self, context, event):
        # Get the mouse position thanks to the event
        self.mouse_pos = event.mouse_region_x, event.mouse_region_y
        # Contextual active object, 2D and 3D regions
        scene = context.scene
        region = context.region
        region3D = context.space_data.region_3d

        viewlayer = viewlayer_fix_291(self,context)

        # The direction indicated by the mouse position from the current view
        self.view_vector = view3d_utils.region_2d_to_vector_3d(region, region3D, self.mouse_pos)
        # The view point of the user
        self.view_point = view3d_utils.region_2d_to_origin_3d(region, region3D, self.mouse_pos)
        # The 3D location in this direction
        self.world_loc = view3d_utils.region_2d_to_location_3d(region, region3D, self.mouse_pos, self.view_vector)

        result, self.loc, normal, index, object, matrix = scene.ray_cast(viewlayer, self.view_point, self.view_vector)


        if result:
            for obj in context.selected_objects:
                obj.select_set(False)
            dg = context.evaluated_depsgraph_get()

            eval_obj = dg.id_eval_get(object)
            context.view_layer.objects.active = object.original

            self.Mat_index = eval_obj.data.polygons[index].material_index
            object.original.active_material_index = self.Mat_index
            self.Mat = object.original.active_material
 def invoke (self, context, event):
     
     viewport_region = context.region
     viewport_region_data = context.space_data.region_3d
     viewport_matrix = viewport_region_data.view_matrix.inverted()
     
     # Shooting a ray from the camera, through the mouse cursor towards the grid with a length of 100000
     # If the camera is more than 100000 units away from the grid it won't detect a point
     ray_start = viewport_matrix.to_translation()
     ray_depth = viewport_matrix @ Vector((0,0,-100000))
     
     # Get the 3D vector position of the mouse
     ray_end = view3d_utils.region_2d_to_location_3d(viewport_region,viewport_region_data, (event.mouse_region_x, event.mouse_region_y), ray_depth )
     
     # A triangle on the grid plane. We use these 3 points to define a plane on the grid
     point_1 = Vector((0,0,0))
     point_2 = Vector((0,1,0))
     point_3 = Vector((1,0,0))
     
     # Create a 3D position on the grid under the mouse cursor using the triangle as a grid plane
     # and the ray cast from the camera
     position_on_grid = mathutils.geometry.intersect_ray_tri(point_1,point_2,point_3,ray_end,ray_start,False )
     
     # Create an empty for testing
     empty = self.create_test_empty(context)
     # Place the empty on the grid under the mouse cursor
     empty.location = position_on_grid
     
     return {'FINISHED'}
예제 #24
0
    def invoke(self, context, event):
        if context.mode == 'OBJECT':

            coord = event.mouse_region_x, event.mouse_region_y
            region = context.region
            rv3d = context.space_data.region_3d
            vec = region_2d_to_vector_3d(region, rv3d, coord)
            loc = region_2d_to_location_3d(region, rv3d, coord, vec)

            SelectedObjects.storedSelectedObjects = [
                obj for obj in context.visible_objects if obj.select
            ]
            for obj in SelectedObjects.storedSelectedObjects:
                obj.select = False

            oldPivot = bpy.data.objects.get('PivotPro', None)
            context.scene.tool_settings.use_snap = True
            if oldPivot is not None:
                enablePivot(context)
                oldPivot.location = loc
            else:
                createPivot(context)
                pivot = bpy.data.objects.get(
                    'PivotPro', None)  # it exist now after CreatePivot
                pivot.location = loc  # so put pivot under cursor
        return {'FINISHED'}
예제 #25
0
def coords_to_loc_3d(context, coords_2d_seq, depth_location):
    from bpy_extras.view3d_utils import region_2d_to_location_3d
    region = context.region
    rv3d = context.region_data

    return tuple((region_2d_to_location_3d(region, rv3d, mval, depth_location)
                  for mval in coords_2d_seq))
예제 #26
0
def mouse_raycast_to_plane(mouse_pos, context, point, normal):
    ''' Get 3D point on plane from mouse.\n
        Params:\n
        \tmouse pos : type = tuple(0,0)
        \tcontext   : type = bpy.context
        \tpoint     : type = Vector, desc = the planes origin
        \tnormal    : type = Vector, desc = the planes direction
        Returns -> Vector 3D'''

    # Get the context arguments
    region = context.region
    rv3d = context.region_data
    intersection = Vector((0, 0, 0))
    try:
        # Camera Origin
        origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, mouse_pos)
        # Mouse origin
        mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, mouse_pos)
        # Camera Origin + Mouse
        ray_origin = origin + mouse
        # From the mouse to the viewport
        loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos,
                                                    ray_origin - origin)
        # Ray to plane
        intersection = mathutils.geometry.intersect_line_plane(
            ray_origin, loc, point, normal)

    except:
        intersection = Vector((0, 0, 0))

    if intersection is None:
        intersection = Vector((0, 0, 0))

    return intersection
예제 #27
0
 def add_draw(self, context, event):
     mouse = (event.mouse_region_x, event.mouse_region_y)
     loc = region_2d_to_location_3d(context.region,
                                    context.space_data.region_3d,
                                    mouse, self.cursor)
     stroke = {"mouse": mouse, "pressure": event.pressure, "location": loc}
     self.strokes.append(stroke)
예제 #28
0
    def execute(self, context):
        # Contextual active object, 2D and 3D regions
        region = bpy.context.region
        region3D = bpy.context.space_data.region_3d

        mouse_offset = self.mouse

        # The direction indicated by the mouse position from the current view
        view_vector = view3d_utils.region_2d_to_vector_3d(
            region, region3D, mouse_offset)
        # The 3D location in this direction
        offset = view3d_utils.region_2d_to_location_3d(region, region3D,
                                                       mouse_offset,
                                                       view_vector)

        mw = self.active_joint.matrix_world.inverted()
        mouse_offset_from_first_ja = mw * offset
        for ja, jb in self.joints:
            jb.location = ja.location + mouse_offset_from_first_ja

        # Update active object so the next #exj will get the correct cursor
        # offset
        if jb:
            bpy.context.scene.objects.active = jb

        return {'FINISHED'}
예제 #29
0
    def modal(self, context, event):
        verts = self.verts
        edges = self.edges
        me = self.me

        if event.type == 'LEFTMOUSE':
            if event.value == 'RELEASE':
                if (self.first):
                    verts = []
                    found = 'NewMesh' in bpy.data.meshes
                    print(found)
                    if found:
                        bpy.data.meshes.remove(bpy.data.meshes["NewMesh"])

                vectorClicked = (view3d_utils.region_2d_to_location_3d(
                    bpy.context.region, bpy.context.space_data.region_3d,
                    (event.mouse_region_x, event.mouse_region_y),
                    mathutils.Vector((0, 0, 0))))
                verts.append((vectorClicked[0], vectorClicked[1], 0))
                for i in range(len(self.verts) - 1):
                    edges.append((i, i + 1))

                self.addVerts(verts)
                self.verts = verts

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            return {'FINISHED'}

        return {'RUNNING_MODAL'}
def get_position_on_grid(mouse_pos, ray_max=1e4):
    viewport_region = bpy.context.region
    viewport_r3d = bpy.context.region_data
    viewport_matrix = viewport_r3d.view_matrix.inverted()
    cam_obj = bpy.context.space_data.camera

    # Shooting a ray from the camera, through the mouse cursor towards the grid with a length of 1e5
    # If the camera is more than 1e5 units away from the grid it won't detect a point
    ray_start = viewport_matrix.to_translation()
    ray_depth = viewport_matrix @ Vector((0, 0, -1e5))

    # Get the 3D vector position of the mouse
    ray_end = view3d_utils.region_2d_to_location_3d(viewport_region, viewport_r3d, (mouse_pos[0], mouse_pos[1]), ray_depth)

    # A triangle on the grid plane. We use these 3 points to define a plane on the grid
    point_1 = Vector((0, 0, 0))
    point_2 = Vector((0, 1, 0))
    point_3 = Vector((1, 0, 0))

    # Create a 3D position on the grid under the mouse cursor using the triangle as a grid plane
    # and the ray cast from the camera
    position_on_grid = mathutils.geometry.intersect_ray_tri(point_1, point_2, point_3, ray_end, ray_start, False)
    if position_on_grid is None:
        return None

    if viewport_is_orthographic(viewport_r3d, None if cam_obj is None else cam_obj.data):
        # multiply by ray max
        position_on_grid = position_on_grid * ray_max

    return position_on_grid
예제 #31
0
    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type == 'MOUSEMOVE':

            #Get the mouse position thanks to the event            
            self.mouse_pos = [event.mouse_region_x, event.mouse_region_y]

            #Contextual active object, 2D and 3D regions
            self.object = bpy.context.object
            region = bpy.context.region
            region3D = bpy.context.space_data.region_3d

            #The direction indicated by the mouse position from the current view
            view_vector = view3d_utils.region_2d_to_vector_3d(region, region3D, self.mouse_pos)
            #The 3D location in this direction
            self.loc = view3d_utils.region_2d_to_location_3d(region, region3D, self.mouse_pos, view_vector)
            #The 3D location converted in object local coordinates
            self.loc = self.object.matrix_world.inverted() * self.loc

        elif event.type in {'ESC'}:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            return {'CANCELLED'}

        return {'PASS_THROUGH'}
예제 #32
0
def cursor_2d_to_location_3d(context, event):
    from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_location_3d
    
    coords = event.mouse_region_x, event.mouse_region_y
    region = context.region
    rv3d = context.space_data.region_3d
    return region_2d_to_location_3d(region, rv3d, coords, region_2d_to_vector_3d(region, rv3d, coords))
예제 #33
0
    def raycast_mouse(self, context, event):
        scene = context.scene
        region = context.region
        region_3d = context.space_data.region_3d
        mouse_pos = (event.mouse_region_x, event.mouse_region_y)

        direction = view3d_utils.region_2d_to_vector_3d(
            region, region_3d, mouse_pos)
        endpoint = view3d_utils.region_2d_to_location_3d(
            region, region_3d, mouse_pos, region_3d.view_location)

        if region_3d.is_perspective:
            direction = -direction
            origin = endpoint + direction * region_3d.view_distance
            farpoint = origin + direction * 1000
        else:
            origin = endpoint + direction * region_3d.view_distance
            farpoint = origin - direction * 1000

        if self.clone:
            self.clone.hide = True

        result, obj, matrix, surface, normal = scene.ray_cast(origin, farpoint)

        if self.clone:
            self.clone.hide = False

        if result:
            endpoint = surface
        else:
            normal = mathutils.Vector((0, 0, 1))

        return (endpoint, normal)
예제 #34
0
        def invoke(self, context, event):  
            self.target = bpy.context.active_object  
            
            if context.space_data.type == 'VIEW_3D':
              
                self.scene = context.scene
                self.region = context.region
                self.rv3d = context.region_data
                self.mouse_co = event.mouse_region_x, event.mouse_region_y
                self.depth = view3d_utils.region_2d_to_vector_3d(self.region, self.rv3d, self.mouse_co)
                self.emp_co = view3d_utils.region_2d_to_location_3d(self.region, self.rv3d, self.mouse_co, self.depth)
                
                bpy.ops.object.select_all(action='DESELECT')
                
                # add custom objects
                bpy.ops.object.empty_add()
                
                context.object.location = self.emp_co
                context.window_manager.modal_handler_add(self)            

                # need active to set origin
                bpy.context.scene.objects.active = self.target

                return {'RUNNING_MODAL'}
            else:
                self.report({'WARNING'}, "Active space must be a View3d")  
                return {'CANCELLED'}
예제 #35
0
def raycast_plane(context, event):
    viewport_region = context.region
    viewport_region_data = context.space_data.region_3d
    viewport_matrix = viewport_region_data.view_matrix.inverted()

    # Shooting a ray from the camera, through the mouse cursor towards the grid with length 100000
    # if the camera is more than 10000 units away from the grid it won't detect a hit
    ray_start = viewport_matrix.to_translation()
    ray_depth = viewport_matrix @ Vector((0, 0, -10000))

    # Get the 3D vector position of the mouse
    ray_end = view3d_utils.region_2d_to_location_3d(
        viewport_region, viewport_region_data,
        (event.mouse_region_x, event.mouse_region_y), ray_depth)

    # 3 Points to build a plane from
    point_1 = Vector((0, 0, 0))
    point_2 = Vector((0, 1, 0))
    point_3 = Vector((1, 0, 0))

    # Create a 3D position on the grid under the mouse using the grid plane points
    # and the ray cast from the camera
    position_on_grid = mathutils.geometry.intersect_ray_tri(
        point_1, point_2, point_3, ray_end, ray_start, False)

    return position_on_grid
예제 #36
0
    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type == 'MOUSEMOVE':
            context.area.header_text_set("WIP")

            new_pos = region_2d_to_location_3d(context.region,
                                               context.space_data.region_3d,
                                               (event.mouse_x, event.mouse_y),
                                               self.vto0)
            self.offset = new_pos - self.pos
            self.vto = self.vto0 + self.offset
            self.update_shader_batch()

        elif event.type == 'LEFTMOUSE':
            cf = self.vto - self.vfrom
            cf.rotate(self.quat.inverted())
            self.bone.simbone.custom_force = cf
            self.finish(context)
            return {'FINISHED'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            self.finish(context)
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}
예제 #37
0
    def invoke(self, context, event):
        if context.mode == 'OBJECT':

            coord = event.mouse_region_x, event.mouse_region_y
            region = context.region
            rv3d = context.space_data.region_3d
            vec = region_2d_to_vector_3d(region, rv3d, coord)
            loc = region_2d_to_location_3d(region, rv3d, coord, vec)

            SelectedObjects.storedSelectedObjects = [
                obj for obj in context.visible_objects if obj.select
            ]
            for obj in SelectedObjects.storedSelectedObjects:
                obj.select = False

            oldPivot = bpy.data.objects.get('PivotPro', None)
            context.scene.tool_settings.use_snap = True
            if oldPivot is not None:
                enablePivot(context)
                oldPivot.location = loc
            else:
                createPivot(context)
                pivot = bpy.data.objects.get(
                    'PivotPro', None)  # it exist now after CreatePivot
                pivot.location = loc  # so put pivot under cursor
        return {'FINISHED'}
예제 #38
0
def get_3d_vertex(context, vertex_2d):
    region = context.region
    rv3d = context.space_data.region_3d

    dir = get_view_direction(context) * -1

    return region_2d_to_location_3d(region, rv3d, vertex_2d, dir)
예제 #39
0
    def invoke(self, context, event):
        rv3d = context.region_data
        region = context.region

        self.mode = persistent_settings['mode']
        self.transform_all = persistent_settings['transform_all']
        self.constrain_x = False
        self.constrain_y = False

        if rv3d.view_perspective == 'PERSP':
            self.report({'WARNING'}, 'Perspective camera unsupported.')
            return {'CANCELLED'}

        self.view_perspective = rv3d.view_perspective
        self.camera_orientation = (
            get_view_orientation_from_quaternion(rv3d.view_rotation))
        self.region_offset_x = 0
        self.region_offset_y = 0

        self.initial_mouse = Vector((
            event.mouse_region_x,
            event.mouse_region_y))
        self.initial_mouse_location_3d = (
            view3d_utils.region_2d_to_location_3d(
                region, rv3d, self.initial_mouse, Vector()))

        self.valid_images = []
        self.previous_rotation_offset = 0.0
        self.revolutions = 0

        self.previous_mouse_cp = 1.0

        # Get currently visible images
        for background_image in context.space_data.background_images:
            image_orientation = background_image.view_axis
            if (background_image.show_background_image
                and background_image.image is not None
                and (rv3d.view_perspective == 'CAMERA'
                     and image_orientation in {'CAMERA', 'ALL'}
                     or rv3d.view_perspective == 'ORTHO'
                     and self.camera_orientation != 'UNDEFINED'
                     and image_orientation in {self.camera_orientation, 'ALL'}
                     )):
                self.valid_images.append(background_image)

        if len(self.valid_images):
            self.active_image = min(
                persistent_settings['active_image'],
                len(self.valid_images)-1)
            self.init_images(self.valid_images)
            context.window_manager.modal_handler_add(self)
            args = (self, context)
            self.do_draw = self.mode in ('ROTATE', 'SCALE')
            self._handle = bpy.types.SpaceView3D.draw_handler_add(
                draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, 'No background image found.')
            return {'CANCELLED'}
예제 #40
0
    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':
            # the arguments we pass the the callback
            args = (self, context)
            # Add the region OpenGL drawing callback
            self._timer = context.window_manager.event_timer_add(.1, context.window)  #bpy.types.WindoManager.event_time_add?
            self._handle = bpy.types.SpaceView3D.draw_handler_add(bgl_utils.draw_callback_crevice_walking, args, 'WINDOW', 'POST_PIXEL')

            #initialze important values and gather important info
            region = context.region  
            rv3d = context.space_data.region_3d
            coord = event.mouse_region_x, event.mouse_region_y
            
            self.tracer_name = context.object.name #adding bpy here because getting weird error
            self.target_name = [ob.name for ob in context.selected_editable_objects if ob.name != self.tracer_name][0]
            
            tracer = bpy.data.objects[self.tracer_name]
            target = bpy.data.objects[self.target_name]
            
            #target.select = False
            tracer.select = True
            context.scene.objects.active = tracer
            
            #mod = tracer.modifers['Shrinkwrap']  #going to need to do some checking for dumb scenarios
            #self.target = mod.target
                      
            vec = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
            ray_origin = view3d_utils.region_2d_to_location_3d(region, rv3d, coord, vec)    
    
            #raycast onto active object
            ray_target = ray_origin + 10000*vec
            [hit, normal, face] = odcutils.obj_ray_cast(target, target.matrix_world, ray_origin, ray_target)
            
            self.max_iters = 50
            self.keep_iterating = False  #turn this off/on when we get convergence on the bias point or add a new bias point
            self.session_iterations = 0
            
            if hit:
                self.current_bias_point = target.matrix_world * hit
            else:
                self.current_bias_point = target.location
            
            
            self.confirmed_path = []
            self.pending_path = [tracer.location.copy()]
            self.bias_points = []
            self.bias_normals = []  #gotta keep track of the normals so we can re-orient the tracker pointed the right way
            
            self.step_size = .5
            self.convergence_limit = 5
            

            

            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}
예제 #41
0
	def mouseTo3d(self, context, x, y):
		'''Convert event.mouse_region to world coordinates'''
		coords = (x, y)
		reg = context.region
		reg3d = context.region_data
		vec = region_2d_to_vector_3d(reg, reg3d, coords)
		loc = region_2d_to_location_3d(reg, reg3d, coords, vec)
		return loc
def coords_to_loc_3d(context, coords_2d_seq, depth_location):
    from bpy_extras.view3d_utils import region_2d_to_location_3d
    region = context.region
    rv3d = context.region_data

    return tuple((
        region_2d_to_location_3d(region, rv3d, mval, depth_location)
        for mval in coords_2d_seq
    ))
예제 #43
0
    def move(self, context, event):
        xy = region_2d_to_location_3d(
                context.region,
                context.space_data.region_3d,
                (event.mouse_region_x, event.mouse_region_y),
                Vector(),
                ).xy

        self.ob.location.xy = xy
def unproject(points, axis, properties):
    """Unproject points on a plane to vertices in 3d space."""
    for p in points:
        new_p = p["point"] - p["delta"] * properties["influence"]

        old_v = p["id"].co
        new_v = view3d_utils.region_2d_to_location_3d(axis["region"], axis["rv3d"], new_p.to_2d(), p["depth"])
        p["v'"] = new_v

    return points
예제 #45
0
 def unproject(self, xy, pos=None, align=False): # 0,0 means region's bottom left corner
     if align:
         xy = snap_pixel_vector(xy)
     if pos is None:
         pos = self.focus
     elif isinstance(pos, (int, float)):
         pos = self.zbuf_range[2] + self.forward * pos
     region = self.region
     rv3d = self.region_data
     return region_2d_to_location_3d(region, rv3d, xy.copy(), pos.copy())
def unproject(points,axis,properties):
    """Unproject points on a plane to vertices in 3d space."""
    for p in points:
        new_p = p['point']-p['delta']*properties['influence']
        
        old_v = p['id'].co
        new_v = view3d_utils.region_2d_to_location_3d(axis['region'],axis['rv3d'],new_p.to_2d(),p['depth'])
        p["v'"]=new_v
    
    return points
예제 #47
0
def mouseTo3d(context, x, y):
	'''Convert event.mouse_region to world coordinates'''
	if context.area.type != 'VIEW_3D':
		raise Exception('Wrong context')
	coords = (x, y)
	reg = context.region
	reg3d = context.region_data
	vec = region_2d_to_vector_3d(reg, reg3d, coords)
	loc = region_2d_to_location_3d(reg, reg3d, coords, vec) #WARNING, this function return indeterminate value when view3d clip distance is too large
	return loc
예제 #48
0
    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type =='LEFT_ALT' or event.type == 'RIGHT_ALT':
            if event.value == 'PRESS': pt_buf.alt = True
            if event.value == 'RELEASE': pt_buf.alt = False
            return {'RUNNING_MODAL'}

        elif event.type =='LEFT_SHIFT' or event.type == 'RIGHT_SHIFT':
            if event.value == 'PRESS': pt_buf.shift = True
            if event.value == 'RELEASE': pt_buf.shift = False
            return {'RUNNING_MODAL'}

        elif event.type == 'MOUSEMOVE':
            if pt_buf.list_m_loc_2d != []:
                pt_buf_list_m_loc_3d_last_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, pt_buf.list_m_loc_3d[-1])

                if pt_buf.alt == True:
                    pt_buf.x = pt_buf_list_m_loc_3d_last_2d[0]
                    pt_buf.y = event.mouse_region_y
                elif pt_buf.shift == True:
                    pt_buf.x = event.mouse_region_x
                    pt_buf.y = pt_buf_list_m_loc_3d_last_2d[1]
                else:
                    pt_buf.x = event.mouse_region_x
                    pt_buf.y = event.mouse_region_y
            else:
                pt_buf.x = event.mouse_region_x
                pt_buf.y = event.mouse_region_y

        elif event.type == 'LEFTMOUSE':
            if event.value == 'PRESS':
                mouse_loc_2d = Vector((pt_buf.x, pt_buf.y))
                pt_buf.list_m_loc_2d.append(mouse_loc_2d)

                mouse_loc_3d = region_2d_to_location_3d(context.region, context.space_data.region_3d, mouse_loc_2d, pt_buf.depth_location)
                pt_buf.list_m_loc_3d.append(mouse_loc_3d)

                pt_buf.depth_location = pt_buf.list_m_loc_3d[-1]      # <----- depth location
            elif event.value == 'RELEASE':
                pass
        elif event.type == 'RIGHTMOUSE':
            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
            self.execute(context)
            pt_buf.sws = 'off'
            return {'FINISHED'}
        elif event.type == 'ESC':
            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
            pt_buf.list_m_loc_2d[:] = []
            pt_buf.list_m_loc_3d[:] = []
            pt_buf.depth_location = Vector((0.0, 0.0, 0.0))
            pt_buf.sws = 'off'
            return {'CANCELLED'}
        return {"PASS_THROUGH"}
예제 #49
0
 def unproject(self, xy, pos=None, align=False, coords='REGION'):
     region = self.region
     rv3d = self.region_data
     
     xy = self.convert_ui_coord(xy, coords, 'REGION')
     
     if align: xy = snap_pixel_vector(xy)
     
     if pos is None:
         pos = self.focus
     elif isinstance(pos, (int, float)):
         pos = self.zbuf_range[2] + self.forward * pos
     
     return region_2d_to_location_3d(region, rv3d, Vector(xy), Vector(pos)).to_3d()
예제 #50
0
	def fromTopView(cls, context):
		'''Create a 2D BBOX from Blender 3dview if the view is top left ortho else return None'''
		scn = context.scene
		area = context.area
		if area.type != 'VIEW_3D':
			return None
		reg = context.region
		reg3d = context.region_data
		if reg3d.view_perspective != 'ORTHO' or tuple(reg3d.view_matrix.to_euler()) != (0,0,0):
			print("View3d must be in top ortho")
			return None
		#
		w, h = area.width, area.height
		coords = (w, h)
		vec = region_2d_to_vector_3d(reg, reg3d, coords)
		loc_ne = region_2d_to_location_3d(reg, reg3d, coords, vec)
		xmax, ymax = loc_ne.x, loc_ne.y
		#
		coords = (0, 0)
		vec = region_2d_to_vector_3d(reg, reg3d, coords)
		loc_sw = region_2d_to_location_3d(reg, reg3d, coords, vec)
		xmin, ymin = loc_sw.x, loc_sw.y
		#
		return cls(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax)
    def get_factor(self, context, pos_mouse, edges):
        """get the length in the space of edited object
        which correspond to 1px of 3d view. This method
        is used to convert the distance of mouse movement
        to offsetting width in interactive mode.
        """
        ob = context.edit_object
        mat_w = ob.matrix_world
        reg = context.region
        reg3d = context.region_data

        verts = set(e.verts[0] for e in edges)
        # get the nearest vertex to the mouse position
        v_nearest = self.get_nearest_vert(context, pos_mouse, tuple(verts))
        depth_loc = mat_w * v_nearest.co  # coord of the vertex in the world space

        win_left = Vector((0, 0))
        win_right = Vector((reg.width, 0))
        left = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_left, depth_loc)
        right = view3d_utils.region_2d_to_location_3d(reg, reg3d, win_right, depth_loc)
        vec_width = mat_w.inverted_safe() * (right - left)  # width vector in the object space
        width_3d = vec_width.length   # window width in the object space

        return width_3d / reg.width
예제 #52
0
def mouse_path_to_spline(
        context,
        mouse_path: list,
) -> None:

    curve_freehand = context.scene.curve_freehand

    spline_data = calc_spline(
        mouse_path,
        error=curve_freehand.error_threshold,
        use_detect_corners=curve_freehand.use_detect_corners,
        detect_corners_angle_threshold=curve_freehand.detect_corners_angle_threshold,
    )

    obj = context.object
    curve = obj.data
    matrix_inverse = obj.matrix_world.inverted()

    from bpy_extras.view3d_utils import region_2d_to_location_3d
    region = context.region
    rv3d = context.region_data
    depth_pt = context_cursor(context)

    spline_data = [
        Cubic(*[
            (*(matrix_inverse * region_2d_to_location_3d(region, rv3d, pt, depth_pt)), *pt[2:])
            for pt in cubic])
        for cubic in spline_data]

    bpy.ops.curve.select_all(action='DESELECT')

    spline = curve.splines.new(type='BEZIER')
    points_to_spline(
        spline, spline_data,
        curve_freehand.pressure_min,
        curve_freehand.pressure_max,
    )

    for bezt in spline.bezier_points:
        bezt.select_control_point = True
        bezt.select_left_handle = True
        bezt.select_right_handle = True

        # we could get this from the calculation...
        a, b, c = bezt.handle_left, bezt.co, bezt.handle_right
        if (a - b).angle(b - c, -1.0) < 1e-2:
            bezt.handle_left_type = bezt.handle_right_type = 'ALIGNED'
예제 #53
0
 def from_ndc(self, pos, to_01=False):
     region = self.region
     rv3d = self.region_data
     
     nx = pos[0]
     ny = pos[1]
     nz = pos[2]
     if not to_01:
         nx = (nx + 1.0) * 0.5
         ny = (ny + 1.0) * 0.5
         nz = (nz + 1.0) * 0.5
     
     near, far, origin = self.zbuf_range
     xy = Vector((nx * region.width, ny * region.height))
     z = near + nz * (far - near)
     pos = origin + self.forward * z
     return region_2d_to_location_3d(region, rv3d, xy, pos).to_3d()
    def modal(self, context, event):
        if event.type == 'MOUSEMOVE':
            # self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
            new_cell_loc = region_2d_to_location_3d(context.region, context.space_data.region_3d, 
                (event.mouse_region_x, event.mouse_region_y), context.scene.cursor_location)
            new_cell_loc = [round(c) for c in new_cell_loc]
            print('CREATING CELL AT: {}'.format(new_cell_loc))
            auto.add(*new_cell_loc)

        elif event.type == 'LEFTMOUSE':
            return {'FINISHED'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            print("NOT DRAWING")
            return {'CANCELLED'}
            
        return{'RUNNING_MODAL'}
 def pan(ary):
     #get reference to all the areas
     area = bpy.context.window_manager.windows[0].screen.areas[1]
     viewport = area.regions[4]
     rv3d = area.spaces[0].region_3d
     
     #convert view location's 3D Cords to 2D Cords
     locCord = rv3d.view_location
     cord =  view3d_utils.location_3d_to_region_2d(viewport, rv3d, locCord)
     
     cord[0] += float(ary[1])
     cord[1] += float(ary[2])
     
     #convert 2d cords to 3d Cords and apply
     vec = view3d_utils.region_2d_to_vector_3d(viewport, rv3d, cord)
     loc = view3d_utils.region_2d_to_location_3d(viewport, rv3d, cord, vec)
     rv3d.view_location = loc
예제 #56
0
    def modal(self, context, event):
        context.area.tag_redraw()

        # allow moving in the 3D View
        if event.type in {
                'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
                'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
                'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
            return {'PASS_THROUGH'}

        if event.type in {'LEFT_ALT', 'RIGHT_ALT'}:
            if event.value == 'PRESS':
                pt_buf.alt = True
            if event.value == 'RELEASE':
                pt_buf.alt = False
            return {'RUNNING_MODAL'}

        elif event.type in {'LEFT_CTRL', 'RIGHT_CTRL'}:
            if event.value == 'PRESS':
                pt_buf.ctrl = not pt_buf.ctrl
            return {'RUNNING_MODAL'}

        elif event.type in {'LEFT_SHIFT', 'RIGHT_SHIFT'}:
            if event.value == 'PRESS':
                pt_buf.shift = True
            if event.value == 'RELEASE':
                pt_buf.shift = False
            return {'RUNNING_MODAL'}

        elif event.type == 'MOUSEMOVE':
            if pt_buf.list_m_loc_2d != []:
                pt_buf_list_m_loc_3d_last_2d = location_3d_to_region_2d(
                                                context.region,
                                                context.space_data.region_3d,
                                                pt_buf.list_m_loc_3d[-1]
                                                )
                if pt_buf.alt is True:
                    pt_buf.x = pt_buf_list_m_loc_3d_last_2d[0]
                    pt_buf.y = event.mouse_region_y
                elif pt_buf.shift is True:
                    pt_buf.x = event.mouse_region_x
                    pt_buf.y = pt_buf_list_m_loc_3d_last_2d[1]
                else:
                    pt_buf.x = event.mouse_region_x
                    pt_buf.y = event.mouse_region_y
            else:
                pt_buf.x = event.mouse_region_x
                pt_buf.y = event.mouse_region_y

        elif event.type == 'LEFTMOUSE':
            if event.value == 'PRESS':
                mouse_loc_2d = Vector((pt_buf.x, pt_buf.y))
                pt_buf.list_m_loc_2d.append(mouse_loc_2d)

                mouse_loc_3d = region_2d_to_location_3d(
                                                context.region, context.space_data.region_3d,
                                                mouse_loc_2d, pt_buf.depth_location
                                                )
                pt_buf.list_m_loc_3d.append(mouse_loc_3d)

                pt_buf.depth_location = pt_buf.list_m_loc_3d[-1]   # <-- depth location
                # run Extrude at cursor
                if pt_buf.ctrl:
                    try:
                        bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source=False)
                    except:
                        pass
            elif event.value == 'RELEASE':
                pass
        elif event.type == 'RIGHTMOUSE':
            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
            self.execute(context)
            pt_buf.sws = 'off'
            return {'FINISHED'}
        elif event.type == 'ESC':
            context.space_data.draw_handler_remove(self._handle_px, 'WINDOW')
            store_restore_view(context, False)
            pt_buf.list_m_loc_2d[:] = []
            pt_buf.list_m_loc_3d[:] = []
            pt_buf.depth_location = Vector((0.0, 0.0, 0.0))
            pt_buf.sws = 'off'
            pt_buf.store_view_matrix = Matrix()
            pt_buf.view_location = (0.0, 0.0, 0.0)
            pt_buf.ctrl = False
            return {'CANCELLED'}

        # Return has to be modal or the tool can crash
        # It's better to define PASS_THROUGH as the exception and not the default
        return {'RUNNING_MODAL'}
예제 #57
0
def draw_callback_px(self, context):
    font_id = 0
    alpha = context.scene.pen_tool_props.a
    font_size = context.scene.pen_tool_props.fs

    bgl.glColor4f(0.0, 0.6, 1.0, alpha)
    bgl.glPointSize(4.0)
    bgl.glBegin(bgl.GL_POINTS)
    bgl.glVertex2f(pt_buf.x, pt_buf.y)
    bgl.glEnd()
    bgl.glDisable(bgl.GL_BLEND)

    # location 3d
    if context.scene.pen_tool_props.b2 is True:
        mloc3d = region_2d_to_location_3d(
                        context.region,
                        context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)),
                        pt_buf.depth_location
                        )
        blf.position(font_id, pt_buf.x + 15, pt_buf.y - 15, 0)
        blf.size(font_id, font_size, context.user_preferences.system.dpi)
        blf.draw(font_id,
                '(' + str(round(mloc3d[0], 4)) + ', ' + str(round(mloc3d[1], 4)) +
                ', ' + str(round(mloc3d[2], 4)) + ')')

    n = len(pt_buf.list_m_loc_3d)

    if n != 0:
        # add points
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glPointSize(4.0)
        bgl.glBegin(bgl.GL_POINTS)
        for i in pt_buf.list_m_loc_3d:
            loc_0 = location_3d_to_region_2d(
                            context.region, context.space_data.region_3d, i
                            )
            bgl.glVertex2f(loc_0[0], loc_0[1])
        bgl.glEnd()
        bgl.glDisable(bgl.GL_BLEND)

        # text next to the mouse
        m_loc_3d = region_2d_to_location_3d(
                            context.region,
                            context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)),
                            pt_buf.depth_location
                            )
        vec0 = pt_buf.list_m_loc_3d[-1] - m_loc_3d
        blf.position(font_id, pt_buf.x + 15, pt_buf.y + 15, 0)
        blf.size(font_id, font_size, context.user_preferences.system.dpi)
        blf.draw(font_id, str(round(vec0.length, 4)))

        #  angle first after mouse
        if n >= 2:
            vec1 = pt_buf.list_m_loc_3d[-2] - pt_buf.list_m_loc_3d[-1]
            if vec0.length == 0.0 or vec1.length == 0.0:
                pass
            else:
                ang = vec0.angle(vec1)

                if round(degrees(ang), 2) == 180.0:
                    text_0 = '0.0'
                elif round(degrees(ang), 2) == 0.0:
                    text_0 = '180.0'
                else:
                    text_0 = str(round(degrees(ang), 2))

                loc_4 = location_3d_to_region_2d(
                                        context.region,
                                        context.space_data.region_3d,
                                        pt_buf.list_m_loc_3d[-1]
                                        )
                bgl.glColor4f(0.0, 1.0, 0.525, alpha)
                blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0)
                blf.size(font_id, font_size, context.user_preferences.system.dpi)
                blf.draw(font_id, text_0 + '')

        bgl.glLineStipple(4, 0x5555)
        bgl.glEnable(bgl.GL_LINE_STIPPLE)      # enable line stipple

        bgl.glColor4f(0.0, 0.6, 1.0, alpha)
        #  draw line between last point and mouse
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glBegin(bgl.GL_LINES)
        loc_1 = location_3d_to_region_2d(
                                context.region,
                                context.space_data.region_3d,
                                pt_buf.list_m_loc_3d[-1]
                                )
        bgl.glVertex2f(loc_1[0], loc_1[1])
        bgl.glVertex2f(pt_buf.x, pt_buf.y)
        bgl.glEnd()
        bgl.glDisable(bgl.GL_BLEND)

        # draw lines between points
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glBegin(bgl.GL_LINE_STRIP)
        for j in pt_buf.list_m_loc_3d:
            loc_2 = location_3d_to_region_2d(context.region, context.space_data.region_3d, j)
            bgl.glVertex2f(loc_2[0], loc_2[1])
        bgl.glEnd()
        bgl.glDisable(bgl.GL_BLEND)

        bgl.glDisable(bgl.GL_LINE_STIPPLE)      # disable line stipple

        # draw line length between points
        if context.scene.pen_tool_props.b1 is True:
            for k in range(n - 1):
                loc_3 = location_3d_to_region_2d(
                                context.region, context.space_data.region_3d,
                                (pt_buf.list_m_loc_3d[k] + pt_buf.list_m_loc_3d[(k + 1) % n]) * 0.5
                                )
                blf.position(font_id, loc_3[0] + 10, loc_3[1] + 10, 0)
                blf.size(font_id, font_size, context.user_preferences.system.dpi)
                blf.draw(font_id,
                         str(round((pt_buf.list_m_loc_3d[k] - pt_buf.list_m_loc_3d[(k + 1) % n]).length, 4)))

        # draw all angles
        if context.scene.pen_tool_props.b0 is True:
            for h in range(n - 1):
                if n >= 2:
                    if h == 0:
                        pass
                    else:
                        vec_ = pt_buf.list_m_loc_3d[h] - pt_buf.list_m_loc_3d[(h - 1) % n]
                        vec_1_ = pt_buf.list_m_loc_3d[h]
                        vec_2_ = pt_buf.list_m_loc_3d[(h - 1) % n]
                        if vec_.length == 0.0 or vec_1_.length == 0.0 or vec_2_.length == 0.0:
                            pass
                        else:
                            ang = vec_.angle(vec_1_ - vec_2_)
                            if round(degrees(ang)) == 0.0:
                                pass
                            else:
                                loc_4 = location_3d_to_region_2d(
                                                context.region, context.space_data.region_3d,
                                                pt_buf.list_m_loc_3d[h]
                                                )
                                bgl.glColor4f(0.0, 1.0, 0.525, alpha)
                                blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0)
                                blf.size(font_id, font_size, context.user_preferences.system.dpi)
                                blf.draw(font_id, str(round(degrees(ang), 2)) + '')
    # tools on / off
    bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
    blf.position(font_id, self.text_location, 20, 0)
    blf.size(font_id, 15, context.user_preferences.system.dpi)
    blf.draw(font_id, "Draw On")
    blf.position(font_id, self.text_location, 40, 0)
    blf.draw(font_id, "Extrude On" if pt_buf.ctrl else "Extrude Off")
예제 #58
0
def draw_callback_px(self, context):

    if context.mode == "EDIT_MESH":
        en0 = context.scene.dt_custom_props.en0

        font_id = 0
        font_size = context.scene.dt_custom_props.fs
    
        ob_act = context.active_object
        bme = bmesh.from_edit_mesh(ob_act.data)
        mtrx = ob_act.matrix_world
    
        list_0 = [v.index for v in bme.verts if v.select]
        if len(list_0) != 0:
            p = bme.verts[list_0[0]].co.copy()
            p_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, p)
        
            q = mtrx * bme.verts[list_0[0]].co.copy()
            q_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, q)
        
            # -- -- -- -- distance to adjacent vertices
            if context.scene.dt_custom_props.b0 == True:
                list_ = [[v.index for v in e.verts] for e in bme.verts[list_0[0]].link_edges]
                for ek in list_:
                    vi = [i for i in ek if i != list_0[0]][0]
                    p1 = bme.verts[vi].co.copy()
                    loc_0_3d = mtrx * ((p + p1) * 0.5)
                    loc_0_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, loc_0_3d)
                    bgl.glColor4f(1.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                    blf.position(font_id, loc_0_2d[0] + 4, loc_0_2d[1] + 4, 0)
                    blf.size(font_id, font_size, context.user_preferences.system.dpi)
                    blf.draw(font_id, str(round((p - p1).length, 4)))
        
            bgl.glLineStipple(4, 0xAAAA)
            bgl.glEnable(bgl.GL_LINE_STIPPLE)
        
            # -- -- -- -- distance to axis local global
            if context.scene.dt_custom_props.b1 == True:
        
                # -- -- -- -- local
                if en0 == 'opt0':
        
                    # -- -- -- -- x axis
                    px = mtrx * Vector((0.0, p[1], p[2]))
                    px_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, px)
        
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(px_loc_2d[0], px_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
        
                    if context.scene.dt_custom_props.b2 == False:
                        lx = (q_loc_2d + px_loc_2d) * 0.5
                        bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, lx[0] + 4, lx[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round(p[0], 4)))
        
                    # -- -- -- -- y axis
                    py = mtrx * Vector((p[0], 0.0, p[2]))
                    py_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, py)
                    
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(py_loc_2d[0], py_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
                
                    if context.scene.dt_custom_props.b2 == False:
                        ly = (q_loc_2d + py_loc_2d) * 0.5
                        bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, ly[0] + 4, ly[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round(p[1], 4)))
        
                    # -- -- -- -- z axis
                    pz = mtrx * Vector((p[0], p[1], 0.0))
                    pz_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, pz)
                
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(pz_loc_2d[0], pz_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
            
                    if context.scene.dt_custom_props.b2 == False:
                        lz = (q_loc_2d + pz_loc_2d) * 0.5
                        bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, lz[0] + 4, lz[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round(p[2], 4)))
        
                    # -- -- -- --
                    if context.scene.dt_custom_props.b2 == True and context.scene.dt_custom_props.b1 == True:
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                
                        bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4 + font_size + 4, 0)
                        blf.draw(font_id, 'x ' + str(round(p[0], 4)))
                
                        bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4, 0)
                        blf.draw(font_id, 'y ' + str(round(p[1], 4)))
        
                        bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4, 0)
                        blf.draw(font_id, 'z ' + str(round(p[2], 4)))
        
                # -- -- -- -- global
                elif en0 == 'opt1':
        
                    # -- -- -- -- x axis
                    ip_x = intersect_line_plane(q, q + (Vector((1.0, 0.0, 0.0)) * 0.1), Vector((0.0, 1.0, 0.0)), Vector((1.0, 0.0, 0.0)))
                    ip_x_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, ip_x)
        
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(ip_x_loc_2d[0], ip_x_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
        
                    if context.scene.dt_custom_props.b2 == False:
                        loc_1_2d = (q_loc_2d + ip_x_loc_2d) * 0.5
                        bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, loc_1_2d[0] + 4, loc_1_2d[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round((q - ip_x).length, 4)))
        
                    # -- -- -- -- y axis
                    ip_y = intersect_line_plane(q, q + (Vector((0.0, 1.0, 0.0)) * 0.1), Vector((1.0, 0.0, 0.0)), Vector((0.0, 1.0, 0.0)))
                    ip_y_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, ip_y)
        
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(ip_y_loc_2d[0], ip_y_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
        
                    if context.scene.dt_custom_props.b2 == False:
                        loc_2_2d = (q_loc_2d + ip_y_loc_2d) * 0.5
                        bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, loc_2_2d[0] + 4, loc_2_2d[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round((q - ip_y).length, 4)))
        
                    # -- -- -- -- z axis
                    ip_z = intersect_line_plane(q, q + (Vector((0.0, 0.0, 1.0)) * 0.1), Vector((1.0, 0.0, 0.0)), Vector((0.0, 0.0, 1.0)))
                    ip_z_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, ip_z)
        
                    bgl.glEnable(bgl.GL_BLEND)
                    bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                    bgl.glBegin(bgl.GL_LINES)
                    bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1])
                    bgl.glVertex2f(ip_z_loc_2d[0], ip_z_loc_2d[1])
                    bgl.glEnd()
                    bgl.glDisable(bgl.GL_BLEND)
        
                    if context.scene.dt_custom_props.b2 == False:
                        loc_3_2d = (q_loc_2d + ip_z_loc_2d) * 0.5
                        bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, loc_3_2d[0] + 4, loc_3_2d[1] + 4, 0)
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                        blf.draw(font_id, str(round((q - ip_z).length, 4)))
        
                    # -- -- -- --
                    if context.scene.dt_custom_props.b2 == True and context.scene.dt_custom_props.b1 == True:
                        blf.size(font_id, font_size, context.user_preferences.system.dpi)
                
                        bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4 + font_size + 4, 0)
                        blf.draw(font_id, 'x ' + str(round((q - ip_x).length, 4)))
                
                        bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4, 0)
                        blf.draw(font_id, 'y ' + str(round((q - ip_y).length, 4)))
                
                        bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a)
                        blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4, 0)
                        blf.draw(font_id, 'z ' + str(round((q - ip_z).length, 4)))
        
            # -- -- -- -- mouse location
            if context.scene.dt_custom_props.b4 == True:
        
                rgn = context.region      # region
                rgn_3d = context.space_data.region_3d      # region 3d
        
                bgl.glEnable(bgl.GL_BLEND)
                bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a)
                bgl.glBegin(bgl.GL_LINES)
                bgl.glVertex2f(0, dt_buf.y )
                bgl.glVertex2f(dt_buf.x - 15, dt_buf.y)
                bgl.glEnd()
                bgl.glDisable(bgl.GL_BLEND)
        
                bgl.glEnable(bgl.GL_BLEND)
                bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a)
                bgl.glBegin(bgl.GL_LINES)
                bgl.glVertex2f(rgn.width, dt_buf.y )
                bgl.glVertex2f(dt_buf.x + 15, dt_buf.y)
                bgl.glEnd()
                bgl.glDisable(bgl.GL_BLEND)
        
                bgl.glEnable(bgl.GL_BLEND)
                bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a)
                bgl.glBegin(bgl.GL_LINES)
                bgl.glVertex2f(dt_buf.x, 0 )
                bgl.glVertex2f(dt_buf.x, dt_buf.y - 15)
                bgl.glEnd()
                bgl.glDisable(bgl.GL_BLEND)
        
                bgl.glEnable(bgl.GL_BLEND)
                bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a)
                bgl.glBegin(bgl.GL_LINES)
                bgl.glVertex2f(dt_buf.x, rgn.height )
                bgl.glVertex2f(dt_buf.x, dt_buf.y + 15)
                bgl.glEnd()
                bgl.glDisable(bgl.GL_BLEND)
                bgl.glDisable(bgl.GL_LINE_STIPPLE)
        
                t = str(dt_buf.x) + ', ' + str(dt_buf.y)
                lo = region_2d_to_location_3d(context.region, context.space_data.region_3d, Vector((dt_buf.x, dt_buf.y)), Vector((0.0, 0.0, 0.0)))
                t1 = '( ' + str(round(lo[0], 4)) + ', ' + str(round(lo[1], 4)) + ', ' + str(round(lo[2], 4)) + ' )'
        
                bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a)
                blf.position(font_id, dt_buf.x + 15, dt_buf.y + 15, 0)
                blf.size(font_id, 14, context.user_preferences.system.dpi)
                blf.draw(font_id, t1 if context.scene.dt_custom_props.b5 == True else t)
        
            bgl.glDisable(bgl.GL_LINE_STIPPLE)
        
            # -- -- -- -- angles
            if context.scene.dt_custom_props.b3 == True:
                list_ek = [[v.index for v in e.verts] for e in bme.verts[list_0[0]].link_edges]
                n1 = len(list_ek)
                
                for j in range(n1):
                    vec1 = p - bme.verts[[ i for i in list_ek[j] if i != list_0[0] ][0]].co.copy()
                    vec2 = p - bme.verts[[ i for i in list_ek[(j + 1) % n1] if i != list_0[0]][0]].co.copy()
                    ang = vec1.angle(vec2)
        
                    a_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, mtrx * (((p - (vec1.normalized() * 0.1)) + (p - (vec2.normalized() * 0.1))) * 0.5))
        
                    bgl.glColor4f(0.0, 0.757, 1.0, context.scene.dt_custom_props.a)
                    blf.position(font_id, a_loc_2d[0], a_loc_2d[1], 0)
                    blf.size(font_id, font_size, context.user_preferences.system.dpi)
                    blf.draw(font_id, str(round(ang, 4) if context.scene.dt_custom_props.b6 == True else round(degrees(ang), 2)))
        
            # -- -- -- -- tool on/off
                    bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
                    blf.position(font_id, 150, 10, 0)
                    blf.size(font_id, 20, context.user_preferences.system.dpi)
                    blf.draw(font_id, 'Ruler On')
    def modal(self, context, event):
        
        scn = context.scene 
                  
        if event.type == 'MOUSEMOVE' and self.LMB_Hold:
        
            #bpy.ops.object.mode_set(mode='OBJECT')
            #bpy.ops.object.mode_set(mode='EDIT')
            
                      
            # create variables           
            coord = event.mouse_region_x, event.mouse_region_y
            region = context.region
            rv3d = context.space_data.region_3d
            vec = region_2d_to_vector_3d(region, rv3d, coord)
            loc = (region_2d_to_location_3d(region, rv3d, coord, vec))
                  
            # get face center
            bpy.ops.object.mode_set(mode='OBJECT')
            me = bpy.context.object.data # Get the active mesh
            bm = bmesh.new()   # create an empty BMesh
            bm.from_mesh(me)   # fill it in from a Mesh
            face = bpy.context.object.data.polygons.active
            face_center = bm.faces[face].calc_center_median()
            bpy.ops.object.mode_set(mode='EDIT')
            face_center_2d = location_3d_to_region_2d(region, rv3d, face_center)
            face_normal = bpy.context.active_object.data.polygons[face].normal
            angle = 0
            
            if mathutils.Vector((coord)).x >= face_center_2d.x  and mathutils.Vector((coord)).y >= face_center_2d.y:
                
                angle = loc.angle(face_center)#/math.pi*180
                
            elif  mathutils.Vector((coord)).x <= face_center_2d.x  and mathutils.Vector((coord)).y <= face_center_2d.x:
                
                angle = -(loc.angle(face_center))#/math.pi*180
                       
                             
            x = rv3d.perspective_matrix[3].x
            y = rv3d.perspective_matrix[3].y
            z = rv3d.perspective_matrix[3].z
            axis = mathutils.Vector((x,y,z))                                           
            
            
            nx = face_normal.x
            ny=  face_normal.y
            nz= face_normal.z
            
            spinAngle = scn.spin *math.pi/180
             
            minDisVec = mathutils.Vector((scn.min_distance,scn.min_distance,scn.min_distance))    
            
#            if scn['stepsCounter']==0:
#                
#               
#                if scn['min_distance'] >= 1:  
#                       
#                    increment = round((loc - face_center).length,0) 
#        
#                    if increment == scn['min_distance'] :
#                                           
#                       if scn.auto_rotate:
#                           bpy.ops.transform.rotate(value=(angle), axis=(axis))
#                       extrusion(coord,region,rv3d,vec,loc,face,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
#                       bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz))
#                       
#                       
#                else:
#                    increment = round((loc - face_center).length,2)
#        
#                    if increment >= scn['min_distance']:
#                                           
#                       if scn.auto_rotate:
#                           bpy.ops.transform.rotate(value=(angle), axis=(axis))
#                       extrusion(coord,region,rv3d,vec,loc,face,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
#                       bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz))
#              
#        
#            else:
#                
#                
#                if scn['min_distance'] >= 1 and scn.steps > scn.stepsCounter:  
#                       
#                    increment = round((loc - face_center).length,0) 
#        
#                    if increment == scn['min_distance'] :
#                                           
#                       if scn.auto_rotate:
#                           bpy.ops.transform.rotate(value=(angle), axis=(axis))
#                       extrusion(coord,region,rv3d,vec,loc,face,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
#                       bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz))
#                       scn['steps']+=1
#                       print(scn.steps, scn.stepsCounter)
#                       
#                       
#                       
#                else:
#                    increment = round((loc - face_center).length,2)
#        
#                    if increment >= scn['min_distance']:
#                                           
#                       if scn.auto_rotate:
#                           bpy.ops.transform.rotate(value=(angle), axis=(axis))
#                       extrusion(coord,region,rv3d,vec,loc,face,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
#                       bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz))                                                                                   
#                       scn.steps+=1
            increment = round((loc - face_center).length,5)
             
              
            if scn.stepsCounter >0:
                
                if increment >= scn['min_distance'] and scn.steps < scn.stepsCounter:                                                                     
                    scn.steps += 1
                    if scn.auto_rotate:
                        bpy.ops.transform.rotate(value=(angle), axis=(axis))
                    extrusion(loc , face_center,scn['taper_value'], scn.cons_x, scn.cons_y, scn.cons_z,scn.orientation) 
                    bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz)) 
                                                            
            else:
                if increment >= scn['min_distance']:
                
                    if scn.auto_rotate:
                       bpy.ops.transform.rotate(value=(angle), axis=(axis))
                    extrusion(loc,face_center,scn['taper_value'],scn.cons_x ,scn.cons_y,scn.cons_z,scn.orientation)
                    bpy.ops.transform.rotate(value=(spinAngle), axis=(nx,ny,nz)) 
                    
                                   
        elif event.type == 'LEFTMOUSE':
            if event.value == 'PRESS':
                self.LMB_Hold = True
            elif event.value == 'RELEASE':
                self.LMB_Hold = False
     
        
        
        elif event.type in {'RIGHTMOUSE', 'NUMPAD_ENTER'} or (scn.steps >= scn.stepsCounter and scn.stepsCounter !=0):
            
            scn.steps = 0 
            if bpy.context.scene.collapse == True :
        
                bpy.ops.mesh.merge(type='COLLAPSE', uvs=True)
                           
            context.area.header_text_set()
                
            return {'FINISHED'}
        
        elif event.type == 'ESC':  
            
            bpy.ops.ed.undo()    
            context.area.header_text_set()
            
            return {'CANCELLED'}
        
        context.area.header_text_set('Hold LMB and move to extrude, RMB to confirm, ESC to abort ')
        return {'RUNNING_MODAL'}