Example #1
0
def main(context, vaxis, gpAxis):
    axisdict = {"X": 0, "Y": 1, "Z": 2}
    mesh = bpy.context.object
    bm = bmesh.from_edit_mesh(mesh.data)
    axis = axisdict[vaxis]
    gpaxis = axisdict[gpAxis]

    for vertice in bm.verts:
        if vertice.select:
            imen = -1000
            imay = 1000
            punto = vertice.co + mesh.location

            jj = [
                point.co for point in bpy.context.scene.grease_pencil.layers.
                active.frames[0].strokes[0].points
            ]
            for point in bpy.context.scene.grease_pencil.layers.active.frames[
                    0].strokes[-1].points:
                if point.co[gpaxis] < punto[gpaxis] and point.co[gpaxis] > imen:
                    imen = point.co[gpaxis]
                    men = point.co
                if point.co[gpaxis] > punto[gpaxis] and point.co[gpaxis] < imay:
                    imay = point.co[gpaxis]
                    may = point.co
            try:
                may
                men
            except:
                print("wrong projection axis!")
                break

            if axis == 0:
                try:
                    vertice.co = (intersect_line_line(
                        men, may, punto,
                        (punto[0] + 1, punto[1], punto[2]))[0][0] -
                                  mesh.location[0], vertice.co.y, vertice.co.z)
                except:
                    pass
            if axis == 1:
                try:
                    vertice.co = (vertice.co.x,
                                  intersect_line_line(men, may, punto,
                                                      (punto[0], punto[1] + 1,
                                                       punto[2]))[0][1] -
                                  mesh.location[1], vertice.co.z)
                except:
                    pass
            if axis == 2:
                try:
                    vertice.co = (vertice.co.x, vertice.co.y,
                                  intersect_line_line(men, may, punto,
                                                      (punto[0], punto[1],
                                                       punto[2] + 1))[0][2] -
                                  mesh.location[2])
                except:
                    pass
    bmesh.update_edit_mesh(mesh.data)
def main(context, vaxis, gpAxis):
    axisdict = {"X": 0, "Y": 1, "Z": 2}
    mesh = bpy.context.object
    bm = bmesh.from_edit_mesh(mesh.data)
    axis = axisdict[vaxis]
    gpaxis = axisdict[gpAxis]
    for vertice in bm.verts:
        if vertice.select:
            imen = -1000
            imay = 1000
            punto = vertice.co + mesh.location
            jj = [point.co for point in bpy.context.object.grease_pencil.layers.active.frames[0].strokes[0].points]
            for point in bpy.context.object.grease_pencil.layers.active.frames[0].strokes[-1].points:
                if point.co[gpaxis] < punto[gpaxis] and point.co[gpaxis] > imen:
                    imen = point.co[gpaxis]
                    men = point.co
                if point.co[gpaxis] > punto[gpaxis] and point.co[gpaxis] < imay:
                    imay = point.co[gpaxis]
                    may = point.co
            try:
                may
                men
            except:
                print("wrong projection axis!")
                break

            if axis == 0:
                try:
                    vertice.co = (
                        intersect_line_line(men, may, punto, (punto[0] + 1, punto[1], punto[2]))[0][0]
                        - mesh.location[0],
                        vertice.co.y,
                        vertice.co.z,
                    )
                except:
                    pass
            if axis == 1:
                try:
                    vertice.co = (
                        vertice.co.x,
                        intersect_line_line(men, may, punto, (punto[0], punto[1] + 1, punto[2]))[0][1]
                        - mesh.location[1],
                        vertice.co.z,
                    )
                except:
                    pass
            if axis == 2:
                try:
                    vertice.co = (
                        vertice.co.x,
                        vertice.co.y,
                        intersect_line_line(men, may, punto, (punto[0], punto[1], punto[2] + 1))[0][2]
                        - mesh.location[2],
                    )
                except:
                    pass
    bmesh.update_edit_mesh(mesh.data)
        def make_corner_straight(bm, verts, p1, p2):
            v1 = verts[0]
            v2 = verts[1]

            face = get_face_with_verts(verts)
            if face is not None and len(face.edges) == 6:

                done = False
                loop_a = None
                loop_b = None
                for vert in verts:
                    face_loops = get_face_loops_for_vert(vert, face)
                    for loop in face_loops:
                        if loop.vert in verts:
                            loop_a = loop

                            if loop.link_loop_next.link_loop_next.vert in verts:
                                loop_b = loop.link_loop_next

                                done = True
                                break
                    if done:
                        break

                if loop_a is not None and loop_b is not None:
                    edge_a = loop_a.link_loop_prev.link_loop_prev.edge
                    edge_b = loop_b.link_loop_next.link_loop_next.edge

                    isect_point = intersect_line_line(p1, p2,
                                                      edge_b.verts[0].co,
                                                      edge_b.verts[1].co)
                    if isect_point is not None:
                        isect_point = isect_point[0]
                    else:
                        isect_point = intersect_line_line(
                            p1, p2, edge_a.verts[0].co, edge_a.verts[1].co)[0]

                    center_vert_co, _ = intersect_point_line(
                        v2.co, isect_point, v1.co)  #p1.lerp(p2, 0.5)

                    # Make the corner geometry
                    center_vert: BMVert = bm.verts.new(
                        center_vert_co
                    )  #bmesh.ops.create_vert(bm, co=center_vert_co)["vert"][0]
                    connect_vert = get_vertex_shared_by_edges([edge_a, edge_b])

                    new_edge_a = bm.edges.new([verts[0], center_vert])
                    new_edge_b = bm.edges.new([verts[1], center_vert])
                    new_edge_c = bm.edges.new([center_vert, connect_vert])

                    bmesh.utils.face_split_edgenet(
                        face, [new_edge_a, new_edge_b, new_edge_c])

                    bm.faces.ensure_lookup_table()
                    bm.edges.ensure_lookup_table()
                    bm.verts.ensure_lookup_table()
Example #4
0
def main(context):
    shape_ob = context.active_object

    sel_spl = [spl for spl in get_selected_bezier_splines(shape_ob) if not spl.use_cyclic_u]

    if sel_spl == None or len(sel_spl) == 0 or len(sel_spl) > 2:
        print ("wrong selection")
        return
    # case of one endpoint selected
    if len(sel_spl) == 1:
        sel_pts = selected_endpoints(sel_spl[0])
        if len(sel_pts) == 2:
            p1, p1_handle = sel_pts
            p1_extend = get_max_extent_2d(p1, p1_handle, get_shape_bounds(shape_ob))
            p2 = nearest_point(p1, get_intersections(p1, p1_extend, shape_ob))
        # case of two endpoints selected on the same spline
        elif len(sel_pts) == 4:
            p2 = intersect_line_line(sel_pts[1], sel_pts[0], sel_pts[3], sel_pts[2])[0]
        else:
            print ("wrong selection")
            return
    # case of two endpoints selected on seperate splines
    if len(sel_spl) == 2:
        sel_pts = selected_endpoints(sel_spl[0]) + selected_endpoints(sel_spl[1])
        p2 = intersect_line_line(sel_pts[1], sel_pts[0], sel_pts[3], sel_pts[2])[0]

    # add point to spline(s)
    if p2 == None:
        print ("no extension found")
    else:
        print ("extended point found on: ", p2)
        if len(sel_spl) == 1:
            if len(sel_pts) == 2:
                bpy.ops.curve.handle_type_set(type='ALIGNED')
                bpy.ops.curve.vertex_add(location=(p2.to_3d()+bpy.context.object.location))
                bpy.ops.curve.handle_type_set(type='AUTOMATIC')
            elif len(sel_pts) == 4:
                bpy.ops.curve.handle_type_set(type='ALIGNED')
                bpy.ops.curve.vertex_add()
                sel_spl[0].bezier_points[0].co = p2.to_3d()
                sel_spl[0].bezier_points[-1].co = p2.to_3d()
                bpy.ops.curve.handle_type_set(type='AUTOMATIC')
        elif len(sel_spl) == 2:
            bpy.ops.curve.handle_type_set(type='ALIGNED')
            bpy.ops.curve.vertex_add()
            if sel_spl[0].bezier_points[0].select_control_point:
                sel_spl[0].bezier_points[0].co = p2.to_3d()
            else:
                sel_spl[0].bezier_points[-1].co = p2.to_3d()
            if sel_spl[1].bezier_points[0].select_control_point:
                sel_spl[1].bezier_points[0].co = p2.to_3d()
            else:
                sel_spl[1].bezier_points[-1].co = p2.to_3d()
            bpy.ops.curve.handle_type_set(type='AUTOMATIC')
