#!/usr/bin/python
#
# me2/slice.py - Case slice
#
# Written 2015 by Werner Almesberger
# Copyright 2015 by Werner Almesberger
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#


import FreeCAD, Part
from FreeCAD import Base
from math import sqrt, sin, cos, atan2

#
# Coordinate system:
#
# x = 0: left edge of PCB (short side, next to the antenna)
# y = 0: bottom edge of PCB (where USB comes out)
# z = 0:
#	globally: bottom surface of PCB
#	during bottom shell construction: rim of the bottom shell
#	durint top shell construction: rim of the top shell
#
#


r1 = 9 / 2.0		# radius of the case top
r2 = 14 / 2.0		# radius of the case bottom
ri = 11 / 2.0		# radius of the battery cavity

w = 50			# total width
side = 30.362		# length of a flat side


# ----- Helper functions ------------------------------------------------------


def v(x, y, z):
	return Base.Vector(x, y, z)


def extrude_shape(shape, z):
	wire = Part.Wire(shape.Edges)
	face = Part.Face(wire)

	return face.extrude(v(0, 0, z))


def rect(x, y, z):
	bottom = Part.Line(v(0, 0, 0), v(x, 0, 0))
	top = Part.Line(v(0, y, 0), v(x, y, 0))
	left = Part.Line(v(0, 0, 0), v(0, y, 0))
	right = Part.Line(v(x, 0, 0), v(x, y, 0))

	s = Part.Shape([ bottom, top, left, right ])
	return extrude_shape(s, z)


def cylinder(r, z):
	return Part.makeCylinder(r, z)


def move(obj, x, y, z):
	obj.translate(v(x, y, z))


# ----- Profile ---------------------------------------------------------------

#
#   |x|     t   _______----
#   ______------   ( \  )
#---( \ )     c _ (_ _   )
#  (   - ) -  -   (      )
#   (   ) r1       (    ) r2
# ---------------------------------------------
#     |       b      |
#
# This can be simplified by (r1, r2) -> (0, r2 - r1)
#
#             _____
#       t  __- (\a  )
#       __-   (     )
#      -a      (   )
# ---------------------------
#     |       b      |
#
# a = 2 * atan (r / t)
# t = b
#

def body(r1, r2, b, w):
	a = 2 * atan2(r2 - r1, b)
	t1x = -r1 * sin(a)
	t1y = r1 + r1 * cos(a)
	t2x = b - r2 * sin(a)
	t2y = r2 + r2 * cos(a)
	h1 = Part.Line(v(0, 0, 0), v(b, 0, 0))
	a2 = Part.Arc(v(b, 0, 0), v(b + r2, r2, 0), v(t2x, t2y, 0))
	h2 = Part.Line(v(t2x, t2y, 0), v(t1x, t1y, 0))
	a1 = Part.Arc(v(t1x, t1y, 0), v(-r1, r1, 0), v(0, 0, 0))

	s = Part.Shape([ h1, a2, h2, a1 ])
	return extrude_shape(s, w)


def slice(w, x, y, ang):
	s = body(r1, r2, side, w)

	h = cylinder(ri, w)
	move(h, side, r2, 0)
	s = s.cut(h)

	s.rotate(v(0, 0, 0), v(0, 0, 1), ang)
	move(s, x, y, 0)

	return s


# ----- Assemble things -------------------------------------------------------


def visualize(shape, name, color, trans):
	obj = doc.addObject("Part::Feature", name)
	obj.Shape = shape
	obj.ViewObject.ShapeColor = color
	obj.ViewObject.Transparency = trans


doc = FreeCAD.newDocument()

# weird: parameters say 17.5 mm but the result is 10 mm

s = slice(w, 0, 0, 90)

visualize(s, "Wedge", (0.2, 0.2, 0.2), 80)
s.exportStl("wedge.stl")
