示例#1
0
    def test_spline_fitting(self):
        # Test a real spline interpolation
        xs = np.linspace(0.0, 2 * math.pi, 100)
        ys = np.array([math.sin(x) for x in xs])
        points = [geom.Vertex((xs[i], ys[i], 0.0)) for i in range(len(xs))]

        cpoints_chunks = fit.fit_bezier_spline(points,
                                               mmath.interp_bezier_curve_2, 2)
        curves = []
        cpoints = []
        for chunk in cpoints_chunks:
            cpoints += chunk
            verts = map(lambda x: geom.Vertex(x), chunk)
            curves += [
                geom.BaseCurve(list(verts), mmath.interp_bezier_curve_2)
            ]
        curve = geom.SuperCurve(curves)

        # Compute the current spline
        spline_ts = np.linspace(0.0, 1.0, 100)
        spline_points = [curve.t(t) for t in spline_ts]
        spline_xs = [p.x for p in spline_points]
        spline_ys = [p.y for p in spline_points]

        # Compute the control points
        cpointsx = [cp[0] for cp in cpoints]
        cpointsy = [cp[1] for cp in cpoints]

        # Actually plot the graph
        if DRAW_GRAPHS:
            plt.plot(spline_xs, spline_ys)  # Approximate function
            plt.plot(xs, ys)  # Original function
            plt.plot(cpointsx, cpointsy, "o")
            plt.show()
示例#2
0
 def test_vert(self):
     vert1 = geom.Vertex((2.0, 3.0, -3.0))
     vert2 = geom.Vertex((2.0, 3.0, 3.0))
     self.assertFalse(np.allclose(vert1, vert2))
     self.assertTrue(
         np.allclose((vert1 + vert2), geom.Vertex((4.0, 6.0, 0.0))))
     self.assertFalse(np.allclose(2 * vert1, vert1 * 3))
     self.assertTrue(np.allclose(vert2, abs(vert1)))
     self.assertTrue(np.allclose(abs(vert1), abs(vert2)))
示例#3
0
def are_edges_coplanar(c, e1, e2, e3, threshold=0.1):
    cross = lambda x, y: geom.Vertex(funchelps.cross(x, y))
    gc = blender.convert_vert(c)
    ge1 = blender.convert_vert(e1)
    ge2 = blender.convert_vert(e2)
    ge3 = blender.convert_vert(e3)
    return abs(funchelps.dot(cross(ge1 - gc, ge2 - gc), ge3 - gc)) < threshold
def plot_beizer_spline_2d(points, function, n, figname, steps=100):
    points_xs = [p[0] for p in points]
    points_ys = [p[1] for p in points]

    cpoints_chunks = fit.fit_bezier_spline(points, function, n)
    curves = []
    cpoints = []
    for chunk in cpoints_chunks:
        cpoints += chunk
        verts = map(lambda x: geom.Vertex(x), chunk)
        curves += [geom.BaseCurve(list(verts), function)]
    curve = geom.SuperCurve(curves)

    spline_ts = np.linspace(0.0, 1.0, steps)
    spline_points = [curve.t(t) for t in spline_ts]
    curve_xs = [p.x for p in spline_points]
    curve_ys = [p.y for p in spline_points]

    # Compute the control points
    cpoints_xs = [cp[0] for cp in cpoints]
    cpoints_ys = [cp[1] for cp in cpoints]

    plt.plot(points_xs, points_ys, "o", color="blue", label="Input points")
    plt.plot(cpoints_xs, cpoints_ys, "o", color="red", label="Control points")
    plt.plot(curve_xs, curve_ys, color="green", label="Bezier spline")
    plt.grid()
    plt.legend()
    plt.savefig(OUT_GRAPH_DIR + figname)
    plt.show()
