Example #1
0
def get_grid_intersection(mousepos):
    region = bpy.context.region
    region_data = bpy.context.region_data

    origin_3d = region_2d_to_origin_3d(region, region_data, mousepos)
    vector_3d = region_2d_to_vector_3d(region, region_data, mousepos)

    xdot = round(Vector((1, 0, 0)).dot(vector_3d), 2)
    ydot = round(Vector((0, 1, 0)).dot(vector_3d), 2)
    zdot = round(Vector((0, 0, 1)).dot(vector_3d), 2)

    # prefer alignment on z
    if abs(zdot * 2) >= max([abs(xdot), abs(ydot)]):
        angle = 0 if zdot <= 0 else 180
        return intersect_line_plane(origin_3d, origin_3d + vector_3d,
                                    Vector((0, 0, 0)), Vector(
                                        (0, 0, 1))), Matrix.Rotation(
                                            radians(angle), 4, "X")

    elif abs(ydot) > abs(xdot):
        angle = 90 if ydot >= 0 else -90
        return intersect_line_plane(origin_3d, origin_3d + vector_3d,
                                    Vector((0, 0, 0)), Vector(
                                        (0, 1, 0))), Matrix.Rotation(
                                            radians(angle), 4, "X")

    else:
        angle = 90 if xdot <= 0 else -90
        return intersect_line_plane(origin_3d, origin_3d + vector_3d,
                                    Vector((0, 0, 0)), Vector(
                                        (1, 0, 0))), Matrix.Rotation(
                                            radians(angle), 4, "Y")
Example #2
0
def find_distant_bmedge_crossing_plane(pt, no, edges, epsilon, e_ind_from, co_from):
    '''
    returns the farthest edge that *crosses* plane and corresponding intersection point
    '''
    
    if(len(edges)==3):
        # shortcut (no need to find farthest... just find first)
        for edge in edges:
            if edge.index == e_ind_from: continue
            v0,v1 = edge.verts
            co0,co1 = v0.co,v1.co
            s0,s1 = no.dot(co0 - pt), no.dot(co1 - pt)
            no_cross = not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon))
            if no_cross: continue
            i = intersect_line_plane(co0, co1, pt, no)
            return (edge,i)
    
    d_max,edge_max,i_max = -1.0,None,None
    for edge in edges:
        if edge.index == e_ind_from: continue
        
        v0,v1 = edge.verts
        co0,co1 = v0.co, v1.co
        s0,s1 = no.dot(co0 - pt), no.dot(co1 - pt)
        if s0 > epsilon and s1 > epsilon: continue
        if s0 < -epsilon and s1 < -epsilon: continue
        #if not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon)):      # edge cross plane?
        #    continue
        
        i = intersect_line_plane(co0, co1, pt, no)
        d = (co_from - i).length
        if d > d_max: d_max,edge_max,i_max = d,edge,i
    return (edge_max,i_max)
Example #3
0
def find_distant_bmedge_crossing_plane(pt, no, edges, epsilon, e_ind_from, co_from):
    '''
    returns the farthest edge that *crosses* plane and corresponding intersection point
    '''
    
    if(len(edges)==3):
        # shortcut (no need to find farthest... just find first)
        for edge in edges:
            if edge.index == e_ind_from: continue
            v0,v1 = edge.verts
            co0,co1 = v0.co,v1.co
            s0,s1 = no.dot(co0 - pt), no.dot(co1 - pt)
            no_cross = not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon))
            if no_cross: continue
            i = intersect_line_plane(co0, co1, pt, no)
            return (edge,i)
    
    d_max,edge_max,i_max = -1.0,None,None
    for edge in edges:
        if edge.index == e_ind_from: continue
        
        v0,v1 = edge.verts
        co0,co1 = v0.co, v1.co
        s0,s1 = no.dot(co0 - pt), no.dot(co1 - pt)
        if s0 > epsilon and s1 > epsilon: continue
        if s0 < -epsilon and s1 < -epsilon: continue
        #if not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon)):      # edge cross plane?
        #    continue
        
        i = intersect_line_plane(co0, co1, pt, no)
        d = (co_from - i).length
        if d > d_max: d_max,edge_max,i_max = d,edge,i
    return (edge_max,i_max)
Example #4
0
    def deform_cylinder(self, e: Edge):
        # Cylindracisations
        # for each edge, apply it's cylindrical transform [r, magnitude]
        e_id = e.p_id
        r = self.params[e_id, 0]
        mag = self.params[e_id, 1]
        if r == 0 or mag == 0:
            return
        mid = Vector(e.coord)
        mask = np.array(mid, dtype=bool)
        normal = Vector(np.invert(mask).astype(dtype=float))
        plane = np.where(mask)[0]

        def _inrange(vertex, ctrl):
            vc = self.vertices[vertex] - ctrl
            if abs(vc[0]) <= r and abs(vc[1]) <= r and abs(vc[2]) <= r:
                return True
            return False

        vertices = []
        for c in [e.ctp_n, e.ctp_p]:
            # filter quadrant normal to edge
            for quadrant in [[c.a_yz, c.a_xz, c.a_xy][i] for i in plane]:
                vertices.extend(quadrant.reshape((1, -1)))
        vertices = np.unique(vertices)

        c_p = (mid + normal)
        c_n = (mid - normal)
        for v in vertices:
            control = geometry.intersect_line_plane(c_p, c_n, self.vertices[v],
                                                    normal)
            center = geometry.intersect_line_plane(normal, normal * -2,
                                                   self.vertices[v], normal)
            center = center + (control - center) * (1 - r)
            if _inrange(v, control):
                self.vertices[v] = self.round_corner(center, self.vertices[v],
                                                     r, mag)

        vertices = []
        for c in [e.ctp_n, e.ctp_p]:
            # filter quadrant of planar curve
            for quadrant in [[c.a_yz, c.a_xz, c.a_xy][i]
                             for i in np.where(normal)[0]]:
                vertices.extend(quadrant[1:, 1:].reshape((1, -1)))
        vertices = np.unique(vertices)

        for v in vertices:
            control = geometry.intersect_line_plane(c_p, c_n, self.vertices[v],
                                                    normal)
            center = geometry.intersect_line_plane(normal, normal * -2,
                                                   self.vertices[v], normal)
            center = center + (control - center) * (1 - r)
            if (control - self.vertices[v]).length < (control - center).length:
                # continue
                self.vertices[v] = self.vertices[v] + (
                    center - self.vertices[v]) * .3 * (center -
                                                       self.vertices[v]).length

        for e in self.m_edges.reshape((1, -1))[0]:
            self.clean_dual_edge(e)
Example #5
0
    def mouse_to_plane(self,
                       context,
                       event,
                       origin=Vector((0, 0, 0)),
                       normal=Vector((0, 0, 1))):
        """
            convert mouse pos to 3d point over plane defined by origin and normal
            return None if the point is behind camera view
        """
        is_perspective, orig, vec = self.region_2d_to_orig_and_vect(
            context, event)
        pt = intersect_line_plane(orig, orig + vec, origin, normal, False)

        # fix issue with parallel plane
        if pt is None:
            pt = intersect_line_plane(orig, orig + vec, origin, vec, False)

        if pt is None:
            return None

        if is_perspective:
            # Check if point is behind point of view (mouse over horizon)
            y = Vector((0, 0, 1))
            x = vec.cross(y)
            x = y.cross(vec)
            itM = Matrix([[x.x, y.x, vec.x, orig.x], [x.y, y.y, vec.y, orig.y],
                          [x.z, y.z, vec.z, orig.z], [0, 0, 0, 1]]).inverted()
            res = itM * pt

            if res.z < 0:
                return None

        return pt
def f_(me, list_0, arg, context, ob_act):

    cb = context.scene.pt_custom_props.b
    cen1 = context.scene.pt_custom_props.en1

    dict_0 = {}
    dict_1 = {}
    
    if arg == 'x':
        pn = Vector((0, 1, 0))
        pp = Vector((1, 0, 0))
    elif arg == 'y':
        pn = Vector((1, 0, 0))
        pp = Vector((0, 1, 0))
    elif arg == 'z':
        pn = Vector((0, 0, 1))
        pp = Vector((0, 1, 0))

    if cb == False:
        for vi in list_0:
            v = (me.vertices[vi].co).copy()
            p = v + (pn * 0.1)
            if cen1 == 'opt0':
                p3 = intersect_line_plane(v, p, pp, pn)
            elif cen1 == 'opt1':
                p1 = ob_act.matrix_world * v
                gp = p1 + (pn * 0.1)
                p2 = intersect_line_plane(p1, gp, pp, pn)
                p3 = (ob_act.matrix_world).inverted() * p2
            
            dict_0[vi] = p3

        for j in dict_0:
            me.vertices[j].co = dict_0[j]

    elif cb == True:
        for vi in list_0:
            v = (me.vertices[vi].co).copy()
            p = v + (pn * 0.1)
            if cen1 == 'opt0':
                p3 = intersect_line_plane(v, p, pp, pn)
            elif cen1 == 'opt1':
                p1 = ob_act.matrix_world * v
                gp = p1 + (pn * 0.1)
                p2 = intersect_line_plane(p1, gp, pp, pn)
                p3 = (ob_act.matrix_world).inverted() * p2

            me.vertices.add(1)
            me.vertices[-1].co = p3
            me.vertices[-1].select = False
            dict_1[vi] = me.vertices[-1].index

        edge_copy_(me, dict_1)
        faces_copy_(me, dict_1)
def intersect_plane_plane_plane(p1c, p1n, p2c, p2n, p3c, p3n):
    point = None
    line = geometry.intersect_plane_plane(p1c, p1n, p2c, p2n)
    if line is not None and line[0] is not None:
        point = geometry.intersect_line_plane(line[0], line[0] + line[1], p3c,
                                              p3n)
    return point
Example #8
0
def extend_vertex():

    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    verts = bm.verts
    faces = bm.faces

    plane = [f for f in faces if f.select][0]
    plane_vert_indices = [v for v in plane.verts[:]]
    all_selected_vert_indices = [v for v in verts if v.select]

    M = set(plane_vert_indices)
    N = set(all_selected_vert_indices)
    O = N.difference(M)
    O = list(O)
    (v1_ref, v1_idx, v1), (v2_ref, v2_idx, v2) = [(i, i.index, i.co)
                                                  for i in O]

    plane_co = plane.calc_center_median()
    plane_no = plane.normal

    new_co = intersect_line_plane(v1, v2, plane_co, plane_no, False)
    new_vertex = verts.new(new_co)

    A_len = (v1 - new_co).length
    B_len = (v2 - new_co).length

    vertex_reference = v1_ref if (A_len < B_len) else v2_ref
    bm.edges.new([vertex_reference, new_vertex])

    bmesh.update_edit_mesh(me, True)