Example #5
0
def generate_3PT_mode_1(pts, obj, nv):
    origin = obj.location
    mw = obj.matrix_world
    V = Vector

    nv = max(3, nv)

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        cp = mw * p1
        bpy.context.scene.cursor_location = cp
        layer = get_layer()
        generate_gp3d_stroke(layer, p1, v1, axis, mw, origin, nv)
    else:
        print('not on a circle')
Example #6
0
File: qt_op.py Project: qrti/QTools
def sectEdges(self, context):
    obj = bpy.context.object

    if obj.mode != 'EDIT':
        self.report({"INFO"}, "Works in edit mode only")
        return

    me = obj.data
    bm = bmesh.from_edit_mesh(me)
    edges = [e for e in bm.edges if e.select]

    if len(edges) != 2:
        self.report({"INFO"}, "Select exactly two edges")
        return

    mytool = context.scene.my_tool

    [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]

    if v1 == v3 or v1 == v4 or v2 == v3 or v2 == v4:
        self.report({"INFO"}, "Edges are not independent")
        return

    iv = geometry.intersect_line_line(v1, v2, v3, v4)

    if not iv:
        self.report({"INFO"}, "Edges do not intersect")
        return

    iv = (iv[0] + iv[1]) / 2

    if not pointOnEdge(iv, v1, v2) or not pointOnEdge(iv, v3, v4):
        self.report({"WARNING"}, "Intersection not on edges")

    if mytool.delFaces:
        vn = bm.verts.new(iv)

        for e in edges:
            bm.edges.new((e.verts[0], vn))
            bm.edges.new((e.verts[1], vn))
            bm.edges.remove(e)

        bmesh.update_edit_mesh(me)

    elif mytool.keepFaces:
        fac = (iv - v1).length / (v2 - v1).length
        ev1 = bmesh.utils.edge_split(edges[0], edges[0].verts[0], fac)

        fac = (iv - v3).length / (v4 - v3).length
        ev2 = bmesh.utils.edge_split(edges[1], edges[1].verts[0], fac)

        bmesh.ops.pointmerge(bm, verts=(ev1[1], ev2[1]), merge_co=iv)
        bmesh.update_edit_mesh(me)

    elif mytool.addVertex:
        bm.verts.new(iv)
        bmesh.update_edit_mesh(me)

    if mytool.setCursor:
        context.scene.cursor.location = obj.matrix_world @ iv
Example #7
0
def xsect_spline(sp_a, sp_b, _hubs, precision):
    pt_a_prev = pt_b_prev = None
    EPS_SPLINE = min(sp_a.length, sp_b.length) / precision
    pt_a_prev = sp_a.points[0]
    for a, pt_a in enumerate(sp_a.points[1:]):
        pt_b_prev = sp_b.points[0]
        for b, pt_b in enumerate(sp_b.points[1:]):

            # Now we have 2 edges
            # print(pt_a, pt_a_prev, pt_b, pt_b_prev)
            xsect = intersect_line_line(pt_a, pt_a_prev, pt_b, pt_b_prev)
            if xsect is not None:
                if (xsect[0] - xsect[1]).length <= EPS_SPLINE:
                    f = intersect_point_line(xsect[1], pt_a, pt_a_prev)[1]
                    # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
                    # for some reason doesnt work so well, same below
                    if f >= 0.0 and f <= 1.0:
                        f = intersect_point_line(xsect[0], pt_b, pt_b_prev)[1]
                        # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
                        if f >= 0.0 and f <= 1.0:
                            # This wont happen often
                            co = xsect[0].lerp(xsect[1], 0.5)
                            hub = get_hub(co, _hubs, EPS_SPLINE)

                            sp_a.hubs.append((a, hub))
                            sp_b.hubs.append((b, hub))

            pt_b_prev = pt_b

        pt_a_prev = pt_a
Example #8
0
    def execute(self, context):
        BlenderFake.forceUpdate()
        obj = bpy.context.active_object
        mat = obj.matrix_world

        se = [e for e in obj.data.edges if (e.select == 1)]
        e1v1 = obj.data.vertices[se[0].vertices[0]].co
        e1v2 = obj.data.vertices[se[0].vertices[1]].co
        e2v1 = obj.data.vertices[se[1].vertices[0]].co
        e2v2 = obj.data.vertices[se[1].vertices[1]].co

        qq = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)

        q = None
        if len(qq)==0:
            #print ("lx 0")
            return {'CANCELLED'}

        if len(qq)==1:
            #print ("lx 1")
            q = qq[0]
        
        if len(qq)==2:
            cc = context.scene.cursor_control
            cc.cycleLinexCoice(2)
            q = qq[cc.linexChoice]

        #q = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)[qc] * mat
        #i2 = geometry.intersect_line_line (e2v1, e2v2, e1v1, e1v2)[0] * mat
        cc.setCursor(mat*q)
        return {'FINISHED'}
Example #9
0
def intersect_line_line(v1, v2, v3, v4, threshold=1e-6):
    """三次元での直線同士の交差判定。平行だった場合、中間地点を求める。
    二次元が与えられたら三次元に拡張する。
    parallel_threshold:
        平行であるとする閾値
    """
    v1 = v1.to_3d()
    v2 = v2.to_3d()
    v3 = v3.to_3d()
    v4 = v4.to_3d()
    vec1 = v2 - v1
    vec2 = v4 - v3

    # 両方点
    if vec1.length == 0.0 and vec2.length == 0.0:
        return None

    # v1-v2が直線、v3-v4が点
    elif vec2.length == 0.0:
        return (v3 - v1).project(vec1) + v1, v3

    # v1-v2が点、v3-v4が直線
    elif vec1.length == 0.0:
        return v1, (v1 - v3).project(vec2) + v3

    # 平行
    elif vec1.normalized().cross(v3 - v1).length < threshold and \
       vec1.normalized().cross(v4 - v1).length < threshold:
        d1 = vec1.dot(v3 - v1)
        d2 = vec1.dot(v4 - v1)
        if d1 > d2:
            d1, d2 = d2, d1
            v3, v4 = v4, v3
            vec2.negate()
        # v3,v4が両方v1側 or v3がv1側, v4がv1-v2間
        if d2 <= 0 or (d1 <= 0 and 0 <= d2 <= vec1.length):
            mid = (v1 + v4) / 2
        # v3,v4が両方v2側 or v3がv1-v2間, v4がv2側
        elif d1 >= vec1.length or \
           (0 <= d1 <= vec1.length and d2 >= vec1.length):
            mid = (v2 + v3) / 2
        # v3,v4がv1-v2間
        elif 0 <= d1 <= vec1.length and 0 <= d2 <= vec1.length:
            mid = (v2 + v3) / 2
        # v1,v2がv3-v4間
        else:
            mid = (v1 + v4) / 2
        isect1 = (mid - v1).project(vec1) + v1
        isect2 = (mid - v3).project(vec2) + v3
        return isect1, isect2

    else:
        result = geom.intersect_line_line(v1, v2, v3, v4)
        if result is not None:
            # isect1, isect2 = result
            # if not math.isnan(isect1[0]) and not math.isnan(isect2[0]):
            #     return isect1, isect2
            return result

    return None
 def closest_extrude_Point(self, p2D : Point2D) -> Point:
     r = self.drawing.Point2D_to_Ray(p2D)
     p,_ = intersect_line_line(
         self.extrude_pt0, self.extrude_pt1,
         r.o, r.o + r.d,
         )
     return Point(p)
Example #11
0
def angleEnlarge(c0, c1, c2, w):
    try:
        t = w[0]  # variable width
    except:
        w = [w, w]  # uniform offset
    c0 = Vector(c0)
    c1 = Vector(c1)
    c2 = Vector(c2)

    v0 = c1 - c0
    v1 = c2 - c1

    sz, rot = readVec(v0)
    b = writeVec(w[0], rot - 90)
    b = b + c0
    c = b + v0

    sz, rot = readVec(v1)
    d = writeVec(w[1], rot - 90)
    d = d + c1
    e = d + v1
    # TODO line_line always returns a tuple (never a None like line_2d)
    interlist = geometry.intersect_line_line(b, c, d, e)
    print(interlist)
    if type(interlist) != type(None):
        return interlist[0]
    else:
        return c