示例#5
0
    def test_curve2_fitting(self):
        A = geom.Vertex((0.0, 0.0, 0.0))
        B = geom.Vertex((0.5, 2.0, 0.0))
        C = geom.Vertex((1.0, 2.0, 1.0))
        curve = geom.BaseCurve((A, B, C), mmath.interp_bezier_curve_2)

        points = list(geom.sample_curve_samples(curve, 100))
        vals = fit.fit_bezier_curve(points, mmath.interp_bezier_curve_2)

        self.assertTrue(np.allclose(np.array(vals), np.array([A, B, C])))

        if HUMAN_READABLE_TESTS:
            print(DELIMETER)
            print(vals)
            print([A, B, C])
            print(DELIMETER)
示例#6
0
    def test_very_simple_spline_fitting(self):
        # Manually construct a sort of sine wave using bezier curves
        sin = lambda x: math.sin(x)

        xs = np.linspace(0.0, 2 * math.pi, 5)
        ys = np.array([math.sin(x) for x in xs])
        cpoints = [geom.Vertex((xs[i], ys[i], 0.0)) for i in range(len(xs))]

        # We need to repeat the control points to have a spline
        cpoints_chunks = ut.splinify_list(cpoints, 3)
        curves = [
            geom.BaseCurve(ps, mmath.interp_bezier_curve_2)
            for ps in cpoints_chunks
        ]
        curve = geom.SuperCurve(curves)

        # Plot the current spline
        spline_ts = np.linspace(0.0, 1.0, 100)
        spline_points = [curve.t(t) for t in spline_ts]
        spline_xs = [p.x for p in spline_points]
        spline_ys = [p.y for p in spline_points]

        # Print the graph
        if DRAW_GRAPHS:
            plt.plot(spline_xs, spline_ys)
            plt.show()
def parse_vertex(values):
    vertex_coord = geometry.VertexCoord(float(values[2]), float(values[3]),
                                        float(values[4]))
    normal = geometry.Normal(float(values[6]), float(values[7]),
                             float(values[8]))
    tex_coord_1 = geometry.TexCoord(float(values[10]), float(values[11]))
    tex_coord_2 = geometry.TexCoord(float(values[13]), float(values[14]))

    return geometry.Vertex(vertex_coord, normal, tex_coord_1, tex_coord_2)
示例#8
0
    def test_vertex(self):
        v = geometry.Vertex('reflex', 65, 47)
        self.assertEqual('%s' % v, '#<Vertex kind=reflex y=65 x=47 idx=None>')
        self.assertFalse(v.is_convex)

        v.mark_terminal()
        self.assertEqual(
            '%s' % v, '#<Vertex kind=reflex y=65 x=47 idx=None terminal=true>')

        v = geometry.Vertex('convex', 82, 31)
        self.assertEqual('%s' % v, '#<Vertex kind=convex y=82 x=31 idx=None>')
        self.assertTrue(v.is_convex)

        v.mark_terminal()
        self.assertEqual(
            '%s' % v, '#<Vertex kind=convex y=82 x=31 idx=None terminal=true>')

        f = lambda: geometry.Vertex('other', 90, 54)
        self.assertRaises(errors.GeometryError, f)
