Exemplo n.º 1
0
 def calc_pentagon_dimensions(self):
     bbox = calc_overall_bbox(self.new_pentagon())
     self._pent_width, self._pent_height = abs(bbox[1] -
                                               bbox[0]), abs(bbox[3] -
                                                             bbox[2])
     self._pent_x, self._pent_y = min(bbox[0],
                                      bbox[1]), min(bbox[2], bbox[3])
Exemplo n.º 2
0
 def calc_pattern_viewbox(self):
     bbox = calc_overall_bbox(self.cairo_group)
     vbwidth = self.cairo_group[1][3].end.real + self.pent_height
     vbheight = self.pent_height * 2
     self._pattern_viewbox = min(bbox[0], bbox[1]) + self.cairo_group[1][2].end.real, \
                             min(bbox[2], bbox[3]), vbwidth * self.repetitions, \
                             vbheight * self.repetitions
Exemplo n.º 3
0
    def draw_path_clip(self):
        path_filename = "{}/path_clip_{}.svg".format(
            self.output_folder,
            basename(self.filename).replace(".svg", ""))
        dwg = Drawing(path_filename)
        image_bbox = calc_overall_bbox(self.tile_paths)

        dx = self.pent_x - min(image_bbox[0], image_bbox[1])
        dy = self.pent_y - min(image_bbox[2], image_bbox[3])
        dwg.add(
            dwg.path(
                **{
                    "d": self.new_pentagon().d(),
                    "fill": "none",
                    'stroke-width': 4,
                    'stroke': rgb(0, 0, 0)
                }))
        neg_transform = "translate({}, {})".format(-dx, -dy)
        transform = "translate({}, {})".format(dx, dy)
        clip_path = dwg.defs.add(
            dwg.clipPath(id="pent_path", transform=neg_transform))
        clip_path.add(dwg.path(d=self.new_pentagon().d()))
        group = dwg.add(
            dwg.g(clip_path="url(#pent_path)",
                  transform=transform,
                  id="clippedpath"))
        for i, path in enumerate(self.tile_paths):
            group.add(
                dwg.path(d=path.d(),
                         style=self.tile_attributes[i].get('style'),
                         id=self.tile_attributes[i]['id']))
        dwg.add(dwg.use("#clippedpath", transform="transform(100, 100)"))

        dwg.viewbox(self.pent_x, self.pent_y, self.pent_width,
                    self.pent_height)
        dwg.save()
        xml = xml.dom.minidom.parse(path_filename)
        open(path_filename, "w").write(xml.toprettyxml())
def flatten_scene(pScene):
    lNode = pScene.GetRootNode()

    if not lNode:
        return

    for i in range(lNode.GetChildCount()):

        lChildNode = lNode.GetChild(i)
        if lChildNode.GetNodeAttribute() is None:
            continue
        lAttributeType = (lChildNode.GetNodeAttribute().GetAttributeType())
        if lAttributeType != FbxNodeAttribute.eMesh:
            continue
        lMesh = lChildNode.GetNodeAttribute()
        projected_points = {}
        control_points = lMesh.GetControlPoints()
        start_point = 0
        poly_paths = []
        for polygon_num in range(lMesh.GetPolygonCount()):
            corners = []
            for corner in range(3):
                corners.append(lMesh.GetPolygonVertex(polygon_num, corner))
            # first, check if any of the control points are already projected
            flattened = []
            for j, corner in enumerate(corners):
                if corner in projected_points:
                    flattened.append(projected_points[corner])
                    continue
                target_corner = corners[j - 1]
                current_vec = control_points[corner]
                target_vec = control_points[target_corner]
                angle = acos(
                    current_vec.DotProduct(target_vec) /
                    (current_vec.Length() * target_vec.Length()))
                length = current_vec.Distance(target_vec)
                # find where the last point was. If it doesn't exist, use the start point
                start_corner = projected_points[target_corner] \
                    if target_corner in projected_points else start_point
                flattened_corner = start_corner + length * (cos(angle) +
                                                            1j * sin(angle))
                projected_points[corner] = flattened_corner
                start_point = flattened_corner
                flattened.append(flattened_corner)
            poly_paths.append(
                Path(*[
                    Line(start=flattened[j], end=flattened[j - 1])
                    for j in range(3)
                ]))

        dwg = Drawing("mesh{}.svg".format(i), profile='tiny')
        for poly_path in poly_paths:
            dwg.add(
                dwg.path(
                    **{
                        'd': poly_path.d(),
                        'fill': "none",
                        'stroke-width': 4,
                        'stroke': rgb(0, 0, 0)
                    }))
        bbox = calc_overall_bbox(poly_paths)
        width, height = abs(bbox[1] - bbox[0]), abs(bbox[3] - bbox[2])
        dwg.viewbox(min(bbox[0], bbox[1]), min(bbox[2], bbox[3]), width,
                    height)
        dwg.save()