Example #12
0
    def execute(self, context):
        BlenderFake.forceUpdate()
        obj = bpy.context.active_object
        mat = obj.matrix_world

        se = [e for e in obj.data.edges if (e.select == 1)]
        e1v1 = obj.data.vertices[se[0].vertices[0]].co
        e1v2 = obj.data.vertices[se[0].vertices[1]].co
        e2v1 = obj.data.vertices[se[1].vertices[0]].co
        e2v2 = obj.data.vertices[se[1].vertices[1]].co

        qq = geometry.intersect_line_line(e1v1, e1v2, e2v1, e2v2)

        q = None
        if len(qq) == 0:
            #print ("lx 0")
            return {'CANCELLED'}

        if len(qq) == 1:
            #print ("lx 1")
            q = qq[0]

        if len(qq) == 2:
            cc = context.scene.cursor_control
            cc.cycleLinexCoice(2)
            q = qq[cc.linexChoice]

        #q = geometry.intersect_line_line (e1v1, e1v2, e2v1, e2v2)[qc] * mat
        #i2 = geometry.intersect_line_line (e2v1, e2v2, e1v1, e1v2)[0] * mat
        cc.setCursor(mat * q)
        return {'FINISHED'}
Example #13
0
def generate_3PT_mode_1_(pts, obj):
    origin = obj.location
    transform_matrix = obj.matrix_local
    V = Vector

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        # cp = transform_matrix * (p1 + origin)
        cp = transform_matrix * p1
        bpy.context.scene.cursor_location = cp
        # generate_gp3d_stroke(cp, axis, obj, radius=(p1-v1).length)
    else:
        print('not on a circle')
def generate_3PT_mode_1_(pts, obj):
    origin = obj.location
    transform_matrix = obj.matrix_local
    V = Vector

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        # cp = transform_matrix * (p1 + origin)
        cp = transform_matrix * p1
        bpy.context.scene.cursor_location = cp
        # generate_gp3d_stroke(cp, axis, obj, radius=(p1-v1).length)
    else:
        print('not on a circle')
Example #15
0
def solve_curvature(p1, p2, n1, n2, fac, fallback):
    """ Add a nice circular curvature on
    """
    from mathutils.geometry import (intersect_line_line,
                                    )

    p1_a = p1 + n1
    p2_a = p2 - n2

    isect = intersect_line_line(p1,
                                p1_a,
                                p2,
                                p2_a,
                                )

    if isect:
        corner = isect[0].lerp(isect[1], 0.5)
    else:
        corner = None

    if corner:
        p1_first_order = p1.lerp(corner, fac)
        p2_first_order = corner.lerp(p2, fac)
        co = p1_first_order.lerp(p2_first_order, fac)

        return co
    else:
        # cant interpolate. just return interpolated value
        return fallback.copy()  # p1.lerp(p2, fac)
Example #16
0
def get_new_position(position_vectors, source):

    source_points = np.array(source.points)
    x_min = np.min(source_points[:, 0])
    x_max = np.max(source_points[:, 0])

    y_min = np.min(source_points[:, 1])
    y_max = np.max(source_points[:, 1])

    z_min = np.min(source_points[:, 2])
    z_max = np.max(source_points[:, 2])

    source_center = np.array(source.get_center())
    my_source_center = np.array([x_min + (x_max - x_min) / 2,
                                 y_min + (y_max - y_min) / 2,
                                 z_min + (z_max - z_min) / 2])

    shift2mycenter = np.subtract(source_center, my_source_center)

    print('my_source_center: {}'.format(my_source_center))
    print('diff from source of: {}'.format(shift2mycenter))

    points = []
    for i, line0 in enumerate(position_vectors[:-1]):
        for line1 in position_vectors[i+1:]:
            p0, p1 = intersect_line_line(line0[0], line0[1], line1[0], line1[1])
            p0 = np.array(p0)
            p1 = np.array(p1)
            center_point = p0 + (np.subtract(p1, p0)/2)
            points.append(center_point)
    points = np.array(points)
    position = np.mean(points, axis=0)
    position = position+shift2mycenter

    return position
Example #17
0
def getIntersection(pointsLeft, pointsRight):
    pL = np.array(pointsLeft)
    pR = np.array(pointsRight)

    camCenterRight = np.transpose(camWorldCenterRight)[0]
    camCenterLeft = np.transpose(camWorldCenterLeft)[0]

    # calcul du point sur l'object en applicant la pseudo-inverse de la camera sur le point trouvé plus-haut

    leftObject = (np.linalg.pinv(camLeft) @ pL)
    rightObject = (np.linalg.pinv(camRight) @ pR)

    # conversion des np.array en mathutils.Vector pour l'utilisation de la methode d'intersection

    leftEndVec = arrayToVector(leftObject)
    rightEndVec = arrayToVector(rightObject)

    leftStartVec = arrayToVector(camCenterLeft)
    rightStartVec = arrayToVector(camCenterRight)

    # affichage des lignes reliant centre à point objet

    '''
    draw3DLine(camCenterLeft,leftObject)
    draw3DLine(camCenterRight,rightObject)
    plt.show()
    '''

    # utilisation de mathutils.geometry.intersect_line_line pour trouver l'intersection des lingnes passant par les 2
    # points.
    return pygeo.intersect_line_line(leftStartVec, leftEndVec, rightStartVec, rightEndVec)
Example #18
0
def generate_3PT(pts, obj, nv, mode=1):
    mw = obj.matrix_world
    V = Vector
    nv = max(3, nv)

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        cp = mw * p1
        bpy.context.scene.cursor_location = cp

        if mode == 0:
            pass

        elif mode == 1:
            generate_bmesh_repr(p1, v1, axis, nv)

    else:
        print('not on a circle')
Example #19
0
def xsect_spline(sp_a, sp_b, _hubs, precision):
    pt_a_prev = pt_b_prev = None
    EPS_SPLINE = min(sp_a.length, sp_b.length) / precision
    pt_a_prev = sp_a.points[0]
    for a, pt_a in enumerate(sp_a.points[1:]):
        pt_b_prev = sp_b.points[0]
        for b, pt_b in enumerate(sp_b.points[1:]):

            # Now we have 2 edges
            # print(pt_a, pt_a_prev, pt_b, pt_b_prev)
            xsect = intersect_line_line(pt_a, pt_a_prev, pt_b, pt_b_prev)
            if xsect is not None:
                if (xsect[0] - xsect[1]).length <= EPS_SPLINE:
                    f = intersect_point_line(xsect[1], pt_a, pt_a_prev)[1]
                    # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
                        # for some reason doesnt work so well, same below
                    if f >= 0.0 and f <= 1.0:
                        f = intersect_point_line(xsect[0], pt_b, pt_b_prev)[1]
                        # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
                        if f >= 0.0 and f <= 1.0:
                            # This wont happen often
                            co = xsect[0].lerp(xsect[1], 0.5)
                            hub = get_hub(co, _hubs, EPS_SPLINE)

                            sp_a.hubs.append((a, hub))
                            sp_b.hubs.append((b, hub))

            pt_b_prev = pt_b

        pt_a_prev = pt_a
Example #20
0
def generate_3PT(pts, obj, nv, mode=1):
    mw = obj.matrix_world
    V = Vector
    nv = max(3, nv)

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        cp = mw * p1
        bpy.context.scene.cursor_location = cp

        if mode == 0:
            pass

        elif mode == 1:
            generate_bmesh_repr(p1, v1, axis, nv)

    else:
        print('not on a circle')
Example #21
0
def solve_curvature(p1, p2, n1, n2, fac, fallback):
    """ Add a nice circular curvature on
    """
    from mathutils.geometry import (
        intersect_line_line, )

    p1_a = p1 + n1
    p2_a = p2 - n2

    isect = intersect_line_line(
        p1,
        p1_a,
        p2,
        p2_a,
    )

    if isect:
        corner = isect[0].lerp(isect[1], 0.5)
    else:
        corner = None

    if corner:
        p1_first_order = p1.lerp(corner, fac)
        p2_first_order = corner.lerp(p2, fac)
        co = p1_first_order.lerp(p2_first_order, fac)

        return co
    else:
        # cant interpolate. just return interpolated value
        return fallback.copy()  # p1.lerp(p2, fac)
Example #22
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
Example #23
0
    def get_slide_vector_intersection(self, context):
        view_origin = region_2d_to_origin_3d(context.region, context.region_data, self.mousepos)
        view_dir = region_2d_to_vector_3d(context.region, context.region_data, self.mousepos)

        i = intersect_line_line(view_origin, view_origin + view_dir, self.origin, self.target_avg)

        return i[1]