示例#9
0
    def test_simple_net(self):
        v0 = geom.Vertex((0.0, 0.0, 0.0))
        v1 = geom.Vertex((1.0, 0.0, 0.0))
        v2 = geom.Vertex((1.0, 1.0, 0.0))
        v3 = geom.Vertex((0.0, 1.0, 0.0))

        disp = geom.Vertex((0.0, 0.0, 0.5))

        m0 = (v0 + v1) / 2.0 + disp
        m1 = (v1 + v2) / 2.0 + disp
        m2 = (v2 + v3) / 2.0 + disp
        m3 = (v3 + v0) / 2.0 + disp

        c1 = geom.SuperCurve(
            [geom.BaseCurve((v0, m0, v1), mmath.interp_bezier_curve_2)])
        c2 = geom.BaseCurve((v1, m1, v2), mmath.interp_bezier_curve_2)
        c3 = geom.BaseCurve((v2, m2, v3), mmath.interp_bezier_curve_2)
        c4 = geom.BaseCurve((v3, m3, v0), mmath.interp_bezier_curve_2)

        c1_points = list(geom.sample_curve_samples(c1, 10))
        c2_points = list(geom.sample_curve_samples(c2, 10))
        c3_points = list(geom.sample_curve_samples(c3, 10))
        c4_points = list(geom.sample_curve_samples(c4, 10))

        polygon = geom.PolygonsNetQuad((c1, c2, c3, c4))
        points = list(geom.sample_patch_samples(polygon, 70))

        if DRAW_GRAPHS:
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot([p.x for p in c1_points], [p.y for p in c1_points],
                    [p.z for p in c1_points])
            ax.plot([p.x for p in c2_points], [p.y for p in c2_points],
                    [p.z for p in c2_points])
            ax.plot([p.x for p in c3_points], [p.y for p in c3_points],
                    [p.z for p in c3_points])
            ax.plot([p.x for p in c4_points], [p.y for p in c4_points],
                    [p.z for p in c4_points])
            ax.plot([p.x for p in points], [p.y for p in points],
                    [p.z for p in points],
                    "o",
                    label="Geometry points")
            plt.show()
示例#10
0
    def test_complex_net(self):
        coords1 = [(0.0, 0.0, 0.0), (0.5, 0.0, 1.0), (1.0, -0.2, 0.5),
                   (1.5, 0.0, 0.0), (2.0, -0.1, 0.5)]
        cpoints1 = [geom.Vertex(coord) for coord in coords1]
        curve1 = geom.generate_spline(cpoints1, mmath.interp_bezier_curve_2)

        coords2 = [(2.0, -0.1, 0.5), (2.0, 1.0, 1.0), (2.1, 2.0, 0.0)]
        cpoints2 = [geom.Vertex(coord) for coord in coords2]
        curve2 = geom.generate_spline(cpoints2, mmath.interp_bezier_curve_2)

        coords3 = [(2.1, 2.0, 0.0), (1.5, 2.0, 0.0), (1.0, 2.1, 0.5),
                   (0.5, 2.0, 1.0), (0.0, 2.0, 0.0)]
        cpoints3 = [geom.Vertex(coord) for coord in coords3]
        curve3 = geom.generate_spline(cpoints3, mmath.interp_bezier_curve_2)

        coords4 = [(0.0, 2.0, 0.0), (-0.5, 1.0, 0.0), (0.0, 0.0, 0.0)]
        cpoints4 = [geom.Vertex(coord) for coord in coords4]
        curve4 = geom.generate_spline(cpoints4, mmath.interp_bezier_curve_2)

        polygon = geom.PolygonsNetQuad((curve1, curve2, curve3, curve4))
        points = list(geom.sample_patch_samples(polygon, 50))

        c1_points = list(geom.sample_curve_samples(curve1, 20))
        c2_points = list(geom.sample_curve_samples(curve2, 20))
        c3_points = list(geom.sample_curve_samples(curve3, 20))
        c4_points = list(geom.sample_curve_samples(curve4, 20))

        if DRAW_GRAPHS:
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot([p.x for p in c1_points], [p.y for p in c1_points],
                    [p.z for p in c1_points])
            ax.plot([p.x for p in c2_points], [p.y for p in c2_points],
                    [p.z for p in c2_points])
            ax.plot([p.x for p in c3_points], [p.y for p in c3_points],
                    [p.z for p in c3_points])
            ax.plot([p.x for p in c4_points], [p.y for p in c4_points],
                    [p.z for p in c4_points])
            ax.plot([p.x for p in points], [p.y for p in points],
                    [p.z for p in points],
                    "o",
                    label="Geometry points")
            plt.show()