Example #9
0
 def project_point_onto_camera(self, point):
     return self.ifc_cutter.camera_obj.matrix_world.inverted(
     ) @ geometry.intersect_line_plane(
         point.xyz,
         point.xyz - Vector(self.ifc_cutter.section_box['projection']),
         self.ifc_cutter.camera_obj.location,
         Vector(self.ifc_cutter.section_box['projection']))
Example #10
0
                    def get_ideal_position(empty_name):
                        # Set Maximum Distance
                        max_distance = 1000
                        # Get Empty Positions
                        main_c = camera_position_array[empty_name + '.R']
                        sub_c = camera_position_array[empty_name + '.L']
                        # Vector to Target Point From Camera
                        target_vector = (sub_c - camera_position
                                         ).normalized() * max_distance
                        # Get Line
                        A = get_mirrored_vector(camera_position,
                                                empty_position, normal)
                        B = get_mirrored_vector(
                            camera_position +
                            (main_c - camera_position).normalized() *
                            max_distance, empty_position, normal)
                        # Calculate Intersection
                        intersection = intersect_line_line(
                            camera_position, target_vector, A, B)
                        mirrored_intersection = get_mirrored_vector(
                            Vector(intersection[1]), empty_position, normal)
                        # Here, You have to get position on the screen
                        insect = intersect_line_plane(
                            camera_position, Vector(intersection[1]),
                            Vector((0, -8 + distance, 0)), Vector((0, 1, 0)))
                        # If it's not intersecting, just return ridiculous value
                        if (insect is None):
                            insect = Vector((100, 100, 100))

                        return mirrored_intersection, (insect - sub_c).length
    def get_3d_for_2d(self, pos_2d, context):

        result = None

        scene = context.scene

        origin, direction = get_origin_and_direction(pos_2d, context)

        # Try to hit an object in the scene
        if self._hit is None:
            hit, self._hit, self._normal, face, hit_obj, *_ = scene.ray_cast(
                context.view_layer, origin, direction)
            if hit:
                self._snap_to_target = True
                result = self._hit.copy()

        # Object was hit before
        else:
            result = intersect_line_plane(origin, origin + direction,
                                          self._hit, self._normal)

        if result is not None:
            result += self._normal.normalized() * scene.snap_offset

        return result
Example #12
0
 def mouse_to_plane(self, context, event, origin=Vector((0, 0, 0)), normal=Vector((0, 0, 1))):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     co2d = (event.mouse_region_x, event.mouse_region_y)
     view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
     ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
     pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
        origin, normal, False)
     # fix issue with parallel plane
     if pt is None:
         pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
             origin, view_vector_mouse, False)
     return pt
Example #13
0
    def get_mouse_3d_on_plane(self, event, context):

        origin, direction = self.get_origin_and_direction(event, context)

        # get the intersection point on infinite plane
        return intersect_line_plane(origin, origin + direction, self.hit,
                                    self.normal)
Example #14
0
    def execute(self, context):
        edit_mode_out()
        ob_act = context.active_object
        me = ob_act.data
        list_0 = [v.index for v in me.vertices if v.select]

        if len(va_buf.list_f) == 0:
            self.report({'INFO'}, 'No face stored in memory')
            edit_mode_in()
            return {'CANCELLED'}
        elif len(va_buf.list_f) != 0:
            if len(list_0) == 0:
                self.report({'INFO'}, 'No vertices selected')
                edit_mode_in()
                return {'CANCELLED'}
            elif len(list_0) != 0:
                f = me.faces[va_buf.list_f[0]]
                for i in list_0:
                    v = (me.vertices[i].co).copy()
                    p = v + ((f.normal).copy() * 0.1)
                    pp = (me.vertices[f.vertices[0]].co).copy()
                    pn = (f.normal).copy()
                    me.vertices[i].co = intersect_line_plane(v, p, pp, pn)
        edit_mode_in()
        return {'FINISHED'}
Example #15
0
 def clean_dual_edge(self, e):
     """
         Get a dual list from an edge
         find the 2 quadrants sharing it
     """
     if self.sub > 2:
         for dual in [e.dual_0, e.dual_1]:
             quads = []
             for c in [e.ctp_n, e.ctp_p]:
                 for quadrant in [c.a_xy, c.a_xz, c.a_yz]:
                     if dual[0] == quadrant[-1, 1]:
                         quads.append(quadrant)
                         break
                     if dual[0] == quadrant[1, -1]:
                         quads.append(quadrant.T)
                         break
             for i in range(self.sub - 1):
                 a = Vector(e.coord)  # self.vertices[quads[0][-1][i]]
                 b = self.vertices[quads[0][-2][i]]
                 c = self.vertices[quads[1][-2][i]]
                 mask = np.array(a, dtype=bool)
                 n = np.invert(mask).astype(dtype=float)
                 p = geometry.intersect_line_plane(
                     c, b, a, Vector((n[0], n[1], n[2])))
                 self.vertices[quads[0][-1][i]] = Vector(
                     (p[0] * mask[0], p[1] * mask[1], p[2] * mask[2]))
Example #16
0
File: ops.py Project: gjinhui/sly
def mutual_cut(sli1, sli2, cut_spec={}):
    """Given two slices, add the appropriate cuts to them if they intersect"""
    if sli1.rot == sli2.rot:
        return      # same orientation, so nothing to intersect

    cut_dir = sli1.cut_direction(sli2)
    verts_3d = [sli1.to_3d(pt) for pt in sli1.poly.exterior.coords]

    points = []
    for (pta, ptb) in pairwise(verts_3d):
        intersect = intersect_line_plane(pta, ptb, sli2.co, sli2.normal())
        # Is the intersecting point between the ends of the segment?
        if intersect and (pta - intersect).dot(ptb - intersect) <= 0:
            points.append(intersect)

    if len(points) > 2:
        print("More than one intersection between slices. Not yet supported!")

    # There should always be an even number of crossings
    assert len(points) % 2 == 0

    z_factor = cut_spec.get('z_factor', 0.5)

    if len(points) >= 2:
        midpt = points[0].lerp(points[1], z_factor)
        sli1.add_cut(midpt, cut_dir, sli2.thickness)
        sli2.add_cut(midpt, -cut_dir, sli1.thickness)
Example #17
0
    def handle_raycast(self, event):
        if not self.mousepaint: return

        coord = event.mouse_region_x, event.mouse_region_y
        if coord == self.lastcoord: return
        self.lastcoord = coord
        view_vector = region_2d_to_vector_3d(bpy.context.region,
                                             bpy.context.region_data, coord)
        ray_origin = region_2d_to_origin_3d(bpy.context.region,
                                            bpy.context.region_data, coord)

        pos, rot, scl = self.root.matrix_world.decompose()
        z = self.cursor.pos.z  # z persists
        offset = Vector((0, 0, z))
        offset = rot * offset
        pos = pos + offset
        nml = rot * UP
        plane_pos = intersect_line_plane(ray_origin, ray_origin + view_vector,
                                         pos, nml)
        if not plane_pos: return  # workaround for quad view?
        mat = self.root.matrix_world.inverted()
        plane_pos = mat * plane_pos
        round_vector(plane_pos)
        if plane_pos != self.lastpos:
            d = plane_pos - self.lastpos
            self.on_move(d)