Example #24
0
def angleEnlarge(c0, c1, c2, w):
    try:
        t = w[0]  # variable width
    except:
        w = [w, w]  # uniform offset
    c0 = Vector(c0)
    c1 = Vector(c1)
    c2 = Vector(c2)

    v0 = c1 - c0
    v1 = c2 - c1

    sz, rot = readVec(v0)
    b = writeVec(w[0], rot - 90)
    b = b + c0
    c = b + v0

    sz, rot = readVec(v1)
    d = writeVec(w[1], rot - 90)
    d = d + c1
    e = d + v1
    # TODO line_line always returns a tuple (never a None like line_2d)
    interlist = geometry.intersect_line_line(b, c, d, e)
    print(interlist)
    if type(interlist) != type(None):
        return interlist[0]
    else:
        return c
Example #25
0
    def slide_snap(self, context, hitobj, hitlocation, hitindex):
        '''
        slide snap to edges of all edit mode objects
        '''

        # get hitface from the cached bmesh
        hitbm = self.snap_bms[hitobj.name]
        hitface = hitbm.faces[hitindex]

        # hit location in hitobj's local space
        hitmx = hitobj.matrix_world
        hit = hitmx.inverted() @ hitlocation

        # get closest edge
        edge = min([(e, (hit - intersect_point_line(hit, e.verts[0].co, e.verts[1].co)[0]).length, (hit - get_center_between_verts(*e.verts)).length) for e in hitface.edges], key=lambda x: (x[1] * x[2]) / x[0].calc_length())[0]

        # set snap coords for view3d drawing
        self.snap_coords = [hitmx @ v.co for v in edge.verts]

        # get snap coords in active's local space
        snap_coords = [self.mx.inverted_safe() @ co for co in self.snap_coords]

        # init proximity and ortho coords for view3d drawing
        self.snap_proximity_coords = []
        self.snap_ortho_coords = []

        # get intersection of individual slide dirs and snap coords
        for v, data in self.verts.items():
            init_co = data['co']
            target = data['target']

            snap_dir = (snap_coords[0] - snap_coords[1]).normalized()
            slide_dir = (init_co - target.co).normalized()

            # check for parallel and almost parallel snap edges, do nothing in this case
            if abs(slide_dir.dot(snap_dir)) > 0.999:
                v.co = init_co

            # with a smaller dot product, interseect_line_line will produce a guaranteed hit
            else:
                i = intersect_line_line(init_co, target.co, *snap_coords)

                v.co = i[1 if self.is_diverging else 0] if i else init_co

                # add coords to draw the slide 'edges'
                if v.co != target.co:
                    self.coords.extend([v.co, target.co])

                # add proximity coords
                if i[1] != snap_coords[0]:
                    self.snap_proximity_coords.extend([i[1], snap_coords[0]])

                # add ortho coords
                if v.co != i[1]:
                    self.snap_ortho_coords.extend([v.co, i[1]])


        self.bm.normal_update()
        bmesh.update_edit_mesh(self.active.data)
    def __init__(self, wall, o):
        self.wall = wall
        self.o = o
        # get neighbor EMPTYs for <o>
        o2 = wall.getCornerEmpty(o)
        self.o2 = o2
        o1 = wall.getPrevious(o2)
        self.o1 = o1

        context = wall.context
        # temporarily remove drivers for the segment EMPTY object
        o.driver_remove("location")

        # get neighbor EMPTYs for <o1> and <o2>
        e1 = wall.getPrevious(o1)
        attached1 = None if e1 else wall.getReferencesForAttached(o1)
        self.attached1 = attached1
        e2 = wall.getNext(o2)
        attached2 = None if e2 else wall.getReferencesForAttached(o2)
        self.attached2 = attached2
        # vectors
        if e1:
            v1 = o1.location - e1.location
        elif attached1:
            v1 = attached1[1].location - attached1[0].location
        if e2:
            v2 = e2.location - o2.location
        elif attached2:
            v2 = attached2[1].location - attached2[0].location

        p = None
        if (e1 or attached1) and (e2 or attached2):
            # check if v1 and v2 are parallel
            if v1.normalized().cross(v2.normalized()).length < zero2:
                # orient <o> along v1, which gives the same effect as orienting <o> along v2
                dy, dx = v1.y, v1.x
            else:
                # point where the lines defined by v1 and v2 intersect
                l1 = (e1, o1) if e1 else attached1
                l2 = (o2, e2) if e2 else attached2
                p = intersect_line_line(l1[0].location, l1[1].location,
                                        l2[0].location, l2[1].location)[0]
                # orient <o> along the line defined by <o> and <p>
                dy, dx = o.location.y - p.y, o.location.x - p.x
        elif e1 or attached1 or e2 or attached2:
            _v = v1 if e1 or attached1 else v2
            # orient <o> along <_v>
            dy, dx = _v.y, _v.x
        else:
            # orient <o> along the normal to the wall segment defined by <o>
            dy, dx = o1.location.x - o2.location.x, o2.location.y - o1.location.y

        o.rotation_euler[2] = math.atan2(dy, dx)
        context.scene.update()
        # adding drivers for o1 and o2
        addMoverDrivers(o1, o, p)
        addMoverDrivers(o2, o, p)

        makeActiveSelected(context, o)
 def orthoCenter(cls, fv):
     try:
         h0 = G3.closestP2L(fv[0], fv[1], fv[2])
         h1 = G3.closestP2L(fv[1], fv[0], fv[2])
         #h2 = G3.closestP2L(fm[2], fm[0], fm[1])
         return geometry.intersect_line_line(fv[0], h0, fv[1], h1)[0]
     except (RuntimeError, TypeError):
         return None
 def orthoCenter(cls, fv):
     try:
         h0 = G3.closestP2L(fv[0], fv[1], fv[2])
         h1 = G3.closestP2L(fv[1], fv[0], fv[2])
         #h2 = G3.closestP2L(fm[2], fm[0], fm[1])
         return geometry.intersect_line_line (fv[0], h0, fv[1], h1)[0]
     except(RuntimeError, TypeError):
         return None
 def __init__(self, wall, o):
     self.wall = wall
     self.o = o
     # get neighbor EMPTYs for <o>
     o2 = wall.getCornerEmpty(o)
     self.o2 = o2
     o1 = wall.getPrevious(o2)
     self.o1 = o1
     
     context = wall.context
     # temporarily remove drivers for the segment EMPTY object
     o.driver_remove("location")
     
     # get neighbor EMPTYs for <o1> and <o2>
     e1 = wall.getPrevious(o1)
     attached1 = None if e1 else wall.getReferencesForAttached(o1)
     self.attached1 = attached1
     e2 = wall.getNext(o2)
     attached2 = None if e2 else wall.getReferencesForAttached(o2)
     self.attached2 = attached2
     # vectors
     if e1:
         v1 = o1.location - e1.location
     elif attached1:
         v1 = attached1[1].location - attached1[0].location
     if e2:
         v2 = e2.location - o2.location
     elif attached2:
         v2 = attached2[1].location - attached2[0].location
     
     p = None
     if (e1 or attached1) and (e2 or attached2):
         # check if v1 and v2 are parallel
         if v1.normalized().cross(v2.normalized()).length < zero2:
             # orient <o> along v1, which gives the same effect as orienting <o> along v2
             dy, dx = v1.y, v1.x
         else:
             # point where the lines defined by v1 and v2 intersect
             l1 = (e1, o1) if e1 else attached1
             l2 = (o2, e2) if e2 else attached2
             p = intersect_line_line(l1[0].location, l1[1].location, l2[0].location, l2[1].location)[0]
             # orient <o> along the line defined by <o> and <p>
             dy, dx = o.location.y-p.y, o.location.x-p.x
     elif e1 or attached1 or e2 or attached2:
         _v = v1 if e1 or attached1 else v2
         # orient <o> along <_v>
         dy, dx = _v.y, _v.x
     else:
         # orient <o> along the normal to the wall segment defined by <o>
         dy, dx = o1.location.x-o2.location.x, o2.location.y-o1.location.y
     
     o.rotation_euler[2] = math.atan2(dy, dx)
     context.scene.update()
     # adding drivers for o1 and o2
     addMoverDrivers(o1, o, p)
     addMoverDrivers(o2, o, p)
     
     makeActiveSelected(context, o)
Example #30
0
def getIntersection(x, y):
    BMEdge = bmesh.types.BMEdge
    x1, x2 = (x.verts[0].co, x.verts[1].co) if isinstance(x, BMEdge) else (x[0], x[1])
    y1, y2 = (y.verts[0].co, y.verts[1].co) if isinstance(y, BMEdge) else (y[0], y[1])
    if angle_2vec3(x1-x2, y1-y2) < 0.002:
        return None
    else:
        vec = geometry.intersect_line_line(x1, x2, y1, y2)
        return (vec[0] + vec[1]) / 2