def plot_bezier_spline_3d(points, function, n, figname, steps=100):
    cpoints_chunks = fit.fit_bezier_spline(points, mmath.bezier_curve_3, 5)
    curves = []
    cpoints = []
    for chunk in cpoints_chunks:
        cpoints += chunk
        verts = map(lambda x: geom.Vertex(x), chunk)
        curves += [geom.BaseCurve(list(verts), mmath.bezier_curve_3)]
    curve = geom.SuperCurve(curves)

    # Compute the current spline
    spline_ts = np.linspace(0.0, 1.0, steps)
    spline_points = [curve.t(t) for t in spline_ts]
    spline_xs = [p.x for p in spline_points]
    spline_ys = [p.y for p in spline_points]
    spline_zs = [p.z for p in spline_points]

    # Compute the current control points
    cpointsx = [cp[0] for cp in cpoints]
    cpointsy = [cp[1] for cp in cpoints]
    cpointsz = [cp[2] for cp in cpoints]

    # Draw the graph
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot([p[0] for p in points], [p[1] for p in points],
            [p[2] for p in points],
            "o",
            color="blue",
            label="Input points")
    ax.plot(spline_xs,
            spline_ys,
            spline_zs,
            color="green",
            label='Bezier spline')
    ax.plot(cpointsx,
            cpointsy,
            cpointsz,
            "o",
            color="red",
            label="Control points")
    plt.grid()
    plt.legend()
    plt.savefig(OUT_GRAPH_DIR + figname)
    plt.show()
示例#12
0
    def test_spline_fitting_3d(self):
        '''Fit a complex 3d curve with a bezier spline of degree three (5 curves).'''
        # Generate a cool 3d curve
        theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
        zs = np.linspace(-2, 2, 100)
        r = zs**2 + 1
        xs = r * np.sin(theta)
        ys = r * np.cos(theta)

        # Fit the data
        points = list(zip(xs, ys, zs))
        cpoints_chunks = fit.fit_bezier_spline(points, mmath.bezier_curve_3, 5)
        curves = []
        cpoints = []
        for chunk in cpoints_chunks:
            cpoints += chunk
            verts = map(lambda x: geom.Vertex(x), chunk)
            curves += [geom.BaseCurve(list(verts), mmath.bezier_curve_3)]
        curve = geom.SuperCurve(curves)

        # Compute the current spline
        spline_ts = np.linspace(0.0, 1.0, 100)
        spline_points = [curve.t(t) for t in spline_ts]
        spline_xs = [p.x for p in spline_points]
        spline_ys = [p.y for p in spline_points]
        spline_zs = [p.z for p in spline_points]

        # Compute the current control points
        cpointsx = [cp[0] for cp in cpoints]
        cpointsy = [cp[1] for cp in cpoints]
        cpointsz = [cp[2] for cp in cpoints]

        # Draw the graph
        if DRAW_GRAPHS:
            fig = plt.figure()
            ax = fig.gca(projection='3d')
            ax.plot(xs, ys, zs, label='parametric curve')
            ax.plot(spline_xs, spline_ys, spline_zs, label='Fitted spline')
            ax.plot(cpointsx, cpointsy, cpointsz, "o", label="Control points")
            plt.legend()
            plt.show()
def plot_bezier_curve(points, function, figname):
    points_xs = [p[0] for p in points]
    points_ys = [p[1] for p in points]

    cpoints = fit.fit_bezier_curve(
        list(zip(points_xs, points_ys, [0] * len(points_xs))), function)
    cpoints_xs = [p[0] for p in cpoints]
    cpoints_ys = [p[1] for p in cpoints]

    curve = geom.BaseCurve([geom.Vertex(p) for p in cpoints], function)
    curve_points = list(geom.sample_curve_samples(curve, 100))
    curve_xs = [p.x for p in curve_points]
    curve_ys = [p.y for p in curve_points]

    plt.plot(points_xs, points_ys, "o", color="blue", label="Input points")
    plt.plot(cpoints_xs, cpoints_ys, "o", color="red", label="Control points")
    plt.plot(curve_xs, curve_ys, color="green", label="Bezier curve")
    plt.grid()
    plt.legend()
    plt.savefig(OUT_GRAPH_DIR + figname)
    plt.show()
