Skip to content
Snippets Groups Projects
common.py 31 KiB
Newer Older
  • Learn to ignore specific revisions
  • Nutti's avatar
    Nutti committed
    
        debug_print("===== Polygons Overlapped Partially =====")
        debug_print(polygons)
    
        return True, polygons
    
    
    def __is_polygon_flipped(points):
        area = 0.0
        for i in range(len(points)):
            uv1 = points.get(i)
            uv2 = points.get(i + 1)
            a = uv1.x * uv2.y - uv1.y * uv2.x
            area = area + a
        if area < 0:
            # clock-wise
            return True
        return False
    
    
    def __is_point_in_polygon(point, subject_points):
        count = 0
        for i in range(len(subject_points)):
            uv_start1 = subject_points.get(i)
            uv_end1 = subject_points.get(i + 1)
            uv_start2 = point
            uv_end2 = Vector((1000000.0, point.y))
            intersected, _ = __is_segment_intersect(uv_start1, uv_end1,
                                                    uv_start2, uv_end2)
            if intersected:
                count = count + 1
    
        return count % 2
    
    
    def __is_points_in_polygon(points, subject_points):
        for i in range(len(points)):
            internal = __is_point_in_polygon(points.get(i), subject_points)
            if not internal:
                return False
    
        return True
    
    
    def get_overlapped_uv_info(bm, faces, uv_layer, mode):
        # at first, check island overlapped
        isl = get_island_info_from_faces(bm, faces, uv_layer)
        overlapped_isl_pairs = []
        for i, i1 in enumerate(isl):
            for i2 in isl[i + 1:]:
                if (i1["max"].x < i2["min"].x) or (i2["max"].x < i1["min"].x) or \
                   (i1["max"].y < i2["min"].y) or (i2["max"].y < i1["min"].y):
                    continue
                overlapped_isl_pairs.append([i1, i2])
    
        # next, check polygon overlapped
        overlapped_uvs = []
        for oip in overlapped_isl_pairs:
            for clip in oip[0]["faces"]:
                f_clip = clip["face"]
                for subject in oip[1]["faces"]:
                    f_subject = subject["face"]
    
                    # fast operation, apply bounding box algorithm
                    if (clip["max_uv"].x < subject["min_uv"].x) or \
                       (subject["max_uv"].x < clip["min_uv"].x) or \
                       (clip["max_uv"].y < subject["min_uv"].y) or \
                       (subject["max_uv"].y < clip["min_uv"].y):
                        continue
    
                    # slow operation, apply Weiler-Atherton cliping algorithm
                    result, polygons = __do_weiler_atherton_cliping(f_clip,
                                                                    f_subject,
                                                                    uv_layer, mode)
                    if result:
                        subject_uvs = [l[uv_layer].uv.copy()
                                       for l in f_subject.loops]
                        overlapped_uvs.append({"clip_face": f_clip,
                                               "subject_face": f_subject,
                                               "subject_uvs": subject_uvs,
                                               "polygons": polygons})
    
        return overlapped_uvs
    
    
    def get_flipped_uv_info(faces, uv_layer):
        flipped_uvs = []
        for f in faces:
            polygon = RingBuffer([l[uv_layer].uv.copy() for l in f.loops])
            if __is_polygon_flipped(polygon):
                uvs = [l[uv_layer].uv.copy() for l in f.loops]
                flipped_uvs.append({"face": f, "uvs": uvs,
                                    "polygons": [polygon.as_list()]})
    
        return flipped_uvs
    
    
    def __is_polygon_same(points1, points2):
        if len(points1) != len(points2):
            return False
    
        pts1 = points1.as_list()
        pts2 = points2.as_list()
    
        for p1 in pts1:
            for p2 in pts2:
                diff = p2 - p1
                if diff.length < 0.0000001:
                    pts2.remove(p2)
                    break
            else:
                return False
    
        return True