Example #31
0
    def make_corner_alt(self, bm, verts, fac=0.5):
        face = get_face_with_verts(verts)
        if face is not None and len(face.edges) == 6:

            done = False
            loop_a = None
            loop_b = None
            for vert in verts:
                face_loops = get_face_loops_for_vert(vert, face)
                for loop in face_loops:
                    if loop.vert in verts:
                        loop_a = loop

                        if loop.link_loop_next.link_loop_next.vert in verts:
                            loop_b = loop.link_loop_next

                            done = True
                            break
                if done:
                    break

            if loop_a is not None and loop_b is not None:
                edge_a = loop_a.link_loop_prev.link_loop_prev.edge
                edge_b = loop_b.link_loop_next.link_loop_next.edge
                vert_a = loop_a.vert
                vert_b = loop_b.edge.other_vert(loop_b.vert)

                edge_a_point, _ = intersect_point_line(vert_b.co,
                                                       edge_a.verts[0].co,
                                                       edge_a.verts[1].co)
                edge_b_point, _ = intersect_point_line(vert_a.co,
                                                       edge_b.verts[0].co,
                                                       edge_b.verts[1].co)

                isect_point = intersect_line_line(edge_a_point, vert_b.co,
                                                  edge_b_point, vert_a.co)
                if isect_point is not None:
                    center_vert_co = isect_point[0]
                    shared_vert = get_vertex_shared_by_edges(
                        [loop_a.edge, loop_b.edge])
                    connect_vert = get_vertex_shared_by_edges([edge_a, edge_b])
                    center_vert_co = center_vert_co.lerp(connect_vert.co, fac)

                    # Make the corner geometry
                    center_vert: BMVert = bmesh.ops.create_vert(
                        bm, co=center_vert_co)["vert"][0]

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

                    new_edge_a = bm.edges.new([vert_a, center_vert])
                    new_edge_b = bm.edges.new([vert_b, center_vert])
                    new_edge_c = bm.edges.new([center_vert, connect_vert])

                    bmesh.utils.face_split_edgenet(
                        face, [new_edge_a, new_edge_b, new_edge_c])
Example #32
0
def getIntersection(x, y):
    BMEdge = bmesh.types.BMEdge
    x1, x2 = (x.verts[0].co,
              x.verts[1].co) if isinstance(x, BMEdge) else (x[0], x[1])
    y1, y2 = (y.verts[0].co,
              y.verts[1].co) if isinstance(y, BMEdge) else (y[0], y[1])
    if angle_2vec3(x1 - x2, y1 - y2) < 0.002:
        return None
    else:
        vec = geometry.intersect_line_line(x1, x2, y1, y2)
        return (vec[0] + vec[1]) / 2
Example #33
0
    def grad_f_ed(ed, p, last_face):

        #walk around non manifold edges
        if len(ed.link_faces) == 1:
            minv = min(ed.verts, key = geos.get)
            return minv.co, minv, None


        f = [fc for fc in ed.link_faces if fc !=last_face][0]
        g = gradient_face(f, geos)
        L = f.calc_perimeter()


        #test for vert intersection
        for v in f.verts:
            v_inter, pct = intersect_point_line(v.co, p, p-L*g)

            delta = v.co - v_inter
            if delta.length < epsilon:
                print('intersect vert')
                return v.co, v, None

        tests = [e for e in f.edges if e != ed]

        for e in tests:

            v0, v1 = intersect_line_line(e.verts[0].co, e.verts[1].co, p, p-L*g)

            V = v0 - e.verts[0].co
            edV = e.verts[1].co - e.verts[0].co
            Vi = v0 - p

            if V.length - edV.length > epsilon:
                #print('intersects outside segment')
                continue
            elif V.dot(edV) < 0:
                #print('intersects behind')
                continue

            elif Vi.dot(g) > 0:  #remember we watnt to travel DOWN the gradient

                #print('shoots out the face, not across the face')
                continue

            else:

                #print('regular face edge crossing')
                return v0, e, f

        #we didn't intersect across an edge, or on a vert,
        #therefore, we should travel ALONG the edge

        vret = min(ed.verts, key = geos.get)
        return vret.co, vret, None
Example #34
0
    def grad_f_ed(ed, p, last_face):

        # walk around non manifold edges
        if len(ed.link_faces) == 1:
            minv = min(ed.verts, key=geos.get)
            return minv.co, minv, None

        f = [fc for fc in ed.link_faces if fc != last_face][0]
        g = gradient_face(f, geos)
        L = f.calc_perimeter()

        # test for vert intersection
        for v in f.verts:
            v_inter, pct = intersect_point_line(v.co, p, p - L * g)

            delta = v.co - v_inter
            if delta.length < epsilon:
                print("intersect vert")
                return v.co, v, None

        tests = [e for e in f.edges if e != ed]

        for e in tests:

            v0, v1 = intersect_line_line(e.verts[0].co, e.verts[1].co, p, p - L * g)

            V = v0 - e.verts[0].co
            edV = e.verts[1].co - e.verts[0].co
            Vi = v0 - p

            if V.length - edV.length > epsilon:
                # print('intersects outside segment')
                continue
            elif V.dot(edV) < 0:
                # print('intersects behind')
                continue

            elif Vi.dot(g) > 0:  # remember we watnt to travel DOWN the gradient

                # print('shoots out the face, not across the face')
                continue

            else:

                # print('regular face edge crossing')
                return v0, e, f

        # we didn't intersect across an edge, or on a vert,
        # therefore, we should travel ALONG the edge

        vret = min(ed.verts, key=geos.get)
        return vret.co, vret, None
Example #35
0
 def persp_fac_to_world_fac(self, fac, inverted_perspective_matrix, v1, v2):
     """v1,v2はpersp座標"""
     v3 = v1 + (v2 - v1) * fac
     v4 = v3.copy()
     v3[2] = 0.0
     v4[2] = 0.5
     vec1 = mul_persp(inverted_perspective_matrix, v1)
     vec2 = mul_persp(inverted_perspective_matrix, v2)
     vec3 = mul_persp(inverted_perspective_matrix, v3)
     vec4 = mul_persp(inverted_perspective_matrix, v4)
     i1, i2 = geo.intersect_line_line(vec1, vec2, vec3, vec4)
     vec12 = vec2 - vec1
     return vec12.dot(i1 - vec1) / vec12.length ** 2
Example #36
0
def add_vertex_to_intersection(bm, edges):
    bm_deselect_all(bm)
    if len(edges) == 2:
        [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]

        iv = geometry.intersect_line_line(v1, v2, v3, v4)
        if iv:
            iv = (iv[0] + iv[1]) / 2
            bm.verts.new(iv)

            bm.verts.ensure_lookup_table()

            bm.verts[-1].select = True
Example #37
0
 def persp_fac_to_world_fac(self, fac, inverted_perspective_matrix, v1, v2):
     """v1,v2はpersp座標"""
     v3 = v1 + (v2 - v1) * fac
     v4 = v3.copy()
     v3[2] = 0.0
     v4[2] = 0.5
     vec1 = mul_persp(inverted_perspective_matrix, v1)
     vec2 = mul_persp(inverted_perspective_matrix, v2)
     vec3 = mul_persp(inverted_perspective_matrix, v3)
     vec4 = mul_persp(inverted_perspective_matrix, v4)
     i1, i2 = geo.intersect_line_line(vec1, vec2, vec3, vec4)
     vec12 = vec2 - vec1
     return vec12.dot(i1 - vec1) / vec12.length ** 2
Example #38
0
def line_from_edge_intersect(edge1, edge2):
    """Get New Line from Intersections.

    Prepares input for sending to intersect_line_line

    Args:
        edge1, edge2: tuples containing 2 vectors.

    Returns:
        Output of intersect_line_line.
    """

    [p1, p2], [p3, p4] = edge1, edge2
    return intersect_line_line(p1, p2, p3, p4)