示例#14
0
 def add(self, dir, point_y, point_x, next_dir):
     self.count += 1
     if self.count >= 128:
         raise errors.AlgorithmError('loop detected at y=%s, x=%s' %
                                     (point_y, point_x))
     # Adjust
     if dir == DIR_DOWN:
         point_x += 1
     if dir == DIR_LEFT:
         point_y += 1
     if next_dir == DIR_DOWN:
         point_x += 1
     elif next_dir == DIR_LEFT:
         point_y += 1
     # Edge
     edge = geometry.Edge(rotate_dir_cw(dir), self.curr_y, self.curr_x,
                          point_y, point_x)
     self.edges.append(edge)
     # Vertex
     kind = 'convex' if next_dir == rotate_dir_cw(dir) else 'reflex'
     self.vertices.append(
         geometry.Vertex(kind, point_y, point_x, len(self.vertices)))
     # Border
     if point_y < self.min_y:
         self.min_y = point_y
     if point_y > self.max_y:
         self.max_y = point_y
     if point_x < self.min_x:
         self.min_x = point_x
     if point_x > self.max_x:
         self.max_x = point_x
     # Done?
     self.curr_y = point_y
     self.curr_x = point_x
     if point_y == self.start_y and point_x == self.start_x:
         first = self.vertices[-1]
         self.vertices = [first] + self.vertices[:-1]
         return True
示例#15
0
    def test_interpolating_curves(self):
        '''We should check that interpolating curves are really interpolating'''
        A = geom.Vertex((0.0, 0.0, 0.0))
        B = geom.Vertex((0.0, 1.0, 0.0))
        C = geom.Vertex((1.0, 1.0, 0.0))
        c = mmath.interp_bezier_curve_2

        self.assertTrue(np.allclose(c(0.0, A, B, C), A))
        self.assertTrue(np.allclose(c(0.5, A, B, C), B))
        self.assertTrue(np.allclose(c(1.0, A, B, C), C))

        A = geom.Vertex((0.0, 0.0, 0.0))
        B = geom.Vertex((0.5, 2.0, 0.0))
        C = geom.Vertex((1.0, 2.0, 1.0))
        D = geom.Vertex((0.0, 0.0, 1.0))
        c = mmath.interp_bezier_curve_3

        self.assertTrue(np.allclose(c(0.0, A, B, C, D), A))
        self.assertTrue(np.allclose(c(1 / 3, A, B, C, D), B))
        self.assertTrue(np.allclose(c(2 / 3, A, B, C, D), C))
        self.assertTrue(np.allclose(c(1.0, A, B, C, D), D))
示例#16
0
def convert_vert(bmv):
    '''Convert blender bmesh vertexes to our geometry.Vertex class.'''
    return geom.Vertex((bmv.co[0], bmv.co[1], bmv.co[2]))
    def read(self, filename, model, params):
        # lists with parsed vertex attributes
        vertex_coords = []
        tex_coords = []
        normals = []
        materials = {}

        # read file
        input_file = open(filename, 'r')

        flipX = 1.0
        flipY = 1.0
        flipZ = 1.0

        if modelformat.get_param(params, 'flipX') != None: flipX = -1.0
        if modelformat.get_param(params, 'flipY') != None: flipY = -1.0
        if modelformat.get_param(params, 'flipZ') != None: flipZ = -1.0

        flipOrder = (flipX * flipY * flipZ) < 0

        # parse lines
        while True:
            line = input_file.readline()

            if len(line) == 0:
                break

            if line[len(line) - 1] == '\n':
                line = line[:len(line) - 1]

            parts = line.split(' ')

            if parts[0] == 'mtllib':
                name = parts[1]
                materials = read_mtl_file(name)
            elif parts[0] == 'v':
                vertex_coords.append(
                    geometry.VertexCoord(flipX * float(parts[1]),
                                         flipY * float(parts[2]),
                                         flipZ * float(parts[3])))
            elif parts[0] == 'vt':
                tex_coords.append(
                    geometry.TexCoord(float(parts[1]), 1 - float(parts[2])))
            elif parts[0] == 'vn':
                normals.append(
                    geometry.Normal(flipX * float(parts[1]),
                                    flipY * float(parts[2]),
                                    flipZ * float(parts[3])))
            elif parts[0] == 'usemtl':
                current_material = materials[parts[1]]
            elif parts[0] == 'f':
                polygon = []

                # parse vertices
                for i in range(1, len(parts)):
                    elements = parts[i].split('/')

                    vert_coord = vertex_coords[int(elements[0]) - 1]
                    normal = normals[int(elements[2]) - 1]

                    if elements[1] == '':
                        tex_coord = geometry.TexCoord(0.0, 0.0)
                    else:
                        tex_coord = tex_coords[int(elements[1]) - 1]

                    polygon.append(
                        geometry.Vertex(vert_coord, normal, tex_coord))

                # triangulate polygon
                new_triangles = geometry.triangulate(polygon, flipOrder)

                # save vertices
                for triangle in new_triangles:
                    triangle.material = current_material
                    model.triangles.append(triangle)

        input_file.close()

        return True