Example #18
0
 def get_pos3d(self, context, normal=Vector((0, 0, 1))):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
         pt is in world space
     """
     region = context.region
     rv3d = context.region_data
     view_vector_mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, self.mouse_pos)
     ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(region, rv3d, self.mouse_pos)
     pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
         self.origin, normal, False)
     # fix issue with parallel plane
     if pt is None:
         pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
             self.origin, view_vector_mouse, False)
     return pt
Example #19
0
def extend_vertex():

    obj = bpy.context.edit_object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    verts = bm.verts
    faces = bm.faces

    plane = [f for f in faces if f.select][0]
    plane_vert_indices = [v for v in plane.verts[:]]
    all_selected_vert_indices = [v for v in verts if v.select]

    M = set(plane_vert_indices)
    N = set(all_selected_vert_indices)
    O = N.difference(M)
    O = list(O)
    (v1_ref, v1_idx, v1), (v2_ref, v2_idx, v2) = [(i, i.index, i.co) for i in O]

    plane_co = plane.calc_center_median()
    plane_no = plane.normal

    new_co = intersect_line_plane(v1, v2, plane_co, plane_no, False)
    new_vertex = verts.new(new_co)

    A_len = (v1 - new_co).length
    B_len = (v2 - new_co).length

    vertex_reference = v1_ref if (A_len < B_len) else v2_ref
    bm.edges.new([vertex_reference, new_vertex])

    bmesh.update_edit_mesh(me, True)
    def doPlane(self, context):
        mode = context.object.mode

        #for blender to update selected verts, faces
        bpy.ops.object.mode_set(mode='OBJECT')
        selectedFaces = [
            f for f in bpy.context.object.data.polygons if f.select
        ]
        selectedVerts = [
            v for v in bpy.context.object.data.vertices if v.select
        ]

        if len(selectedFaces) == 0:
            self.report({'ERROR'}, 'select one meshs at least.')
        else:
            norms = Vector()
            centers = Vector()
            for f in selectedFaces:
                norms += f.normal
                centers += f.center

            count = len(selectedFaces)

            norms_aver = norms / count
            center_aver = centers / count

            try:
                for v in selectedVerts:
                    res = geometry.intersect_line_plane(
                        v.co, v.co + norms_aver, center_aver, norms_aver)
                    v.co = res
            except:
                self.report({'ERROR'},
                            'sorry for unknown error, please retry.')
            bpy.ops.object.mode_set(mode=mode)
Example #21
0
 def execute(self, context):
     edit_mode_out()
     ob_act = context.active_object
     me = ob_act.data
     list_0 = [v.index for v in me.vertices if v.select]
     
     if len(va_buf.list_f) == 0:
         self.report({'INFO'}, 'No face stored in memory')
         edit_mode_in()
         return {'CANCELLED'}
     elif len(va_buf.list_f) != 0:
         if len(list_0) == 0:
             self.report({'INFO'}, 'No vertices selected')
             edit_mode_in()
             return {'CANCELLED'}
         elif len(list_0) != 0:
             f = me.faces[va_buf.list_f[0]]
             for i in list_0:
                 v = (me.vertices[i].co).copy()
                 p = v + ((f.normal).copy() * 0.1)
                 pp = (me.vertices[f.vertices[0]].co).copy()
                 pn = (f.normal).copy()
                 me.vertices[i].co = intersect_line_plane(v, p, pp, pn)
     edit_mode_in()
     return {'FINISHED'}
Example #22
0
def raycast_grid(scene, context, up_vector, right_vector, plane_normal,
                 ray_origin, ray_vector):
    """
    Raycast to a plane on the scene cursor, and return the grid snapped position
    :param scene:
    :param context:
    :param up_vector:
    :param right_vector:
    :param plane_normal:
    :param ray_origin:
    :param ray_vector:
    :return: grid_position, x_vector, y_vector, plane_pos
    """

    plane_pos = intersect_line_plane(ray_origin, ray_origin + ray_vector,
                                     scene.cursor_location, plane_normal)
    # Didn't hit the plane exit
    if plane_pos is None:
        return None, None, None, None

    world_pixels = scene.sprytile_data.world_pixels
    target_grid = get_grid(context, context.object.sprytile_gridid)
    grid_x = target_grid.grid[0]
    grid_y = target_grid.grid[1]

    grid_position, x_vector, y_vector = get_grid_pos(plane_pos,
                                                     scene.cursor_location,
                                                     right_vector.copy(),
                                                     up_vector.copy(),
                                                     world_pixels, grid_x,
                                                     grid_y)
    return grid_position, x_vector, y_vector, plane_pos
Example #23
0
 def mouse_to_plane(self, context, event, origin=Vector((0, 0, 0)), normal=Vector((0, 0, 1))):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     co2d = (event.mouse_region_x, event.mouse_region_y)
     view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
     ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
     pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
        origin, normal, False)
     # fix issue with parallel plane
     if pt is None:
         pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
             origin, view_vector_mouse, False)
     return pt
def extend_vertex(context):
    """Computes Edge Extension to Face.

    Args:
        context: Blender bpy.context instance.

    Returns:
        Nothing.
    """

    obj = bpy.context.edit_object
    pg = context.scene.pdt_pg

    if all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"]):
        object_data = obj.data
        bm = bmesh.from_edit_mesh(object_data)
        verts = bm.verts
        faces = bm.faces

        planes = [f for f in faces if f.select]
        if not len(planes) == 1:
            failure_message(context)
            return

        plane = planes[0]
        plane_vert_indices = plane.verts[:]
        all_selected_vert_indices = [v for v in verts if v.select]

        plane_verts = set(plane_vert_indices)
        all_verts = set(all_selected_vert_indices)
        diff_verts = all_verts.difference(plane_verts)
        diff_verts = list(diff_verts)

        if not len(diff_verts) == 2:
            failure_message(context)
            return

        (v1_ref, v1), (v2_ref, v2) = [(i, i.co) for i in diff_verts]

        plane_co = plane.calc_center_median()
        plane_no = plane.normal

        new_co = intersect_line_plane(v1, v2, plane_co, plane_no, False)

        if new_co:
            new_vertex = verts.new(new_co)
            a_len = (v1 - new_co).length
            b_len = (v2 - new_co).length

            vertex_reference = v1_ref if (a_len < b_len) else v2_ref
            bm.edges.new([vertex_reference, new_vertex])
            bmesh.update_edit_mesh(object_data, loop_triangles=True)

        else:
            failure_message_on_plane(context)
    else:
        pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
        context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
        return
Example #25
0
 def project_point_onto_camera(self, point):
     return self.camera.matrix_world.inverted(
     ) @ geometry.intersect_line_plane(
         point.xyz,
         point.xyz - Vector(self.camera_projection),
         self.camera.location,
         Vector(self.camera_projection),
     )
Example #26
0
    def grab_mouse_move(self, context, x, y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        crv_mx = self.crv_obj.matrix_world
        i_crv_mx = crv_mx.inverted()

        hit = False
        if self.snap_type == 'SCENE':

            if bversion() < '002.077.000':
                res, obj, omx, loc, no = context.scene.ray_cast(
                    ray_origin, ray_target)
            else:
                res, loc, no, ind, obj, mx = context.scene.ray_cast(
                    ray_origin, view_vector)
            mx = Matrix.Identity(4)
            if res:
                hit = True

            else:
                #cast the ray into a plane a
                #perpendicular to the view dir, at the last bez point of the curve
                hit = True
                view_direction = rv3d.view_rotation * Vector((0, 0, -1))
                plane_pt = self.grab_undo_loc
                loc = intersect_line_plane(ray_origin, ray_target, plane_pt,
                                           view_direction)

        elif self.snap_type == 'OBJECT':
            mx = self.snap_ob.matrix_world
            imx = mx.inverted()
            loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin,
                                                      imx * ray_target)

            if bversion() < '002.077.000':
                loc, no, face_ind = self.snap_ob.ray_cast(
                    imx * ray_origin, imx * ray_target)
                if face_ind != -1:
                    hit = True
            else:
                ok, loc, no, face_ind = self.snap_ob.ray_cast(
                    imx * ray_origin, imx * ray_target - imx * ray_origin)
                if ok:
                    hit = True

        if not hit:
            self.grab_cancel()

        else:
            local_loc = i_crv_mx * mx * loc
            self.crv_data.splines[0].bezier_points[
                self.selected].co = local_loc
            self.b_pts[self.selected] = mx * loc
Example #27
0
 def triangle_intersection(self, points: List[Point]):
     l = len(points)
     assert l == 3, 'triangle intersection on non triangle (%d)' % (l,)
     s0, s1, s2 = map(self.side, points)
     if abs(s0 + s1 + s2) == 3:
         return []    # all points on same side of plane
     p0, p1, p2 = map(Point, points)
     if s0 == 0 or s1 == 0 or s2 == 0:   # at least one point on plane
         # handle if all points in plane
         if s0 == 0 and s1 == 0 and s2 == 0:
             return [(p0, p1), (p1, p2), (p2, p0)]
         # handle if two points in plane
         if s0 == 0 and s1 == 0:
             return [(p0, p1)]
         if s1 == 0 and s2 == 0:
             return [(p1, p2)]
         if s2 == 0 and s0 == 0:
             return [(p2, p0)]
         # one point on plane, two on same side
         if s0 == 0 and s1 == s2:
             return [(p0, p0)]
         if s1 == 0 and s2 == s0:
             return [(p1, p1)]
         if s2 == 0 and s0 == s1:
             return [(p2, p2)]
     # two points on one side, one point on the other
     p01 = intersect_line_plane(p0, p1, self.o, self.n)
     p12 = intersect_line_plane(p1, p2, self.o, self.n)
     p20 = intersect_line_plane(p2, p0, self.o, self.n)
     if s0 == 0:
         return [(p0, p12)]
     if s1 == 0:
         return [(p1, p20)]
     if s2 == 0:
         return [(p2, p01)]
     if s0 != s1 and s0 != s2 and p01 and p20:
         return [(p01, p20)]
     if s1 != s0 and s1 != s2 and p01 and p12:
         return [(p01, p12)]
     if s2 != s0 and s2 != s1 and p12 and p20:
         return [(p12, p20)]
     print('%s %s %s' % (str(p0), str(p1), str(p2)))
     print('%s %s %s' % (str(s0), str(s1), str(s2)))
     print('%s %s %s' % (str(p01), str(p12), str(p20)))
     assert False
Example #28
0
 def triangle_intersection(self, points: List[Point]):
     l = len(points)
     assert l == 3, 'triangle intersection on non triangle (%d)' % (l, )
     s0, s1, s2 = map(self.side, points)
     if abs(s0 + s1 + s2) == 3:
         return []  # all points on same side of plane
     p0, p1, p2 = map(Point, points)
     if s0 == 0 or s1 == 0 or s2 == 0:  # at least one point on plane
         # handle if all points in plane
         if s0 == 0 and s1 == 0 and s2 == 0:
             return [(p0, p1), (p1, p2), (p2, p0)]
         # handle if two points in plane
         if s0 == 0 and s1 == 0:
             return [(p0, p1)]
         if s1 == 0 and s2 == 0:
             return [(p1, p2)]
         if s2 == 0 and s0 == 0:
             return [(p2, p0)]
         # one point on plane, two on same side
         if s0 == 0 and s1 == s2:
             return [(p0, p0)]
         if s1 == 0 and s2 == s0:
             return [(p1, p1)]
         if s2 == 0 and s0 == s1:
             return [(p2, p2)]
     # two points on one side, one point on the other
     p01 = intersect_line_plane(p0, p1, self.o, self.n)
     p12 = intersect_line_plane(p1, p2, self.o, self.n)
     p20 = intersect_line_plane(p2, p0, self.o, self.n)
     if s0 == 0:
         return [(p0, p12)]
     if s1 == 0:
         return [(p1, p20)]
     if s2 == 0:
         return [(p2, p01)]
     if s0 != s1 and s0 != s2 and p01 and p20:
         return [(p01, p20)]
     if s1 != s0 and s1 != s2 and p01 and p12:
         return [(p01, p12)]
     if s2 != s0 and s2 != s1 and p12 and p20:
         return [(p12, p20)]
     print('%s %s %s' % (str(p0), str(p1), str(p2)))
     print('%s %s %s' % (str(s0), str(s1), str(s2)))
     print('%s %s %s' % (str(p01), str(p12), str(p20)))
     assert False
Example #29
0
    def execute(self, context):
        C = context
        D = bpy.data
        ob = C.active_object

        #if bpy.app.debug != True:
        #    bpy.app.debug = True
        #    if C.active_object.show_extra_indices != True:
        #        C.active_object.show_extra_indices = True
        if ob.mode == 'OBJECT':
            me = C.object.data
            bm = bmesh.new()
            bm.from_mesh(me)
        else:
            obj = C.edit_object
            me = obj.data
            bm = bmesh.from_edit_mesh(me)
        bm.select_history.validate()
        if len(bm.select_history) < 3:
            self.report({'INFO'}, 'Pick three vertices first')
            return {'CANCELLED'}

        points3Index = []
        points3 = []
        _ordering = bm.select_history if self.ref_order == "first" else list(
            bm.select_history)[::-1]
        for i in _ordering:
            if len(points3) >= 3:
                break
            elif isinstance(i, bmesh.types.BMVert):
                points3.append(i.co)
                points3Index.append(i.index)
        print(points3Index)
        if len(points3) < 3:
            self.report({'INFO'},
                        'At least three vertices are needed being selected')
            return {'CANCELLED'}

        points3Normal = normal(*points3)
        for v in bm.verts:
            if v.select and v.index not in points3Index:
                _move = True
                if self.filter_distance > 0.0:
                    _move = abs(
                        distance_point_to_plane(
                            v.co, points3[0],
                            points3Normal)) < self.filter_distance
                if _move == True:
                    v.co = intersect_line_plane(v.co, v.co + points3Normal,
                                                points3[0], points3Normal)
        if ob.mode == 'OBJECT':
            bm.to_mesh(me)
            bm.free()
        else:
            bmesh.update_edit_mesh(me, True)

        return {'FINISHED'}
Example #30
0
def follow_mouse_intersection(sensor):
    ray_p0 = sensor.raySource
    ray_p1 = sensor.rayTarget
    # print ("rays ", ray_p0, ray_p1)
    intersection = geometry.intersect_line_plane(ray_p0, ray_p1, G.plane.p, G.plane.n)

    if intersection:
        # print (intersection)
        G.stimLocation = [intersection.x, intersection.y, G.stim.worldPosition[2]]
        G.holeLocation = [intersection.x, intersection.y, G.hole.worldPosition[2]]
Example #31
0
def calc_line_plane_intersection(start,
                                 end,
                                 plane_normal,
                                 plane_origin,
                                 fallback=None):
    isect_point = intersect_line_plane(start, end, plane_origin, plane_normal)
    if isect_point is not None:
        return utils.math.constrain_point_to_line_seg(start, isect_point, end)
    else:
        return fallback
def flip_edge(bm: BMesh, e: BMEdge, pivot_vert: BMVert) \
              -> BMLoop:

    print("Flipping edge {}".format(e))

    # TODO: If the angle is completely flat
    # we could do a simpler edge flipping

    # As we don't do the projection with the signpost datastructure
    # what we'll do is simulate an edge flip performing an intersection
    # and creating 4 faces
    op_vert_1: BMVert = get_opposed_vert(e.link_faces[0], e)
    op_vert_2: BMVert = get_opposed_vert(e.link_faces[1], e)

    start_v = [loop for loop in e.link_loops if loop.vert == pivot_vert][0] \
        .link_loop_next.edge.other_vert(e.other_vert(pivot_vert))

    # end_v = [loop for loop in e.link_loops if loop.vert == pivot_vert][0] \
    #     .link_loop_radial_next.link_loop_next.edge.other_vert(pivot_vert)

    plane_no = e.verts[0].co - e.verts[1].co

    p = intersect_line_plane(e.verts[0].co, e.verts[1].co, start_v.co,
                             plane_no)

    print("New intersection point was {}".format(p))

    for face in list(e.link_faces):
        bm.faces.remove(face)

    intersection_vert = bm.verts.new(p)

    create_face_with_ccw_normal(bm, intersection_vert, op_vert_1, e.verts[0])
    create_face_with_ccw_normal(bm, intersection_vert, op_vert_1, e.verts[1])
    create_face_with_ccw_normal(bm, intersection_vert, op_vert_2, e.verts[0])
    create_face_with_ccw_normal(bm, intersection_vert, op_vert_2, e.verts[1])

    intersection_vert.normal = (start_v.co - p).cross(pivot_vert.co - p)

    print("Removing edge {}".format(e))
    bm.edges.remove(e)

    bm.verts.ensure_lookup_table()
    bm.verts.index_update()
    bm.edges.ensure_lookup_table()
    bm.edges.index_update()
    bm.faces.ensure_lookup_table()
    bm.faces.index_update()

    loop = [
        lo for lo in intersection_vert.link_loops
        if lo.edge.other_vert(intersection_vert) == pivot_vert
    ][0]

    return loop
Example #33
0
def GetMouseLocation(self, event, context):
	region = bpy.context.region
	rv3d = bpy.context.region_data
	coord = event.mouse_region_x, event.mouse_region_y
	view_vector_mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
	ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
	V_a = ray_origin_mouse + view_vector_mouse
	V_b = rv3d.view_rotation @ Vector((0.0, 0.0, -1.0))
	pointLoc = intersect_line_plane(ray_origin_mouse, V_a, context.object.location, V_b)
	loc = (self.GeneralNormal @ pointLoc) * -1
	return loc
Example #34
0
 def get_pos3d(self, context):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     rM = context.active_object.matrix_world.to_3x3()
     view_vector_mouse = view3d_utils.region_2d_to_vector_3d(
         region, rv3d, self.mouse_pos)
     ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(
         region, rv3d, self.mouse_pos)
     pt = intersect_line_plane(ray_origin_mouse,
                               ray_origin_mouse + view_vector_mouse,
                               self.origin, rM * self.glprovider.normal,
                               False)
     # attempt to fix issue with parallel plane
     if pt is None:
         pt = intersect_line_plane(ray_origin_mouse,
                                   ray_origin_mouse + view_vector_mouse,
                                   self.origin, view_vector_mouse, False)
     return pt
Example #35
0
    def grab_mouse_move(self, context, x, y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        hit = False
        if self.snap_type == 'SCENE':

            mx = Matrix.Identity(4)  #scene ray cast returns world coords
            imx = Matrix.Identity(4)
            no_mx = imx.to_3x3().transposed()

            res, loc, no, ind, obj, omx = context.scene.ray_cast(
                context.view_layer, ray_origin, view_vector)
            #res, loc, no, ind, obj, omx = context.scene.ray_cast(ray_origin, view_vector)

            if res:
                hit = True

            else:
                #cast the ray into a plane a
                #perpendicular to the view dir, at the last bez point of the curve
                hit = True
                view_direction = rv3d.view_rotation @ Vector((0, 0, -1))
                plane_pt = self.grab_undo_loc
                loc = intersect_line_plane(ray_origin, ray_target, plane_pt,
                                           view_direction)
                no = view_direction

        elif self.snap_type == 'OBJECT':
            mx = self.snap_ob.matrix_world
            imx = mx.inverted()
            no_mx = imx.to_3x3().transposed()
            #if bversion() < '002.077.000':
            #    loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin, imx * ray_target)
            #    if face_ind != -1:
            #        hit = True
            #else:
            ok, loc, no, face_ind = self.snap_ob.ray_cast(
                imx @ ray_origin, imx @ ray_target - imx @ ray_origin)
            if ok:
                hit = True

        if not hit:
            self.grab_cancel()

        else:
            self.b_pts[self.selected].location = mx @ loc
            self.b_pts[self.selected].surface_normal = no_mx @ no
            self.update_ui()
Example #36
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()
        bm = bmesh.new()
        bm.from_mesh(context.active_object.data)

        # For easy access to verts, edges, and faces:
        bVerts = bm.verts
        bEdges = bm.edges
        bFaces = bm.faces

        fVerts = []
        normal = None

        # Find the selected face.  This will provide the plane to project onto:
        for f in bFaces:
            if f.select:
                for v in f.verts:
                    fVerts.append(v)
                f.normal_update()
                normal = f.normal
                f.select = False
                break

        for e in bEdges:
            if e.select:
                v1 = e.verts[0]
                v2 = e.verts[1]
                if v1 in fVerts and v2 in fVerts:
                    e.select = False
                    continue
                intersection = intersect_line_plane(v1.co, v2.co, fVerts[0].co, normal)
                if intersection != None:
                    d1 = distance_point_to_plane(v1.co, fVerts[0].co, normal)
                    d2 = distance_point_to_plane(v2.co, fVerts[0].co, normal)
                    # If they have different signs, then the edge crosses the plane:
                    if abs(d1 + d2) < abs(d1 - d2):
                        # Make the first vertice the positive vertice:
                        if d1 < d2:
                            v2, v1 = v1, v2
                        new = list(bmesh.utils.edge_split(e, v1, 0.5))
                        new[1].co = intersection
                        e.select = False
                        new[0].select = False
                        if self.pos:
                            bEdges.remove(new[0])
                        if self.neg:
                            bEdges.remove(e)

        bm.to_mesh(context.active_object.data)
        bpy.ops.object.editmode_toggle()
##        bpy.ops.mesh.remove_doubles()
        return {'FINISHED'}
Example #37
0
  def grab_mouse_move(self,context,x,y):
      region = context.region
      rv3d = context.region_data
      coord = x, y
      view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
      ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
      ray_target = ray_origin + (view_vector * 1000)
      
      crv_mx = self.crv_obj.matrix_world
      i_crv_mx = crv_mx.inverted()  
      
      
      hit = False
      if self.snap_type == 'SCENE':
          
          mx = Matrix.Identity(4) #scene ray cast returns world coords
          if bversion() < '002.077.000':
              res, obj, omx, loc, no = context.scene.ray_cast(ray_origin, ray_target)
          else:
              res, loc, no, ind, obj, omx = context.scene.ray_cast(ray_origin, view_vector)
          
          if res:
              hit = True
      
          else:
              #cast the ray into a plane a
              #perpendicular to the view dir, at the last bez point of the curve
              hit = True
              view_direction = rv3d.view_rotation * Vector((0,0,-1))
              plane_pt = self.grab_undo_loc
              loc = intersect_line_plane(ray_origin, ray_target,plane_pt, view_direction)
              
      elif self.snap_type == 'OBJECT':
          mx = self.snap_ob.matrix_world
          imx = mx.inverted()
          
          if bversion() < '002.077.000':
              loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin, imx * ray_target)
              if face_ind != -1:
                  hit = True
          else:
              ok, loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin, imx * ray_target - imx*ray_origin)
              if ok:
                  hit = True
 
      if not hit:
          self.grab_cancel()
          
      else:
          local_loc = i_crv_mx * mx * loc
          self.crv_data.splines[0].bezier_points[self.selected].co = local_loc
          self.b_pts[self.selected] = mx * loc
Example #38
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()
        bm = bmesh.new()
        bm.from_mesh(context.active_object.data)

        # For easy access to verts, edges, and faces:
        bVerts = bm.verts
        bEdges = bm.edges
        bFaces = bm.faces

        fVerts = []
        normal = None

        # Find the selected face.  This will provide the plane to project onto:
        for f in bFaces:
            if f.select:
                for v in f.verts:
                    fVerts.append(v)
                f.normal_update()
                normal = f.normal
                f.select = False
                break

        for e in bEdges:
            if e.select:
                v1 = e.verts[0]
                v2 = e.verts[1]
                if v1 in fVerts and v2 in fVerts:
                    e.select = False
                    continue
                intersection = intersect_line_plane(v1.co, v2.co, fVerts[0].co, normal)
                if intersection != None:
                    d1 = distance_point_to_plane(v1.co, fVerts[0].co, normal)
                    d2 = distance_point_to_plane(v2.co, fVerts[0].co, normal)
                    # If they have different signs, then the edge crosses the plane:
                    if abs(d1 + d2) < abs(d1 - d2):
                        # Make the first vertice the positive vertice:
                        if d1 < d2:
                            v2, v1 = v1, v2
                        new = list(bmesh.utils.edge_split(e, v1, 0.5))
                        new[1].co = intersection
                        e.select = False
                        new[0].select = False
                        if self.pos:
                            bEdges.remove(new[0])
                        if self.neg:
                            bEdges.remove(e)

        bm.to_mesh(context.active_object.data)
        bpy.ops.object.editmode_toggle()
##        bpy.ops.mesh.remove_doubles()
        return {'FINISHED'}
Example #39
0
def region_2d_to_location_3d(region, rv3d, coord, depth_location):
    """
    Return a 3d location from the region relative 2d coords, aligned with
    *depth_location*.

    :arg region: region of the 3D viewport, typically bpy.context.region.
    :type region: :class:`bpy.types.Region`
    :arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
    :type rv3d: :class:`bpy.types.RegionView3D`
    :arg coord: 2d coordinates relative to the region;
       (event.mouse_region_x, event.mouse_region_y) for example.
    :type coord: 2d vector
    :arg depth_location: the returned vectors depth is aligned with this since
       there is no defined depth with a 2d region input.
    :type depth_location: 3d vector
    :return: normalized 3d vector.
    :rtype: :class:`mathutils.Vector`
    """
    from mathutils import Vector
    from mathutils.geometry import intersect_point_line

    persmat = rv3d.perspective_matrix.copy()
    viewinv = rv3d.view_matrix.inverted()
    coord_vec = region_2d_to_vector_3d(region, rv3d, coord)
    depth_location = Vector(depth_location)

    if rv3d.is_perspective:
        from mathutils.geometry import intersect_line_plane

        origin_start = viewinv.translation.copy()
        origin_end = origin_start + coord_vec
        view_vec = viewinv.col[2].copy()
        return intersect_line_plane(
            origin_start,
            origin_end,
            depth_location,
            view_vec,
            1,
        )
    else:
        dx = (2.0 * coord[0] / region.width) - 1.0
        dy = (2.0 * coord[1] / region.height) - 1.0
        persinv = persmat.inverted()
        viewinv = rv3d.view_matrix.inverted()
        origin_start = ((persinv.col[0].xyz * dx) + (persinv.col[1].xyz * dy) +
                        viewinv.translation)
        origin_end = origin_start + coord_vec
        return intersect_point_line(
            depth_location,
            origin_start,
            origin_end,
        )[0]
Example #40
0
 def edge_intersection(self, points: List[Point]):
     s0, s1 = map(self.side, points)
     if abs(s0 + s1) == 2:
         return []   # points on same side
     p0, p1 = map(Point, points)
     if s0 == 0 and s1 == 0:
         return [(p0, p1)]
     if s0 == 0:
         return [(p0, p0)]
     if s1 == 0:
         return [(p1, p1)]
     p01 = Point(intersect_line_plane(p0, p1, self.o, self.n))
     return [(p01, p01)]
Example #41
0
def get_world_coords(coords):
    cont = logic.getCurrentController()
    ray = cont.sensors["MouseRay"]
    
    ray_start = ray.raySource
    ray_end = ray.rayTarget
    
    plane_origin = Vector((0, 0, 0))
    plane_normal = Vector((0, 0, 1))
    
    intersection = geometry.intersect_line_plane(ray_start, ray_end, plane_origin, plane_normal)
    if intersection:
        return intersection
Example #42
0
 def edge_intersection(self, points: List[Point]):
     s0, s1 = map(self.side, points)
     if abs(s0 + s1) == 2:
         return []  # points on same side
     p0, p1 = map(Point, points)
     if s0 == 0 and s1 == 0:
         return [(p0, p1)]
     if s0 == 0:
         return [(p0, p0)]
     if s1 == 0:
         return [(p1, p1)]
     p01 = Point(intersect_line_plane(p0, p1, self.o, self.n))
     return [(p01, p01)]
Example #43
0
def region_2d_to_location_3d(region, rv3d, coord, depth_location):
    """
    Return a 3d location from the region relative 2d coords, aligned with
    *depth_location*.

    :arg region: region of the 3D viewport, typically bpy.context.region.
    :type region: :class:`bpy.types.Region`
    :arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
    :type rv3d: :class:`bpy.types.RegionView3D`
    :arg coord: 2d coordinates relative to the region;
       (event.mouse_region_x, event.mouse_region_y) for example.
    :type coord: 2d vector
    :arg depth_location: the returned vectors depth is aligned with this since
       there is no defined depth with a 2d region input.
    :type depth_location: 3d vector
    :return: normalized 3d vector.
    :rtype: :class:`mathutils.Vector`
    """
    from mathutils import Vector
    from mathutils.geometry import intersect_point_line

    persmat = rv3d.perspective_matrix.copy()
    viewinv = rv3d.view_matrix.inverted()
    coord_vec = region_2d_to_vector_3d(region, rv3d, coord)
    depth_location = Vector(depth_location)

    if rv3d.is_perspective:
        from mathutils.geometry import intersect_line_plane

        origin_start = viewinv.translation.copy()
        origin_end = origin_start + coord_vec
        view_vec = viewinv.col[2].copy()
        return intersect_line_plane(origin_start,
                                    origin_end,
                                    depth_location,
                                    view_vec, 1,
                                    )
    else:
        dx = (2.0 * coord[0] / region.width) - 1.0
        dy = (2.0 * coord[1] / region.height) - 1.0
        persinv = persmat.inverted()
        viewinv = rv3d.view_matrix.inverted()
        origin_start = ((persinv.col[0].xyz * dx) +
                        (persinv.col[1].xyz * dy) +
                         viewinv.translation)
        origin_end = origin_start + coord_vec
        return intersect_point_line(depth_location,
                                    origin_start,
                                    origin_end,
                                    )[0]
 def mousemove_drawing(self, context, event):
     screen_v = Vector((event.mouse_region_x, event.mouse_region_y))
     self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
    
     #this will just add in apoint every 10 recorded mouse positions
     #later you will want to do something smarter :-)
     if len(self.mouse_path) > self.draw_points_max or (screen_v - Vector(self.mouse_path[0])).length >= self.extrusion_radius:
         region = context.region
         rv3d = context.region_data
         #this is the view_vector @ the mous coord
         #which is not the same as the view_direction!!!
         view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, self.mouse_path[-1])
         ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, self.mouse_path[-1])
         ray_target = ray_origin + (view_vector * 10000)
        
         #cast the ray into a plane a
         #perpendicular to the view dir, at the last bez point of the curve
         
         view_direction = rv3d.view_rotation * Vector((0,0,-1))
         if self.active_spline.type == 'BEZIER':
             plane_pt = self.curve_object.matrix_world * self.active_spline.bezier_points[-1].co
         elif self.active_spline.type == 'NURBS':
             plane_pt = self.curve_object.matrix_world * self.active_spline.points[-1].co
             
         new_coord = intersect_line_plane(ray_origin, ray_target,plane_pt, view_direction)
        
         if new_coord:
             if self.active_spline.type == 'BEZIER':
                 self.active_spline.bezier_points.add(1)
                 self.active_spline.bezier_points[-1].co = self.curve_object.matrix_world.inverted() * new_coord
                 self.active_spline.bezier_points[-1].handle_right.xyz = self.active_spline.bezier_points[-1].co
                 self.active_spline.bezier_points[-1].handle_left.xyz = self.active_spline.bezier_points[-1].co
                 self.active_spline.bezier_points[-1].handle_left_type = 'AUTO'
                 self.active_spline.bezier_points[-1].handle_right_type = 'AUTO'
                 
             elif self.active_spline.type == 'NURBS':
                 self.active_spline.points.add(1)
                 loc = self.curve_object.matrix_world.inverted() * new_coord
                 #NURBS pahts have 4 dim points
                 self.active_spline.points[-1].co = Vector((loc[0], loc[1], loc[2], 1))
                 
            
             #udpate everything
             #udpate modifiers and objects etc.
             self.curve_object.update_tag()
             context.scene.update()
            
         self.mouse_path = []
Example #45
0
    def _intersect_edge_plane(self, edge, orientation, position, ix_points):
        """ Find the intersection between this edge and plane.
        Append the IntersectionPoint (if any) to ix_points.
        """
        if (edge, None) in self._saved_results:
            return self._saved_results[(edge, None)]

        if (edge.t_vert.pos[orientation] > position and
            edge.b_vert.pos[orientation] > position):
            point = None
        elif (edge.t_vert.pos[orientation] < position and
              edge.b_vert.pos[orientation] < position):
            point = None
        else:
            vec_t_vert = Vector((edge.t_vert.pos))
            vec_b_vert = Vector((edge.b_vert.pos))

            plane_co = Vector(([0,0,0]))
            plane_co[orientation] = position

            plane_norm = Vector(([0,0,0]))
            plane_norm[orientation] = 1.

            point = intersect_line_plane(vec_t_vert,
                                         vec_b_vert,
                                         plane_co,
                                         plane_norm,
                                         False) # only intersect segment

        if not point:
            ix_point = None
            # print("Not found!")
            # print("  t_vert: " + str(edge.t_vert.pos))
            # print("  b_vert: " + str(edge.b_vert.pos))
            # print("  pl_pos: " + str(position))
        else:
            # print("Found ixpoint! " + str(point))
            # print("  t_vert: " + str(vec_t_vert))
            # print("  b_vert: " + str(vec_b_vert))
            # print("  pl_pos: " + str(position))
            ix_point = IntersectionPoint(edge, None, point)
            ix_points.append(ix_point)
            
        self._saved_results[(edge, None)] = ix_point

        return ix_point
Example #46
0
def f_1(me, list_0, list_1):

    dict_1 = {vi: [] for vi in list_1}

    for fi in list_0:
        f = me.faces[fi]
        for vi in list_1:
            v = (me.vertices[vi].co).copy()
            p = v + ((f.normal).copy() * 0.1)
            pp = (me.vertices[f.vertices[0]].co).copy()
            pn = (f.normal).copy()
            p1 =  intersect_line_plane(v, p, pp, pn)
            d = (p1 - v).length
            p2 = p1 + ((f.normal).copy() * d)
            me.vertices.add(1)
            me.vertices[-1].co = p2
            me.vertices[-1].select = False
            dict_1[vi].append(me.vertices[-1].index)

    n = len(list_0)
    edge_copy_1(me, dict_1, n)
    faces_copy_1(me, dict_1, n)
def f_3(me, list_f, list_0):
    
    dict_1 = {vi: [] for vi in list_0}

    for fi in list_f:
        f = me.faces[fi]
        pp = (me.vertices[f.vertices[0]].co).copy()
        pn = (f.normal).copy()
        for vi in list_0:
            v = (me.vertices[vi].co).copy()
            p = v + ((f.normal).copy() * 0.1)

            p1 =  intersect_line_plane(v, p, pp, pn)

            me.vertices.add(1)
            me.vertices[-1].co = p1
            me.vertices[-1].select = False
            dict_1[vi].append(me.vertices[-1].index)

    n = len(list_f)
    edge_copy_1(me, dict_1, n)
    faces_copy_1(me, dict_1, n)
Example #48
0
def com_line_cross_test(com1, com2, pt, no, factor = 2):
    '''
    test used to make sure a cut is reasoably between
    2 other cuts
    
    higher factor requires better aligned cuts
    '''
    
    v = intersect_line_plane(com1,com2,pt,no)
    if v:
        #if the distance between the intersection is less than
        #than 1/factor the distance between the current pair
        #than this pair is invalide because there is a loop
        #in between
        check = intersect_point_line(v,com1,com2)
        invalid_length = (com2 - com1).length/factor  #length beyond which an intersection is invalid
        test_length = (v - pt).length
        
        #this makes sure the plane is between A and B
        #meaning the test plane is between the two COM's
        in_between = check[1] >= 0 and check[1] <= 1
        
        if in_between and test_length < invalid_length:
            return True
Example #49
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()

        bm = bmesh.new()
        bm.from_mesh(context.active_object.data)

        bFaces = bm.faces
        bEdges = bm.edges
        bVerts = bm.verts

        fVerts = []

        # Find the selected face.  This will provide the plane to project onto:
        for f in bFaces:
            if f.select:
                for v in f.verts:
                    fVerts.append(v)
                f.normal_update()
                normal = f.normal
                f.select = False
                break

        for e in bEdges:
            if e.select:
                v1 = e.verts[0]
                v2 = e.verts[1]
                if v1 in fVerts or v2 in fVerts:
                    e.select = False
                    continue
                intersection = intersect_line_plane(v1.co, v2.co, fVerts[0].co, normal)
                if intersection != None:
                    print("Made it this far: intersection != None")
                    # Use abs because we don't care what side of plane we're on:
                    d1 = distance_point_to_plane(v1.co, fVerts[0].co, normal)
                    d2 = distance_point_to_plane(v2.co, fVerts[0].co, normal)
                    # If d1 is closer than we use v1 as our vertice:
                    # "xor" with 'use_force':
                    if (abs(d1) < abs(d2)) is not self.use_force:
                        print("Made it this far: (abs(d1) < abs(d2)) xor force")
                        if self.make_copy:
                            v1 = bVerts.new()
                            v1.co = e.verts[0].co
                        if self.use_normal:
                            vector = normal
                            vector.length = abs(d1)
                            v1.co = v1.co - (vector * sign(d1))
                        else:
                            print("New coordinate", end = ": ")
                            print(intersection)
                            v1.co = intersection
                    else:
                        if self.make_copy:
                            v2 = bVerts.new()
                            v2.co = e.verts[1].co
                        if self.use_normal:
                            vector = normal
                            vector.length = abs(d2)
                            v2.co = v2.co - (vector * sign(d2))
                        else:
                            v2.co = intersection
                e.select = False

        bm.to_mesh(context.active_object.data)
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
        face = f
        fedges = f.edges

if not fedges: print('no face')
else:
    for e in bm.edges:
        if e.select == True and not isEdgeOfFace(e, fedges):
            sedges.append(e)
    if not sedges: print('no edge')
    else:
        # <HEART>
        for sedge in sedges:
            iv = geometry.intersect_line_plane(
                sedge.verts[0].co,
                sedge.verts[1].co,
                face.verts[0].co,
                face.normal,
                False
            )
            if iv == None: print('coplanar edge is selected')
            else:
                sedge.select = False
                bm.verts.new(iv).select = True
        face.select = False
        bmesh.update_edit_mesh(me)
        # vert mode highligts created verts
        bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
# -------------------------------------------
# select a face plus some other mesh edges
# run script, VERTICES PLACED where that plane crossed an edge
# .. face edges considered to be planar
Example #51
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 cross_section(bme, mx, point, normal, debug = True):
    '''
    Takes a mesh and associated world matrix of the object and returns a cross secion in local
    space.
    
    Args:
        mesh: Blender BMesh
        mx:   World matrix (type Mathutils.Matrix)
        point: any point on the cut plane in world coords (type Mathutils.Vector)
        normal:  plane normal direction (type Mathutisl.Vector)
    '''
    
    times = []
    times.append(time.time())
    #bme = bmesh.new()
    #bme.from_mesh(me)
    #bme.normal_update()
    
    #if debug:
        #n = len(times)
        #times.append(time.time())
        #print('succesfully created bmesh in %f sec' % (times[n]-times[n-1]))
    verts =[]
    eds = []
    
    #convert point and normal into local coords
    #in the mesh into world space.This saves 2*(Nverts -1) matrix multiplications
    imx = mx.inverted()
    pt = imx * point
    no = imx.to_3x3() * normal  #local normal
    
    edge_mapping = {}  #perhaps we should use bmesh becaus it stores the great cycles..answer yup
    
    for ed in bme.edges:
        
        A = ed.verts[0].co
        B = ed.verts[1].co
        V = B - A
        
        proj = V.project(no).length
        
        #perp to normal = parallel to plane
        #only calc 2nd projection if necessary
        if proj == 0:
            
            #make sure not coplanar
            p_to_A = A - pt
            a_proj = p_to_A.project(no).length
            
            if a_proj == 0:
               
                edge_mapping[len(verts)] = ed.link_faces
                verts.append(1/2 * (A +B)) #put a midpoing since both are coplanar

        else:
            
            #this handles the one point on plane case
            v = intersect_line_plane(A,B,pt,no)
           
            if v:
                check = intersect_point_line(v,A,B)
                if check[1] >= 0 and check[1] <= 1:
                    
                                             
                    
                    #the vert coord index    =  the face indices it came from
                    edge_mapping[len(verts)] = [f.index for f in ed.link_faces]
                    verts.append(v)
    
    if debug:
        n = len(times)
        times.append(time.time())
        print('calced intersections %f sec' % (times[n]-times[n-1]))
       
    #iterate through smartly to create edge keys          
    for i in range(0,len(verts)):
        a_faces = set(edge_mapping[i])
        for m in range(i,len(verts)):
            if m != i:
                b_faces = set(edge_mapping[m])
                if a_faces & b_faces:
                    eds.append((i,m))
    
    if debug:
        n = len(times)
        times.append(time.time())
        print('calced connectivity %f sec' % (times[n]-times[n-1]))
        
    if len(verts):
        #new_me = bpy.data.meshes.new('Cross Section')
        #new_me.from_pydata(verts,eds,[])
        
    
        #if debug:
            #n = len(times)
            #times.append(time.time())
            #print('Total Time: %f sec' % (times[-1]-times[0]))
            
        return (verts, eds)
    else:
        return None
Example #53
0
 def intersect(self, v1, v2):
     """平面とv1-v2からなる直線の交点を求める"""
     return geom.intersect_line_plane(v1, v2, self.location, self.normal)
def cross_edge(A,B,pt,no):
    '''
    wrapper of intersect_line_plane that limits intersection
    to within the line segment.
    
    args:
        A - Vector endpoint of line segment
        B - Vector enpoint of line segment
        pt - pt on plane to intersect
        no - normal of plane to intersect
        
    return:
        list [Intersection Type, Intersection Point, Intersection Point2]
        eg... ['CROSS',Vector((0,1,0)), None]
        eg... ['POINT',Vector((0,1,0)), None]
        eg....['COPLANAR', Vector((0,1,0)),Vector((0,2,0))]
        eg....[None,None,None]
    '''
 
    ret_val = [None]*3 #list [intersect type, pt 1, pt 2]
    V = B - A #vect representation of the edge
    proj = V.project(no).length
    
    #perp to normal = parallel to plane
    #worst case is a coplanar issue where the whole face is coplanar..we will get there
    if proj == 0:
        
        #test coplanar
        #don't test both points.  We have already tested once for paralellism
        #simply proving one out of two points is/isn't in the plane will
        #prove/disprove coplanar
        p_to_A = A - pt
        #truly, we could precalc all these projections to save time but use mem.
        #because in the multiple edges coplanar case, we wil be testing
        #their verts over and over again that share edges.  So for a mesh with
        #a lot of n poles, precalcing the vert projections may save time!  
        #Hint to future self, look at  Nfaces vs Nedges vs Nverts
        #may prove to be a good predictor of which method to use.
        a_proj = p_to_A.project(no).length
        
        if a_proj == 0:
            print('special case co planar edge')
            ret_val = ['COPLANAR',A,B]
            
    else:
        
        #this handles the one point on plane case
        v = intersect_line_plane(A,B,pt,no)
       
        if v:
            check = intersect_point_line(v,A,B)
            if check[1] > 0 and check[1] < 1:  #this is the purest cross...no co-points
                #the vert coord index    =  the face indices it came from
                ret_val = ['CROSS',v,None]
                
            elif check[1] == 0 or check[1] == 1:
                print('special case coplanar point')
                #now add all edges that have that point into the already checked list
                #this takes care of poles
                ret_val = ['POINT',v,None]
    
    return ret_val
Example #55
0
    def push_mesh_data(self,context, re_order = True):
        
        if len(self.cut_lines) < 2:
            print('waiting on other cut lines')
            return
        
        imx = self.original_form.matrix_world.inverted()
        
        total_verts = []
        total_edges = []
        total_faces = []
        
        valid_cuts = [c_line for c_line in self.cut_lines if c_line.verts != [] and c_line.verts_simple != []]
        self.cut_lines = valid_cuts
        if len(valid_cuts) < 2:
            return
        


        #####order the cuts####
        
        #first dictionary their current indices
        planes = [(cut.plane_pt, cut.plane_no) for cut in valid_cuts]
        
        valid_pairs = []
        #test validity of all pairs
        #a pair is valid if the line segment corosses
        #none of the other planes reasonable close to
        #the plane origin.  This will fail in hairpin turns
        #but that case should be relatively uncommon
        
        for i in range(0,len(valid_cuts)):
            for m in range(i,len(valid_cuts)):
                if m != i:
                    pair = (i,m)
                    valid_pairs.append(pair)
                    A = valid_cuts[i].plane_pt
                    B = valid_cuts[m].plane_pt
                    C = .5 * (A + B)
                    ray1 = A - valid_cuts[i].plane_tan.world_position
                    ray2 = B - valid_cuts[m].plane_tan.world_position
                    ray = ray1.lerp(ray2,.5).normalized()
                    
                    hit = self.original_form.ray_cast(imx * (C + 100 * ray), imx * (C - 100 * ray))
                    
                    for j, plane in enumerate(planes):
                        if j != i and j != m:
                            pt = plane[0]
                            no = plane[1]
                            v = intersect_line_plane(A,B,pt,no)
                            if v:
                                check = intersect_point_line(v,A,B)
                                pair_length = (B - A).length/2
                                inval_length = (v - pt).length
                                if (check[1] >= 0 and check[1] <= 1 and inval_length < pair_length) or hit[2] == -1:
                                    print('invalid pair %s' % str(pair))
                                    
                                    if pair in valid_pairs:
                                        valid_pairs.remove(pair)
                                    
        print(valid_pairs)
        
        if re_order and len(valid_pairs) > 0:
            #sort the pairs
            new_order = []
            new_order.append(valid_pairs[-1][0])
            new_order.append(valid_pairs[-1][1])
            valid_pairs.pop()
            
            tests = 0
            max_tests = len(valid_pairs) + 2
            while len(valid_pairs) and tests < max_tests:
                tests += 1
                for pair in valid_pairs:
                    end = set(pair) & {new_order[-1]}
                    beg = set(pair) & {new_order[0]}
                    if end or beg:
                        valid_pairs.remove(pair)
                        if end:
                            new_order.append(list(set(pair) - end)[0])
                        else:
                            new_order.insert(0, list(set(pair)-beg)[0])
                            
                        break
            print('the new order is')            
            print(new_order)     
            cuts_copy = valid_cuts.copy()
            valid_cuts = []
            for i, n in enumerate(new_order):
                valid_cuts.append(cuts_copy[n])
            
            del cuts_copy
            self.valid_cuts = valid_cuts  
        #now
        n_rings = len(self.valid_cuts)
        n_lines = len(self.valid_cuts[0].verts_simple)
        #align verts
        for i in range(0,n_rings-1):
            vs_1 = self.valid_cuts[i].verts_simple
            vs_2 = self.valid_cuts[i+1].verts_simple
            es_1 = self.valid_cuts[i].eds_simple
            es_2 = self.valid_cuts[i+1].eds_simple
            
            self.valid_cuts[i+1].verts_simple = contour_utilities.align_edge_loops(vs_1, vs_2, es_1, es_2)
        
                
        #work out the connectivity edges
        for i, cut_line in enumerate(self.valid_cuts):
            for v in cut_line.verts_simple:
                total_verts.append(imx * v)
            for ed in cut_line.eds_simple:
                total_edges.append((ed[0]+i*n_lines,ed[1]+i*n_lines))
            
            if i < n_rings - 1:
                #make connections between loops
                for j in range(0,n_lines):
                    total_edges.append((i*n_lines + j, (i+1)*n_lines + j))
        
        cyclic = 0 in valid_cuts[0].eds_simple[-1]
        #work out the connectivity faces:
        for j in range(0,len(valid_cuts) - 1):
            for i in range(0,n_lines-1):
                ind0 = j * n_lines + i
                ind1 = j * n_lines + (i + 1)
                ind2 = (j + 1) * n_lines + (i + 1)
                ind3 = (j + 1) * n_lines + i
                total_faces.append((ind0,ind1,ind2,ind3))
            
            if cyclic:
                ind0 = (j + 1) * n_lines - 1
                ind1 = j * n_lines + int(math.fmod((j+1)*n_lines, n_lines))
                ind2 = ind0 + 1
                ind3 = ind0 + n_lines
                total_faces.append((ind0,ind1,ind2,ind3))
                print('part implemented')
        print(len(total_verts))       
        print(total_faces)
        self.follow_lines = []
        for i in range(0,len(self.valid_cuts[0].verts_simple)):
            tmp_line = []
            for cut_line in self.valid_cuts:
                tmp_line.append(cut_line.verts_simple[i])
            self.follow_lines.append(tmp_line)


        self.verts = total_verts
        self.faces = total_faces
        self.edges = total_edges
        '''
Example #56
0
def find_sorted_bmedges_crossing_plane(pt, no, edges, epsilon, e_ind_from, co_from):
    '''
    pt - point on cutting plane: mathutils.Vector
    no - normal of cutting plane: mathutils.Vector
    edges - edges of BMeshFace
    epsilon - error for coplanar verts: Float
    e_ind_from - index of the previous bmesh edge the walker just crossed
    co_from  - location where the cutting plane crosses the lats BMEdge (e_ind_from)
    #e_exclude - a dictionary of edges previulsy crossed. dictionary should return order in which edges were crossed.
    
    returns a list of bmedges that *cross* plane and corresponding intersection points
    
    If BMFace happens to be a convex NGon with > 2 crosses, the list will be sorted such that the 0th item is the only
    valid intersection which makes an edge in teh cross section with e_ind_from.
    
    '''
    if(len(edges)<=4):
        # shortcut (no need to find multiple... just find first)
        for edge in edges:
            if edge.index == e_ind_from: continue
            v0,v1 = edge.verts
            co0,co1 = v0.co,v1.co
            s0,s1 = no.dot(co0 - pt), no.dot(co1 - pt)
            no_cross = not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon))
            if no_cross: continue
            i = intersect_line_plane(co0, co1, pt, no)
            return [(edge,i)]

    #http://stackoverflow.com/questions/6618515/sorting-list-based-on-values-from-another-list
    i_edges = []
    intersects = []
    ds = [] 
    coords = {} #cache these to prevent twice per vert calcing
    for edge in edges:
        v0,v1 = edge.verts
        if v0 not in coords: coords[v0] = no.dot(v0.co-pt)
        if v1 not in coords: coords[v1] = no.dot(v1.co-pt)
        
    for edge in edges:
        #if edge.index == e_ind_from: continue  #<--we do need the e_ind_from edge because it helps us sort
        #if edge.index in e_ind_exclude: continue  #<-maybe don't need this because of the ordering :-)
        v0,v1 = edge.verts
        s0,s1 = coords[v0],coords[v1]
        if s0 > epsilon and s1 > epsilon: continue
        if s0 < -epsilon and s1 < -epsilon: continue
        #if not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon)):      # edge cross plane?
        #    continue
        
        i = intersect_line_plane(v0.co, v1.co, pt, no)
        d = (i - co_from).length
        
        i_edges += [edge]
        intersects += [i]
        ds += [d]
        
    
    if len(i_edges) == 2:
        ed = [e for e in i_edges if e.index != e_ind_from][0]
        return [(ed, intersects[i_edges.index(ed)])]
    
    elif len(i_edges) > 2:  #a concave ngon with 4,6,8.. crossings
        print('there are %i crossings' % len(i_edges))
        #all the crossings are colinear if ngon is planar, so sorting them is easy
        edge_from = [e for e in i_edges if e.index == e_ind_from][0]
        min_i = intersects[i_edges.index(edge_from)]
        
        max_i = intersects[ds.index(max(ds))]
        direction = (max_i - min_i).normalized()
        
        signed_ds = []
        for j, ed in enumerate(i_edges):
            signed_ds += [(intersects[j] - min_i).dot(direction)]
            
        #[x for (y,x) in sorted(zip(Y,X))]  X sorted by Y
        sorted_edges = [ed for (d,ed) in sorted(zip(signed_ds,i_edges))]
        sorted_is = [i for (d,i) in sorted(zip(signed_ds, intersects))]
        n = sorted_edges.index(edge_from)
        
        if n % 2 == 0:
            print('odd crossings, this is the problem or a bad face')
            sorted_edges = list(reversed(list_shift(sorted_edges, n + 2)))
            sorted_is = list(reversed(list_shift(sorted_is, n + 2)))
        
        else:
            sorted_edges = list_shift(sorted_edges, n - 1)
            sorted_is =list_shift(sorted_is, n - 1)
        print('came from this edge ' + str(e_ind_from))
        print('leaving to this edge' + str(sorted_edges[0].index))
        return list(zip(sorted_edges, sorted_is))
    
    else:
        print('no crossings perhaps')
        print([e.index for e in edges])
        print(pt)
        print(no)
        return []
Example #57
0
def find_bmedges_crossing_plane(pt, no, edges, epsilon):
    '''
    pt - pt on cutting plane: mathutils.Vector
    no - normal of cutting plane: mathutils.Vector
    edges - edges of BMFace:  bmesh.BMEdge
    epsilon - dist from plane < epsilon means coplanar
    
    returns a list of tupples (edge, intersection):  [(BMEdges, mathutils.Vector)]
    
    if there are more than two (indicating a concave NGon) edges will be returned
    ordered across the ngon (in an arbitrary direction) such that only 
    intersections (0,1), (2,3), (4,5) can make valid edges.
    
    this information is useful for special cases like E or pac-man shaped Ngons (dumb scenarios)
    see this image #TODO link
    
    also, for God's sake, the NGon better be planar
    '''
    
    coords = {}
    for edge in edges:
        v0,v1 = edge.verts
        if v0 not in coords: coords[v0] = no.dot(v0.co-pt)
        if v1 not in coords: coords[v1] = no.dot(v1.co-pt)
    #print(str(coords))
    
    i_edges = []
    intersects = []
    ds = [] 
    signed_ds = []
    
    for edge in edges:
        v0,v1 = edge.verts
        s0,s1 = coords[v0],coords[v1]
        if s0 > epsilon and s1 > epsilon: continue
        if s0 < -epsilon and s1 < -epsilon: continue
        #if not ((s0>epsilon and s1<-epsilon) or (s0<-epsilon and s1>epsilon)):      # edge cross plane?
        #    continue
        
        i = intersect_line_plane(v0.co, v1.co, pt, no)
        if not i: continue  
        d = (i - pt).length
        if d == 0.00:
            d = epsilon
        i_edges += [edge]
        intersects += [i]
        ds += [d]
            
    if len(i_edges) > 2:  #a concave ngon with 4,6,8.. crossings
        
        print('There are %i crossed edges' % len(i_edges))
        print('There are %i total edges' % len(edges))
        #all the crossings are colinear if ngon is planar, so sorting them is easy
        min_i = intersects[ds.index(min(ds))]
        min_ed = i_edges[ds.index(min(ds))]
        
        max_i = intersects[ds.index(max(ds))]
        direction = (max_i - min_i).normalized()
        
        signed_ds = []
        for j, ed in enumerate(i_edges):
            signed_ds += [(intersects[j] - min_i).dot(direction)]
            
        print('signed_ds')
        print(signed_ds)
        
        #[x for (y,x) in sorted(zip(Y,X))]  X sorted by Y
        sorted_edges = [ed for (d,ed) in sorted(zip(signed_ds,i_edges))]
        sorted_is = [i for (d,i) in sorted(zip(signed_ds, intersects))]
        n = sorted_edges.index(min_ed)
        
        if n % 2:
            print('shifting and reversing')
            sorted_edges = list(reversed(list_shift(sorted_edges, n + 1)))
            sorted_is = list(reversed(list_shift(sorted_is, n + 1)))
    
    elif len(i_edges) == 0:
        print('no edges crossing plane')
        sorted_edges = []
        sorted_is = [] 
    else:
        sorted_edges = i_edges
        sorted_is = intersects        
    return list(zip(sorted_edges,sorted_is))
Example #58
0
 def line_intersection(self, p0:Point, p1:Point):
     return intersect_line_plane(p0, p1, self.o, self.n)
def snap_utilities(self,
    context,
    obj_matrix_world,
    bm_geom,
    bool_update,
    mcursor,
    outer_verts = False,
    constrain = None,
    previous_vert = None,
    ignore_obj = None,
    increment = 0.0):

    rv3d = context.region_data
    region = context.region
    is_increment = False

    if not hasattr(self, 'snap_cache'):
        self.snap_cache = True
        self.type = 'OUT'
        self.bvert = None
        self.bedge = None
        self.bface = None
        self.hit = False
        self.out_obj = None

    if bool_update:
        #self.bvert = None
        self.bedge = None
        #self.bface = None

    if isinstance(bm_geom, bmesh.types.BMVert):
        self.type = 'VERT'

        if self.bvert != bm_geom:
            self.bvert = bm_geom
            self.vert = obj_matrix_world * self.bvert.co
            #self.Pvert = location_3d_to_region_2d(region, rv3d, self.vert)
        
        if constrain:
            #self.location = (self.vert-self.const).project(vector_constrain) + self.const
            location = intersect_point_line(self.vert, constrain[0], constrain[1])
            #factor = location[1]
            self.location = location[0]
        else:
            self.location = self.vert

    elif isinstance(bm_geom, bmesh.types.BMEdge):
        if self.bedge != bm_geom:
            self.bedge = bm_geom
            self.vert0 = obj_matrix_world*self.bedge.verts[0].co
            self.vert1 = obj_matrix_world*self.bedge.verts[1].co
            self.po_cent = (self.vert0+self.vert1)/2
            self.Pcent = location_3d_to_region_2d(region, rv3d, self.po_cent)
            self.Pvert0 = location_3d_to_region_2d(region, rv3d, self.vert0)
            self.Pvert1 = location_3d_to_region_2d(region, rv3d, self.vert1)
        
            if previous_vert and previous_vert not in self.bedge.verts:
                    pvert_co = obj_matrix_world*previous_vert.co
                    point_perpendicular = intersect_point_line(pvert_co, self.vert0, self.vert1)
                    self.po_perp = point_perpendicular[0]
                    #factor = point_perpendicular[1] 
                    self.Pperp = location_3d_to_region_2d(region, rv3d, self.po_perp)

        if constrain:
            location = intersect_line_line(constrain[0], constrain[1], self.vert0, self.vert1)
            if location == None:
                is_increment = True
                orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
                end = orig + view_vector
                location = intersect_line_line(constrain[0], constrain[1], orig, end)
            self.location = location[0]
        
        elif hasattr(self, 'Pperp') and abs(self.Pperp[0]-mcursor[0]) < 10 and abs(self.Pperp[1]-mcursor[1]) < 10:
            self.type = 'PERPENDICULAR'
            self.location = self.po_perp

        elif abs(self.Pcent[0]-mcursor[0]) < 10 and abs(self.Pcent[1]-mcursor[1]) < 10:
            self.type = 'CENTER'
            self.location = self.po_cent

        else:
            if increment and previous_vert in self.bedge.verts:
                is_increment = True
            self.type = 'EDGE'
            orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
            end = orig + view_vector
            self.location = intersect_line_line(self.vert0, self.vert1, orig, end)[0]

    elif isinstance(bm_geom, bmesh.types.BMFace):
        is_increment = True
        self.type = 'FACE'

        if self.bface != bm_geom:
            self.bface = bm_geom
            self.face_center = obj_matrix_world*bm_geom.calc_center_median()
            self.face_normal = bm_geom.normal*obj_matrix_world.inverted()

        orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
        end = orig + view_vector
        location = intersect_line_plane(orig, end, self.face_center, self.face_normal, False)
        if constrain:
            is_increment = False
            location = intersect_point_line(location, constrain[0], constrain[1])[0]

        self.location = location

    else:
        is_increment = True
        self.type = 'OUT'

        orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
        end = orig + view_vector * 1000

        if not outer_verts or self.out_obj == None:
            result, self.out_obj, self.out_mat, self.location, normal = context.scene.ray_cast(orig, end)
            self.out_mat_inv = self.out_mat.inverted()
            #print(self.location)

        if self.out_obj and self.out_obj != ignore_obj:
            self.type = 'FACE'
            if outer_verts:
                # get the ray relative to the self.out_obj
                ray_origin_obj = self.out_mat_inv * orig
                ray_target_obj = self.out_mat_inv * end
                location, normal, face_index = self.out_obj.ray_cast(ray_origin_obj, ray_target_obj)
                if face_index == -1:
                    self.out_obj = None
                else:
                    self.location = self.out_mat*location
                    try:
                        verts = self.out_obj.data.polygons[face_index].vertices
                        v_dist = 100

                        for i in verts:
                            v_co = self.out_mat*self.out_obj.data.vertices[i].co
                            v_2d = location_3d_to_region_2d(region, rv3d, v_co)
                            dist = (Vector(mcursor)-v_2d).length_squared
                            if dist < v_dist:
                                is_increment = False
                                self.type = 'VERT'
                                v_dist = dist
                                self.location = v_co
                    except:
                        print('Fail')
            if constrain:
                is_increment = False
                self.preloc = self.location
                self.location = intersect_point_line(self.preloc, constrain[0], constrain[1])[0]
        else:
            if constrain:
                self.location = intersect_line_line(constrain[0], constrain[1], orig, end)[0]
            else:
                self.location = out_Location(rv3d, region, orig, view_vector)

    if previous_vert:
        pvert_co = obj_matrix_world*previous_vert.co
        vec = self.location - pvert_co
        if is_increment and increment:
            pvert_co = obj_matrix_world*previous_vert.co
            vec = self.location - pvert_co
            self.len = round((1/increment)*vec.length)*increment
            self.location = self.len*vec.normalized() + pvert_co
        else:
            self.len = vec.length
Example #60
0
    def C_Beam(self):
        mid = self.w / 2
        web = self.tw / 2
        # Bottom of the stringer:
        baseZ = -self.rise - self.hT - self.h
        # Top of the strigner:
        topZ = -self.rise - self.hT
        # Vertical taper amount:
        taper = self.tf * self.tp

        if self.dis or self.nS == 1:
            offset = (self.wT / (self.nS + 1)) - mid
        else:
            offset = 0

        # taper < 100%:
        if self.tp > 0:
            for i in range(self.nS):
                coords = []
                coords.append(Vector([0, offset,                baseZ]))
                coords.append(Vector([0, offset,                baseZ + taper]))
                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
                coords.append(Vector([0, offset,                topZ - taper]))
                coords.append(Vector([0, offset,                topZ]))
                coords.append(Vector([0, offset + (mid - web),  topZ]))
                coords.append(Vector([0, offset + (mid + web),  topZ]))
                coords.append(Vector([0, offset + self.w,       topZ]))
                coords.append(Vector([0, offset + self.w,       topZ - taper]))
                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
                coords.append(Vector([0, offset + self.w,       baseZ + taper]))
                coords.append(Vector([0, offset + self.w,       baseZ]))
                coords.append(Vector([0, offset + (mid + web),  baseZ]))
                coords.append(Vector([0, offset + (mid - web),  baseZ]))
                for j in range(16):
                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
                # If the bottom meets the ground:
                #   Bottom be flat with the xy plane, but shifted down.
                #   Either project onto the plane along a vector (hard) or use the built in
                #       interest found in mathutils.geometry (easy).  Using intersect:
                if self.g:
                    for j in range(16):
                        coords[j] = intersect_line_plane(coords[j], coords[j + 16],
                                                         Vector([0, 0, topZ]),
                                                         Vector([0, 0, 1]))
                self.G.Make_mesh(coords, self.faces3a, 'stringer')

                if self.dis or self.nS == 1:
                    offset += self.wT / (self.nS + 1)
                else:
                    offset += (self.wT - self.w) / (self.nS - 1)
        # taper = 100%:
        else:
            for i in range(self.nS):
                coords = []
                coords.append(Vector([0, offset,                baseZ]))
                coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
                coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
                coords.append(Vector([0, offset,                topZ]))
                coords.append(Vector([0, offset + self.w,       topZ]))
                coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
                coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
                coords.append(Vector([0, offset + self.w,       baseZ]))
                for j in range(8):
                    coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
                self.G.Make_mesh(coords, self.faces3b, 'stringer')
                offset += self.wT / (self.nS + 1)
                
        return {'FINISHED'}