Example #39
0
def createOutline(curve, outline):

    for spline in curve.data.splines[:]:
        p = spline.bezier_points
        out = []

        n = ((p[0].handle_right - p[0].co).normalized() -
             (p[0].handle_left - p[0].co).normalized()).normalized()
        n = Vector((-n[1], n[0], n[2]))
        o = p[0].co + outline * n
        out.append(o)

        for i in range(1, len(p)):
            n = ((p[i].handle_right - p[i].co).normalized() -
                 (p[i].handle_left - p[i].co).normalized()).normalized()
            n = Vector((-n[1], n[0], n[2]))
            o = intersect_line_line(out[-1], (out[-1] + p[i].co - p[i - 1].co),
                                    p[i].co, p[i].co + n)[0]
            out.append(o)

        curve.data.splines.new('BEZIER')
        if spline.use_cyclic_u:
            curve.data.splines[-1].use_cyclic_u = True
        p_out = curve.data.splines[-1].bezier_points
        p_out.add(len(out) - 1)

        for i in range(len(out)):
            p_out[i].handle_left_type = 'FREE'
            p_out[i].handle_right_type = 'FREE'

            p_out[i].co = out[i]

            if i < len(out) - 1:
                l = (p[i + 1].co - p[i].co).length
                l2 = (out[i] - out[i + 1]).length

            if i == 0:
                p_out[i].handle_left = out[i] + (
                    (p[i].handle_left - p[i].co) * l2 / l)
            if i < len(out) - 1:
                p_out[i + 1].handle_left = out[i + 1] + (
                    (p[i + 1].handle_left - p[i + 1].co) * l2 / l)
            p_out[i].handle_right = out[i] + (
                (p[i].handle_right - p[i].co) * l2 / l)

        for i in range(len(p)):
            p_out[i].handle_left_type = p[i].handle_left_type
            p_out[i].handle_right_type = p[i].handle_right_type

    return
Example #40
0
def generate_3PT_mode_1(pts=None, num_verts=20, make_edges=False):
    '''
    Arc from start - throught - Eend
    - call this function only if you have 3 pts,
    - do your error checking before passing to it.
    '''
    num_verts -= 1
    verts, edges = [], []
    V = Vector

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        # do arc
        p1, _ = r

        # find arc angle.
        a = (v1 - p1).angle((v4 - p1), 0)
        s = (2 * math.pi) - a

        interior_angle = (v1 - v2).angle(v4 - v3, 0)
        if interior_angle > 0.5 * math.pi:
            s = math.pi + 2 * (0.5 * math.pi - interior_angle)

        for i in range(num_verts + 1):
            mat_rot = mathutils.Matrix.Rotation(((s / num_verts) * i), 4, axis)
            vec = ((v4 - p1) * mat_rot) + p1
            verts.append(vec[:])
    else:
        # do straight line
        step_size = 1 / num_verts
        verts = [v1_.lerp(v4_, i * step_size)[:] for i in range(num_verts + 1)]

    if make_edges:
        edges = [(n, n + 1) for n in range(len(verts) - 1)]

    return verts, edges
Example #41
0
    def grad_v(v):
        '''
        walk down from a vert
        '''

        eds = [ed for ed in v.link_edges if geos[ed.other_vert(v)] <= geos[v]]
        if len(eds) == 0:
            print('lowest vert or local minima')
            return None, None, None

        fs = set()

        for ed in eds:
            fs.update(ed.link_faces)

        minf = min(fs, key=lambda x: sum([geos[vrt] for vrt in x.verts]))

        for ed in minf.edges:
            if v not in ed.verts:
                g = gradient_face(minf, geos)
                L = minf.calc_perimeter()

                v0, v1 = intersect_line_line(ed.verts[0].co, ed.verts[1].co,
                                             v.co, v.co - L * g)

                V = v0 - ed.verts[0].co
                edV = ed.verts[1].co - ed.verts[0].co
                if V.length - edV.length > epsilon:
                    continue
                    #print('intersects outside segment')
                elif V.dot(edV) < 0:

                    #print('intersects behind')
                    continue
                else:
                    #print('regular edge crossing')

                    return v0, ed, minf

        #we were not able to walk through a face
        print('must walk on edge')
        vs = [ed.other_vert(v) for ed in eds]
        minv = min(vs, key=geos.get)

        if geos[minv] > geos[v]:
            print('Found smallest geodesic already')
            return None, None, None

        return minv.co, minv, None
Example #42
0
def generate_3PT_mode_1(pts=None, num_verts=20, make_edges=False):
    '''
    Arc from start - throught - Eend
    - call this function only if you have 3 pts,
    - do your error checking before passing to it.
    '''
    num_verts -= 1
    verts, edges = [], []
    V = Vector

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        # do arc
        p1, _ = r

        # find arc angle.
        a = (v1 - p1).angle((v4 - p1), 0)
        s = (2 * math.pi) - a

        interior_angle = (v1 - v2).angle(v4 - v3, 0)
        if interior_angle > 0.5 * math.pi:
            s = math.pi + 2 * (0.5 * math.pi - interior_angle)

        for i in range(num_verts + 1):
            mat_rot = mathutils.Matrix.Rotation(((s / num_verts) * i), 4, axis)
            vec = ((v4 - p1) * mat_rot) + p1
            verts.append(vec[:])
    else:
        # do straight line
        step_size = 1 / num_verts
        verts = [v1_.lerp(v4_, i * step_size)[:] for i in range(num_verts + 1)]

    if make_edges:
        edges = [(n, n + 1) for n in range(len(verts) - 1)]

    return verts, edges
Example #43
0
def center_of_circumscribed_circle_tri(v1, v2, v3):
    """三角形の外接円の中心点を求める"""
    if v1 != v2 and v2 != v3 and v3 != v1:
        # 垂直二等分線の交差点を求める
        v12 = v2 - v1
        v13 = v3 - v1
        med12 = (v1 + v2) / 2
        med13 = (v1 + v3) / 2
        per12 = v13 - v13.project(v12)
        per13 = v12 - v12.project(v13)
        inter = geom.intersect_line_line(med12, med12 + per12,
                                        med13, med13 + per13)
        if inter:
            return (inter[0] + inter[1]) / 2
    return None
def add_vertex_to_intersection():

    obj = bpy.context.object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)

    edges = [e for e in bm.edges if e.select]

    if len(edges) == 2:
        [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]

        iv = geometry.intersect_line_line(v1, v2, v3, v4)
        iv = (iv[0] + iv[1]) / 2
        bm.verts.new(iv)
        bmesh.update_edit_mesh(me)
Example #45
0
def get_intersection_dictionary(cm, bm, edge_indices):

    bm.verts.ensure_lookup_table()
    bm.edges.ensure_lookup_table()

    permutations = get_valid_permutations(cm, bm, edge_indices)

    k = defaultdict(list)
    d = defaultdict(list)

    for edges in permutations:
        vert_vectors = cm.vectors_from_edges_tuple(bm, edges)
        v1, v2, v3, v4 = vert_vectors

        # Edges obviously can not intersect if their bounding
        # boxes do not intersect
        if (max(v1.x, v2.x) < min(v3.x, v4.x) or
            max(v1.y, v2.y) < min(v3.y, v4.y) or
            max(v1.z, v2.z) < min(v3.z, v4.z)):
                continue
        if (max(v3.x, v4.x) < min(v1.x, v2.x) or
            max(v3.y, v4.y) < min(v1.y, v2.y) or
            max(v3.z, v4.z) < min(v1.z, v2.z)):
                continue

        # Edges can not intersect if they do not lie in
        # the same plane
        if not cm.is_coplanar(vert_vectors):
            continue

        points = intersect_line_line(*vert_vectors)

        # some can be skipped.    (NaN, None, not on both edges)
        if can_skip(cm, points, vert_vectors):
            continue

        # reaches this point only when an intersection happens on both edges.
        [k[edge].append(points[0]) for edge in edges]

    # k will contain a dict of edge indices and points found on those edges.
    for edge_idx, unordered_points in k.items():
        tv1, tv2 = bm.edges[edge_idx].verts
        v1 = bm.verts[tv1.index].co
        v2 = bm.verts[tv2.index].co
        ordered_points = order_points((v1, v2), unordered_points)
        d[edge_idx].extend(ordered_points)

    return d
Example #46
0
    def grad_v(v):
        """
        walk down from a vert
        """

        eds = [ed for ed in v.link_edges if geos[ed.other_vert(v)] <= geos[v]]
        if len(eds) == 0:
            print("lowest vert or local minima")
            return None, None, None

        fs = set()

        for ed in eds:
            fs.update(ed.link_faces)

        minf = min(fs, key=lambda x: sum([geos[vrt] for vrt in x.verts]))

        for ed in minf.edges:
            if v not in ed.verts:
                g = gradient_face(minf, geos)
                L = minf.calc_perimeter()

                v0, v1 = intersect_line_line(ed.verts[0].co, ed.verts[1].co, v.co, v.co - L * g)

                V = v0 - ed.verts[0].co
                edV = ed.verts[1].co - ed.verts[0].co
                if V.length - edV.length > epsilon:
                    continue
                    # print('intersects outside segment')
                elif V.dot(edV) < 0:

                    # print('intersects behind')
                    continue
                else:
                    # print('regular edge crossing')

                    return v0, ed, minf

        # we were not able to walk through a face
        print("must walk on edge")
        vs = [ed.other_vert(v) for ed in eds]
        minv = min(vs, key=geos.get)

        if geos[minv] > geos[v]:
            print("Found smallest geodesic already")
            return None, None, None

        return minv.co, minv, None
 def centerOfSphere(cls, fv):
     try:
         if len(fv)==3:
             return G3.circumCenter(fv) # Equator
         if len(fv)==4:
             fv3 = [fv[0],fv[1],fv[2]]
             c1 = G3.circumCenter(fv)
             n1 = G3.ThreePnormal(fv)
             fv3 = [fv[1],fv[2],fv[3]]
             c2 = G3.circumCenter(fv3)
             n2 = G3.ThreePnormal(fv3)
             d1 = c1+n1
             d2 = c2+n2
             return geometry.intersect_line_line (c1, d1, c2, d2)[0]
     except(RuntimeError, TypeError):
         return None