示例#18
0
    def test_3d_quad_plot_almost_cube(self):
        verts = [
            geom.Vertex((0.0, 0.0, 0.0)),
            geom.Vertex((1.0, 0.0, 0.0)),
            geom.Vertex((1.0, 1.0, 0.0)),
            geom.Vertex((0.0, 1.0, 0.0))
        ]
        verts2 = [
            geom.Vertex((0.0, 0.0, 1.0)),
            geom.Vertex((1.0, 0.0, 1.0)),
            geom.Vertex((1.0, 1.0, 1.0)),
            geom.Vertex((0.0, 1.0, 1.0))
        ]
        verts3 = [
            geom.Vertex((0.0, 0.0, 0.0)),
            geom.Vertex((0.0, 0.0, 1.0)),
            geom.Vertex((1.0, 0.0, 1.0)),
            geom.Vertex((1.0, 0.0, 0.0))
        ]
        verts4 = [
            geom.Vertex((0.0, 1.0, 0.0)),
            geom.Vertex((0.0, 1.0, 1.0)),
            geom.Vertex((1.0, 1.0, 1.0)),
            geom.Vertex((1.0, 1.0, 0.0))
        ]

        if DRAW_GRAPHS:
            fig = plt.figure()
            ax = fig.add_subplot(111, projection='3d')
            ax.add_collection3d(
                Poly3DCollection([verts, verts2, verts3, verts4]))
            plt.show()