Exemplo n.º 5
0
def flatten_shape(i, all_paths, merge_paths):
    dwg = Drawing("merge_output%s.svg" % i, profile='tiny')

    def draw_line(start, end, offset=0.0):
        start += offset
        end += offset
        dwg.add(
            dwg.line(start=(start.real, start.imag),
                     end=(end.real, end.imag),
                     stroke_width=4,
                     stroke=rgb(255, 0, 0)))

    dwg.add(
        dwg.path(
            **{
                'd': all_paths[i].d(),
                'fill': "none",
                'stroke-width': 4,
                'stroke': rgb(0, 0, 0)
            }))
    dwg.add(
        dwg.path(
            **{
                'd': merge_paths[i].d(),
                'fill': "none",
                'stroke-width': 4,
                'stroke': rgb(255, 0, 0)
            }))
    bbox = calc_overall_bbox(all_paths[i])
    width, height = abs(bbox[1] - bbox[0]), abs(bbox[3] - bbox[2])
    margin = 40
    lower = min(bbox[2], bbox[3]) + height + margin
    left = min(bbox[0], bbox[1]) + margin

    def draw_marker(loc, col=rgb(255, 0, 0), offset=(left, lower)):
        dwg.add(
            dwg.circle(center=(loc.real + offset[0], loc.imag + offset[1]),
                       r=4,
                       fill=col))

    max_axis = max(width, height)
    num_lines = 10
    points = [merge_paths[i].point(j / num_lines)
              for j in range(num_lines)] + [merge_paths[i].point(1.0)]
    angles = [
        asin((points[j + 1].imag - points[j].imag) /
             abs(points[j + 1] - points[j])) for j in range(num_lines)
    ]

    ends = [max_axis * (sin(angle) + cos(angle) * 1j) for angle in angles]
    intersection_clips = []
    for j, end in enumerate(ends):
        end_point = end + points[j]
        intersections = other_paths[i].intersect(
            Line(start=points[j], end=end_point))

        for intersection in intersections[0]:
            intersection_point = intersection[1].point(intersection[2])
            target = merge_paths[i].length() * (
                1 - j / num_lines) + abs(intersection_point - points[j]) * 1j
            intersection_clips.append(
                PathClip(index=other_paths[i].index(intersection[1]),
                         t=intersection[2],
                         target=target))
            if j % 10 == 0:
                draw_line(points[j], intersection_point)
                draw_marker(intersection_point, rgb(0, 255, 0), (0, 0))
            break

    # make the flexed points by chopping the chunks of the other paths out, then
    # translating and rotating them such that their end points line up with the diff lines
    def transform_side(sides, targets, angle_offset=0):
        def angle(point1, point2):
            diff = point1 - point2
            if diff.real == 0:
                return 90.0
            return atan(diff.imag / diff.real) * 180.0 / pi

        # change this so that it has two targets
        transformed_side = Path(*sides)
        source_angle = angle(transformed_side.end, transformed_side.start) - \
                       angle(targets[0], targets[1])
        transformed_side = transformed_side.rotated(-source_angle +
                                                    angle_offset)
        source = transformed_side.end if angle_offset == 0 else transformed_side.start
        diff = targets[1] - source
        transformed_side = transformed_side.translated(diff)
        draw_marker(targets[0], rgb(0, 200, 200))
        draw_marker(targets[1], rgb(0, 255, 255))
        transformed_diff = abs(transformed_side.start - transformed_side.end)
        targets_diff = abs(targets[0] - targets[1])
        if transformed_diff < targets_diff:
            transformed_side.insert(
                0, Line(start=targets[0], end=transformed_side.start))
        elif transformed_diff > targets_diff:
            # pop elements off until the transformed diff is smaller
            while transformed_diff > targets_diff:
                transformed_side.pop(0)
                transformed_diff = abs(transformed_side.start -
                                       transformed_side.end)
            print("path", transformed_side)
            print("path is longer", transformed_diff - targets_diff)
        return transformed_side

    start_index = 0
    curr_t = 0
    flexed_path = []
    t_resolution = 0.01
    if intersection_clips[0].index > intersection_clips[-1].index or \
        (intersection_clips[0].index == intersection_clips[-1].index and
         intersection_clips[0].t > intersection_clips[-1].t):
        intersection_clips.reverse()
    # add the end of the shape to the intersection clips
    intersection_clips.append(
        PathClip(index=len(other_paths[i]) - 1,
                 t=1.0,
                 target=merge_paths[i].length()))
    last_target = 0
    for clip in intersection_clips:
        sides = []
        print("boundaries", start_index, clip.index, curr_t, clip.t)
        upper_t = clip.t if start_index == clip.index else 1.0
        while start_index <= clip.index and curr_t < upper_t:
            curr_seg = other_paths[i][start_index]
            while curr_t < upper_t:
                max_t = curr_t + t_resolution if curr_t + t_resolution < clip.t else clip.t
                sides.append(
                    Line(start=curr_seg.point(curr_t),
                         end=curr_seg.point(max_t)))
                curr_t += t_resolution
            curr_t = upper_t
            if start_index != clip.index:
                curr_t = 0.0
            if upper_t == 1.0:
                start_index += 1
                upper_t = clip.t if start_index == clip.index else 1.0
        if len(sides) != 0:
            flexed_path.append(
                transform_side(sides, [last_target, clip.target]))
        last_target = clip.target

    straight_path = [Line(start=0, end=merge_paths[i].length())]
    for p in flexed_path:
        p = p.translated(left + lower * 1j)
        dwg.add(
            dwg.path(d=p.d(),
                     fill="none",
                     stroke_width=4,
                     stroke=rgb(255, 0, 0)))

    transformed_path = flexed_path + straight_path
    transformed_path = Path(*transformed_path).translated(left + lower * 1j)
    dwg.add(
        dwg.path(d=transformed_path.d(),
                 fill="none",
                 stroke_width=4,
                 stroke=rgb(0, 0, 0)))
    bbox = calc_overall_bbox(list(all_paths[i]) + list(transformed_path))

    width, height = abs(bbox[1] - bbox[0]), abs(bbox[3] - bbox[2])
    dwg.viewbox(min(bbox[0], bbox[1]), min(bbox[2], bbox[3]), width, height)
    dwg.save()
    return flexed_path