Example #48
0
def SegmentIntersect(A, B, C, D, point=True, more=False, pdeb=False):

    A, B, C, D = Vectors([A, B, C, D])
    # "l,dAB=readVec(B-A)
    # l,dBA=readVec(A-B)
    # l,dCD=readVec(D-C)
    dec = 0.03
    # if cfloat(dAB,'not',dCD,dec) and cfloat(dBA,'not',dCD,dec) :
    if parallel(A, B, C, D, False) == False:
        if (signedarea(A, B, C) * signedarea(A, B, D) <= 0) and (signedarea(C, D, A) * signedarea(C, D, B) <= 0):
            # inter=LineIntersect(A,B,C,D)
            inter = geometry.intersect_line_line(A, B, C, D)
            # if (AB)=(CD) : return none
            # if type(inter)!=type(tuple()) :
            #    if pdeb :print 'nonetype'
            #    return False
            # if (AB)=(CD) bis : return -1.#IND
            # elif str(inter[0][0])=='-1.#IND' :
            #    if pdeb :print '-1#IND'
            #    return False

            # if (AB)=(CD) : return none
            if type(inter) != type(tuple()) or str(inter[0][0]) == "nan":
                if pdeb:
                    dprint("parrallel")
                return False
            # inter is equal to A,B,C or D : shall we include them ?
            elif point == False and (
                cfloat(inter[0], "eq", A, dec)
                or cfloat(inter[0], "eq", B, dec)
                or cfloat(inter[0], "eq", C, dec)
                or cfloat(inter[0], "eq", D, dec)
            ):
                if pdeb:
                    dprint("canceled : %s is an extremity" % inter[0])
                return False
            # ok
            else:
                return inter
        elif pdeb:
            dprint("segments")
    # segments doesn't cross ( parralel or merged )
    elif more:
        if pdeb:
            dprint("parallels")
        return False, True
    return False
Example #49
0
def generate_3PT_mode_1(pts, obj, nv):
    origin = obj.location
    mw = obj.matrix_world
    V = Vector

    nv = max(3, nv)

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        cp = mw * p1
        bpy.context.scene.cursor_location = cp
        layer = get_layer()
        generate_gp3d_stroke(layer, p1, v1, axis, mw, origin, nv)

        ''' 
        # f = [i for i in dir(bpy.context) if 'gpencil' in i]
        active_gpencil_frame
        active_gpencil_layer
        editable_gpencil_layers
        editable_gpencil_strokes
        gpencil_data
        gpencil_data_owner
        visible_gpencil_layers
        '''
        
        #bpy.context.active_gpencil_layer = layer
        #print(bpy.context.gpencil_data)
        scn = bpy.context.scene
        scn.grease_pencil = bpy.data.grease_pencil['tc_circle_000']

    else:
        print('not on a circle')
def createOutline(curve, outline):

    for spline in curve.data.splines[:]:
        p = spline.bezier_points
        out = []
        
        n = ((p[0].handle_right-p[0].co).normalized()-(p[0].handle_left-p[0].co).normalized()).normalized()
        n = Vector((-n[1], n[0], n[2]))
        o = p[0].co+outline*n
        out.append(o)
        
        for i in range(1,len(p)):
            n = ((p[i].handle_right-p[i].co).normalized()-(p[i].handle_left-p[i].co).normalized()).normalized()
            n = Vector((-n[1], n[0], n[2]))
            o = intersect_line_line(out[-1], (out[-1]+p[i].co-p[i-1].co), p[i].co, p[i].co+n)[0]
            out.append(o)
            
        curve.data.splines.new('BEZIER')
        if spline.use_cyclic_u:
            curve.data.splines[-1].use_cyclic_u = True
        p_out = curve.data.splines[-1].bezier_points
        p_out.add(len(out)-1)
    
        for i in range(len(out)):
            p_out[i].handle_left_type = 'FREE'  
            p_out[i].handle_right_type = 'FREE'
            
            p_out[i].co = out[i]
            
            if i<len(out)-1:
                l = (p[i+1].co-p[i].co).length
                l2 = (out[i]-out[i+1]).length
            
            if i==0:
                p_out[i].handle_left = out[i] + ((p[i].handle_left-p[i].co)*l2/l)
            if i<len(out)-1:
                p_out[i+1].handle_left = out[i+1] + ((p[i+1].handle_left-p[i+1].co)*l2/l)
            p_out[i].handle_right = out[i] + ((p[i].handle_right-p[i].co)*l2/l)
    
        for i in range(len(p)):
            p_out[i].handle_left_type = p[i].handle_left_type
            p_out[i].handle_right_type = p[i].handle_right_type
            
    return
def edgeIntersect(context, operator):
    from mathutils.geometry import intersect_line_line

    obj = context.active_object

    if obj.type != "MESH":
        operator.report({"ERROR"}, "Object must be a mesh")
        return None

    edges = []
    mesh = obj.data
    verts = mesh.vertices

    is_editmode = obj.mode == "EDIT"
    if is_editmode:
        bpy.ops.object.mode_set(mode="OBJECT")

    for e in mesh.edges:
        if e.select:
            edges.append(e)

            if len(edges) > 2:
                break

    if is_editmode:
        bpy.ops.object.mode_set(mode="EDIT")

    if len(edges) != 2:
        operator.report({"ERROR"}, "Operator requires exactly 2 edges to be selected")
        return

    line = intersect_line_line(
        verts[edges[0].vertices[0]].co,
        verts[edges[0].vertices[1]].co,
        verts[edges[1].vertices[0]].co,
        verts[edges[1].vertices[1]].co,
    )

    if line is None:
        operator.report({"ERROR"}, "Selected edges do not intersect")
        return

    point = line[0].lerp(line[1], 0.5)
    context.scene.cursor_location = obj.matrix_world * point
Example #52
0
    def start_grad_f(f, p):

        g = gradient_face(f, geos)
        L = f.calc_perimeter()

        # test for vert intersection
        for v in f.verts:
            v_inter, pct = intersect_point_line(v.co, p, p - L * g)

            delta = v.co - v_inter
            if delta.length < epsilon:
                print("intersects vert")
                return v, v.co, None

        for e in f.edges:

            v0, v1 = intersect_line_line(e.verts[0].co, e.verts[1].co, p, p - L * g)

            V = v0 - e.verts[0].co
            edV = e.verts[1].co - e.verts[0].co
            Vi = v0 - p

            if V.length - edV.length > epsilon:
                # print('intersects outside segment')
                continue
            elif V.dot(edV) < 0:
                # print('intersects behind')
                continue

            elif Vi.dot(g) > 0:  # remember we watnt to travel DOWN the gradient
                # print('shoots out the face, not across the face')
                continue
            else:
                # print('regular face edge crossing')
                return v0, e, f

        # we didn't intersect across an edge, or on a vert,
        # therefore, we should travel ALONG the edge

        vret = min(f.verts, key=geos.get)
        return vret.co, vret, None
Example #53
0
def add_vertex_to_intersection():

    obj = bpy.context.object
    me = obj.data
    bm = bmesh.from_edit_mesh(me)

    edges = [e for e in bm.edges if e.select]

    if len(edges) == 2:
        [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]

        iv = geometry.intersect_line_line(v1, v2, v3, v4)
        iv = (iv[0] + iv[1]) / 2
        bm.verts.new(iv)

        # precaution?
        if hasattr(bm.verts, "ensure_lookup_table"):
            bm.verts.ensure_lookup_table()
            # bm.edges.ensure_lookup_table()

        bm.verts[-1].select = True
        bmesh.update_edit_mesh(me)