示例#19
0
def run(bm):
    '''Run the algorithm on the given bmesh (blender mesh), 
    returns the patches (TODO in a data structure we still need to decide)'''
    verts_list = list(bm.verts)
    faces_list = list(bm.faces)
    verts_indexes = [v.index for v in verts_list]

    # Extract the skeleton mesh.
    patches, macro_edges, singular_verts = extract_base_mesh(bm)

    def calculate_patches(macro_edges, bm):
        boundaries = set(sum(macro_edges, ()))

        # Now we need to understand which vertex belong to which face. We use the connected components approach.
        patch_verts_attribution = partition_mesh_vertices(
            verts_indexes, boundaries, bm)

        # Now we need to understand which superedges belong to which face.
        patches = compute_patch_edges(patch_verts_attribution, macro_edges)

        # We now need to reorder the vertices of each face so that we can build a spline on them.
        for i, part in enumerate(patches):
            try:
                patches[i] = reorder_patch_edges(part)
            except:
                patches[i] = None

        # Filter empty and quadrangualte.
        patches = [p for p in patches if p]
        patches = quadrangulate_patches_keep_separate_edges(
            patches, verts_list)

        return patch_verts_attribution, patches

    MIN_VERTS = 20

    threshold = PATCH_THRESHOLD * size_estimate(bm)
    print("Using Threshold:", threshold)

    def is_patch_big_enough(patch):
        '''Returns if all the edges of the patch are big enough for it to be splitted.'''
        return all(len(edge) >= 5 for edge in flat_patch_edges(patch))

    def can_simplify(patch_verts):
        '''Returns wheter the patch contains enough point to be simplified.'''
        return patch_verts and len(patch_verts) > MIN_VERTS

    patch_verts_attribution, patches = calculate_patches(macro_edges, bm)
    skip_patches = []

    # Now that we defined the patches we should iterate to improve the error.
    result = []
    patch_improved = True
    #patch_improved = False
    while patch_improved:
        patch_improved = False
        print("Number of patches", len(patches))

        for i, current_patch in enumerate(patches):
            current_attr = patch_verts_attribution[i]

            if all([
                    current_patch not in skip_patches,
                    can_simplify(current_attr),
                    is_patch_big_enough(current_patch),
                    compute_patch_error(flat_patch_edges(current_patch), bm,
                                        current_attr) > threshold
            ]):

                #pr("ERROR", compute_patch_error(current_patch, bm, current_attr))
                try:
                    old_edges = sum(current_patch, [])
                    new_edges = split_patch_4(current_patch, current_attr, bm)
                    new_macro_edges = set(macro_edges)

                    for edge in old_edges:
                        if edge in new_macro_edges:
                            new_macro_edges.remove(edge)
                        if edge[::-1] in macro_edges:
                            new_macro_edges.remove(edge[::-1])

                    for edge in new_edges:
                        if edge[::-1] not in new_macro_edges:
                            new_macro_edges.add(edge)

                    patch_verts_attribution, patches = calculate_patches(
                        new_macro_edges, bm)
                    macro_edges = new_macro_edges

                    patch_improved = True
                    break
                except Exception as e:
                    print("Patch discarded")
                    skip_patches += [current_patch]

    result = patches

    #We need to fit the patch edges with lower degree curves
    #edges = set(sum(result, []))
    edges = set(sum(sum(result, []), []))
    edges = sorted(edges, key=len)

    edge_correspondence = {}
    old_verts = [geom.Vertex((v.co.x, v.co.y, v.co.z)) for v in verts_list]

    # TODO Disable this. Returns the patches without the edge fitting.
    #return old_verts, result, old_verts, result

    # Output values
    new_verts = []
    new_edges = []
    new_patches = []

    SAMPLES = 20
    spline_threshold = SPLINE_THRESHOLD * size_estimate(bm)
    THRESHOLD_DISTANCE = VERTEX_MERGE_THRESHOLD * size_estimate(bm)

    edge_conversion = {}

    def merge_all_edges(edges):
        if not edges:
            return []
        result = edges[0]
        for e in edges[1:]:
            result += e[1:]
        return tuple(result)

    for i, edge in enumerate(edges):
        if edge_conversion.get(edge):
            pass
        else:
            cpoints = tuple([old_verts[i] for i in edge])

            def squash_chunks(chunks):
                if len(chunks) == 1:
                    return chunks[0]
                return chunks[0][:-1] + squash_chunks(chunks[1:])

            new_cpoints = []
            error = float("inf")
            n_splines = 1

            try:
                while error > spline_threshold:
                    cpoints_chunks = fit.fit_bezier_spline(
                        cpoints, mmath.interp_bezier_curve_2, n_splines)
                    verts_chunks = [[geom.Vertex(p) for p in chunk]
                                    for chunk in cpoints_chunks]
                    verts_chunks[0][0] = cpoints[0]
                    verts_chunks[-1][-1] = cpoints[-1]

                    # Increase the precision at the next step
                    n_splines += 1

                    # We need to use the original extremes control points to ensure continuity
                    new_cpoints = squash_chunks(verts_chunks)

                    # Check the error and fallback to default spline if issues
                    new_curve = geom.generate_spline(
                        new_cpoints, mmath.interp_bezier_curve_2)
                    new_curve_points = list(
                        geom.sample_curve_samples(new_curve, len(cpoints)))
                    error = errors.simple_max_error(new_curve_points, cpoints)
            except:
                new_cpoints = cpoints

            print("Compressing edge: %s/%s. n.verts: %s -> %s" %
                  (i + 1, len(edges), len(cpoints), len(new_cpoints)))

            new_verts += new_cpoints
            new_verts_indexes = tuple(
                [new_verts.index(v) for v in new_cpoints])
            edge_conversion[edge] = new_verts_indexes
            edge_conversion[edge[::-1]] = new_verts_indexes[::-1]

    final_patches = []

    # Convert the edges with the approximated ones.
    for patch in result:
        converted_edges = [[edge_conversion[edge] for edge in edges]
                           for edges in patch]
        final_patches += [flat_patch_edges(converted_edges)]

    # TODO Remember to disable this.
    #return new_verts, final_patches, new_verts, final_patches

    def generate_convert(threshold_index, prev_index):
        def convert(index):
            if index < threshold_index:
                return index
            elif index == threshold_index:
                return prev_index
            else:
                return index - 1

        return convert

    def update_edge(e, convert):
        return tuple([convert(i) for i in e])

    def update_patch(p, convert):
        return [update_edge(e, convert) for e in p]

    def my_index(l, element):
        """Returns the element in the list, otherwise -1"""
        return l.index(element) if element in l else -1

    def my_index_closest(l, element):
        temp = list(l)
        mod = lambda x: x[0] * x[0] + x[1] * x[1] + x[2] * x[2]

        closest = sorted(temp, key=lambda x: mod(x - element))[0]

        return l.index(closest) if mod(element -
                                       closest) < THRESHOLD_DISTANCE else -1

    def recursive_max(l):
        if isinstance(l, (int, float)):
            return l
        return max((recursive_max(e) for e in l))

    # Filter out vertices which are not unique.

    final_verts = []
    for i, vert in enumerate(new_verts):
        index = my_index_closest(final_verts, vert) if final_verts else -1
        if index == -1:
            final_verts += [vert]
        else:
            # The element is not in the list. This means that we need to decrement all the indexes and replace i with index.
            convert_func = generate_convert(len(final_verts), index)
            for i, p in enumerate(final_patches):
                final_patches[i] = update_patch(p, convert_func)

    input_size = compute_input_mesh_size(bm)
    output_size = compute_output_mesh_size(final_patches)

    print("Statistics ------------------------------------------")
    print("Input Vertices:   ", len(verts_list))
    print("Input Faces:      ", len(faces_list))
    print("Output Vertices:  ", len(final_verts))
    print("Output Faces:     ", len(final_patches))
    print("Input Size:       ", input_size)
    print("Output Size:      ", output_size)
    print("Compression Ratio:", (input_size / output_size))
    print("-----------------------------------------------------")

    old_pathces = [flat_patch_edges(p) for p in result]

    return old_verts, old_pathces, final_verts, final_patches
示例#20
0
import Smeshalist
import geometry
import random 

Smeshalist.getInstance(8383, False)

counter = 0
while counter < 1000:
    counter = counter + 1
    point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))

    vertex = geometry.Vertex(point1)
    vertex.groupId = 1
    Smeshalist.addVertex(vertex)

counter = 0
while counter < 1000:
    counter = counter + 1
    point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))
    point2 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))

    edge = geometry.Edge(point1, point2)
    edge.groupId = 1
    Smeshalist.addEdge(edge)


counter = 0
while counter < 1000:
    counter = counter + 1
    point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))
    point2 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))
示例#21
0
 def test_complex_error(self):
     verts1 = [geom.Vertex((0.0, 0.0, 1.0)), geom.Vertex((0.0, 0.0, 0.0))]
     refs = [geom.Vertex((0.0, 1.0, 1.0)), geom.Vertex((0.0, 1.0, 0.0))]
     self.assertEqual(errors.verts_sets_sq_error(verts1, refs), 2)