Exemplo n.º 6
0
 # for each of the shapes, construct a new shape where the section in the merge paths
 # is straight
 merge_paths = [
     Path(*list(all_paths[i])[start_one:end_one]) for i in range(0, 2)
 ]
 other_paths = [
     Path(*list(all_paths[i])[end_one:] + list(all_paths[i])[0:start_one])
     for i in range(0, 2)
 ]
 flexed_paths = [
     flatten_shape(i, all_paths, merge_paths) for i in range(0, 2)
 ]
 dwg = Drawing("flexed_sides.svg", profile="tiny")
 upper_sizes = [0, 0]
 for i, path_list in enumerate(flexed_paths):
     bbox = calc_overall_bbox(path_list)
     if i == 0:
         upper_sizes = [max(bbox[0], bbox[1]), abs(bbox[3] - bbox[2])]
     transform = "scale(1, {})".format(-1 if i == 0 else 1)
     group = dwg.add(dwg.g(transform=transform))
     for path in path_list:
         path = path.translated(-min(bbox[2], bbox[3]) * 1j)
         group.add(
             dwg.path(
                 **{
                     'd': path.d(),
                     'fill': "none",
                     'stroke-width': 4,
                     'stroke': rgb(0, 0, 0)
                 }))
 bbox = calc_overall_bbox(flexed_paths[1])
Exemplo n.º 7
0
    def draw_pattern(self):
        self.output_filename = "{}/snake_tiling_m_{}_{}.svg".format(
            self.output_folder, self.dx, self.dy)
        dwg = Drawing(self.output_filename)
        # add background panel
        background_clippath = dwg.rect(insert=(self.pattern_viewbox[0],
                                               self.pattern_viewbox[1]),
                                       size=('100%', '100%'))
        background_panel = dwg.rect(insert=(self.pattern_viewbox[0],
                                            self.pattern_viewbox[1]),
                                    size=('101%', '101%'),
                                    fill='#3072a2')
        clip_path = dwg.defs.add(dwg.clipPath(id="background_panel"))
        clip_path.add(background_clippath)
        clipped_drawing = dwg.add(
            dwg.g(clip_path="url(#background_panel)", id="clippedpath"))
        clipped_drawing.add(background_panel)
        current_color = 0

        def add_pentagon(group, transform, current_color, draw_pent=True):
            pent_group = group.add(
                dwg.g(transform=format_transform(*transform)))
            if draw_pent:
                pent_group.add(
                    dwg.path(
                        **{
                            'd': self.new_pentagon().d(),
                            'fill': self.colors[current_color %
                                                len(self.colors)],
                            'stroke-width': 4,
                            'stroke': rgb(0, 0, 0)
                        }))
            return pent_group

        for y in range(self.num_down):
            transform = "translate({}, {})".format(0, self.rep_spacing * y)
            dgroup = clipped_drawing.add(dwg.g(transform=transform))
            for x in range(self.num_across):
                # if x is odd, point 1 of pent 1 needs to be attached to point 3 of pent 2
                if x % 2 == 1:
                    dx = int(
                        x / 2
                    ) * self.rep_spacing + self.pent_width * 2 + self.column_offset.real
                    diff = dx + self.column_offset.imag * 1j
                else:
                    diff = int(x / 2) * self.rep_spacing
                for i in range(4):
                    snake_bbox = calc_overall_bbox(self.tile_paths)
                    snake_width, snake_height = abs(snake_bbox[0] - snake_bbox[1]), \
                                                abs(snake_bbox[2] - snake_bbox[3])
                    pent_group = add_pentagon(
                        dgroup,
                        (self.transforms[i][0], self.transforms[i][1] + diff),
                        current_color,
                        draw_pent=False)
                    for i, path in enumerate(self.tile_paths):
                        stransform = 'translate({},{})'.format(
                            snake_width * self.dx, snake_height * self.dy)
                        pent_group.add(
                            dwg.path(
                                **{
                                    'd': path.d(),
                                    'style': self.tile_attributes[i].get(
                                        'style'),
                                    'id': self.tile_attributes[i]['id'],
                                    'transform': stransform
                                }))
                    current_color += 1

        dwg.viewbox(*self.pattern_viewbox)
        dwg.save()