Example #54
0
def generate_3PT(pts, obj, nv, mode=0):
    origin = obj.location
    mw = obj.matrix_world
    V = Vector

    nv = max(3, nv)

    # construction
    v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
    edge1_mid = v1.lerp(v2, 0.5)
    edge2_mid = v3.lerp(v4, 0.5)
    axis = geometry.normal(v1, v2, v4)
    mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

    # triangle edges
    v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
    v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
    v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
    v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

    r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
    if r:
        p1, _ = r
        cp = mw * p1
        bpy.context.scene.cursor_location = cp

        if mode == 0:
            layer = get_layer()
            generate_gp3d_stroke(layer, p1, v1, axis, mw, origin, nv)

            scn = bpy.context.scene
            scn.grease_pencil = bpy.data.grease_pencil['tc_circle_000']

        elif mode == 1:
            generate_bmesh_repr(p1, v1, axis, nv)

    else:
        print('not on a circle')
Example #55
0
def linkLayers(layer1, layer2):
    for i in range(0, len(layer1)):
        nextI = (i + 1)%len(layer1)
        nextII = (i + 2)%len(layer1)
        a = mathutils.Vector((layer2[i]['hinge3'].matrix_world[0][3]     , layer2[i]['y'], layer2[i]['hinge3'].matrix_world[2][3]))
        b = mathutils.Vector((layer2[nextI]['hinge1'].matrix_world[0][3] , layer2[i]['y'], layer2[nextI]['hinge1'].matrix_world[2][3]))
        c = mathutils.Vector((layer1[nextI]['hinge3'].matrix_world[0][3] , layer2[i]['y'], layer1[nextI]['hinge3'].matrix_world[2][3]))
        d = mathutils.Vector((layer1[nextII]['hinge1'].matrix_world[0][3], layer2[i]['y'], layer1[nextII]['hinge1'].matrix_world[2][3]))
        print(a, b, c, d)
        (v1, v2) = intersect_line_line(a, b, c, d)
        print (v1, v2)

        bpy.ops.object.select_all(action='DESELECT')
        bpy.types.SpaceView3D.cursor_location =  (0,0,0)
        bpy.ops.object.add(type='EMPTY')
        hinge = bpy.context.scene.objects.active
        hinge.name = ("mid hinge")
        hinge.location = v1
        hinge.rotation_euler = (tau/4,0,0)
        bpy.ops.rigidbody.constraint_add(type='HINGE')
        hinge.rigid_body_constraint.disable_collisions = False
        hinge.rigid_body_constraint.object1     = layer1[nextI]['bar1']
        hinge.rigid_body_constraint.object2     = layer2[nextI]['bar2']
        hinge.select = False
Example #56
0
def is_parallel(v1, v2, v3, v4):
    result = intersect_line_line(v1, v2, v3, v4) 
    return result == None
Example #57
0
    def execute(self, context):
        bpy.ops.object.editmode_toggle()
        bm = bmesh.new()
        bm.from_mesh(bpy.context.active_object.data)

        bVerts = bm.verts
        bEdges = bm.edges
        edges = []
        vectors = []

        for e in bEdges:
            if e.select:
                edges.append(e)

        # Until I can figure out a better way of handeling it:
        if len(edges) < 2:
            bpy.ops.object.editmode_toggle()
            self.report({'ERROR_INVALID_INPUT'}, "You must select two edges.")
            return {'CANCELLED'}

        verts = [edges[0].verts[0],
                 edges[0].verts[1],
                 edges[1].verts[0],
                 edges[1].verts[1]]

        cos = intersect_line_line(verts[0].co, verts[1].co, verts[2].co, verts[3].co)

        # If the two edges are parallel:
        if cos == None:
            self.report({'WARNING'}, "Selected lines are parallel: results may be unpredictable.")
            vectors.append(verts[0].co - verts[1].co)
            vectors.append(verts[0].co - verts[2].co)
            vectors.append(vectors[0].cross(vectors[1]))
            vectors.append(vectors[2].cross(vectors[0]))
            vectors.append(-vectors[3])
        else:
            # Warn the user if they have not chosen two planar edges:
            if not is_same_co(cos[0], cos[1]):
                self.report({'WARNING'}, "Selected lines are not planar: results may be unpredictable.")

            # This makes the +/- behavior predictable:
            if (verts[0].co - cos[0]).length < (verts[1].co - cos[0]).length:
                verts[0], verts[1] = verts[1], verts[0]
            if (verts[2].co - cos[0]).length < (verts[3].co - cos[0]).length:
                verts[2], verts[3] = verts[3], verts[2]

            vectors.append(verts[0].co - verts[1].co)
            vectors.append(verts[2].co - verts[3].co)
            
            # Normal of the plane formed by vector1 and vector2:
            vectors.append(vectors[0].cross(vectors[1]))

            # Possible directions:
            vectors.append(vectors[2].cross(vectors[0]))
            vectors.append(vectors[1].cross(vectors[2]))

        # Set the length:
        vectors[3].length = self.length
        vectors[4].length = self.length

        # Perform any additional rotations:
        matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
        vectors.append(matrix * -vectors[3]) # vectors[5]
        matrix = Matrix.Rotation(radians(90 - self.angle), 3, vectors[2])
        vectors.append(matrix * vectors[4]) # vectors[6]
        vectors.append(matrix * vectors[3]) # vectors[7]
        matrix = Matrix.Rotation(radians(90 + self.angle), 3, vectors[2])
        vectors.append(matrix * -vectors[4]) # vectors[8]

        # Perform extrusions and displacements:
        # There will be a total of 8 extrusions.  One for each vert of each edge.
        # It looks like an extrusion will add the new vert to the end of the verts
        # list and leave the rest in the same location.
        # ----------- EDIT -----------
        # It looks like I might be able to do this with in "bpy.data" with the ".add"
        # function.
        # ------- BMESH UPDATE -------
        # BMesh uses ".new()"

        for v in range(len(verts)):
            vert = verts[v]
            if (v == 0 and self.vert1) or (v == 1 and self.vert2) or (v == 2 and self.vert3) or (v == 3 and self.vert4):
                if self.pos:
                    new = bVerts.new()
                    new.co = vert.co - vectors[5 + (v // 2) + ((v % 2) * 2)]
                    bEdges.new((vert, new))
                if self.neg:
                    new = bVerts.new()
                    new.co = vert.co + vectors[5 + (v // 2) + ((v % 2) * 2)]
                    bEdges.new((vert, new))

        bm.to_mesh(bpy.context.active_object.data)
        bpy.ops.object.editmode_toggle()
        return {'FINISHED'}
Example #58
0
def intersect_line_line(v1, v2, v3, v4, threshold=1e-6):
    """
    三次元での直線同士の交差判定。平行だった場合、中間地点を求める。
    二次元が与えられたら三次元に拡張する。
    parallel_threshold:
        平行であるとする閾値
    """
    v1 = v1.to_3d()
    v2 = v2.to_3d()
    v3 = v3.to_3d()
    v4 = v4.to_3d()
    vec1 = v2 - v1
    vec2 = v4 - v3

    # 両方点
    if vec1.length == 0.0 and vec2.length == 0.0:
        return None

    # v1-v2が直線、v3-v4が点
    elif vec2.length == 0.0:
        return (v3 - v1).project(vec1) + v1, v3

    # v1-v2が点、v3-v4が直線
    elif vec1.length == 0.0:
        return v1, (v1 - v3).project(vec2) + v3

    # 平行
    elif vec1.normalized().cross(v3 - v1).length < threshold and \
       vec1.normalized().cross(v4 - v1).length < threshold:
        d1 = vec1.dot(v3 - v1)
        d2 = vec1.dot(v4 - v1)
        if d1 > d2:
            d1, d2 = d2, d1
            v3, v4 = v4, v3
            vec2.negate()
        # v3,v4が両方v1側 or v3がv1側, v4がv1-v2間
        if d2 <= 0 or (d1 <= 0 and 0 <= d2 <= vec1.length):
            mid = (v1 + v4) / 2
        # v3,v4が両方v2側 or v3がv1-v2間, v4がv2側
        elif d1 >= vec1.length or \
           (0 <= d1 <= vec1.length and d2 >= vec1.length):
            mid = (v2 + v3) / 2
        # v3,v4がv1-v2間
        elif 0 <= d1 <= vec1.length and 0 <= d2 <= vec1.length:
            mid = (v2 + v3) / 2
        # v1,v2がv3-v4間
        else:
            mid = (v1 + v4) / 2
        isect1 = (mid - v1).project(vec1) + v1
        isect2 = (mid - v3).project(vec2) + v3
        return isect1, isect2

    else:
        result = geom.intersect_line_line(v1, v2, v3, v4)
        if result is not None:
    #        isect1, isect2 = result
    #        if not math.isnan(isect1[0]) and not math.isnan(isect2[0]):
    #            return isect1, isect2
            return result

    return None