Created
June 14, 2016 03:47
-
-
Save CapnKernel/f1acc650f4ff4991793cd8498d27817b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% extends "hv/base.html" %} | |
| {% load url from future %} | |
| {% block header %}Stencil border generator{% endblock %} | |
| {% block content %} | |
| <h2>Stencil border generator</h2> | |
| <form method="POST"> | |
| {% csrf_token %} | |
| <table border="1"> | |
| {% if form.non_field_errors %} | |
| <tr> | |
| <tr colspan="4">{{ form.non_field_errors }}</tr> | |
| </tr> | |
| {% endif %} | |
| <tr> | |
| <th>Board size</th> | |
| <td>x: {{ form.board_size_x.errors }}{{ form.board_size_x }}</td> | |
| <td>y: {{ form.board_size_y.errors }}{{ form.board_size_y }}</td> | |
| <td>{{ form.board_size_units }}</td> | |
| </tr> | |
| <tr> | |
| <th>Board top left</th> | |
| <td>x: {{ form.board_tl_x.errors }}{{ form.board_tl_x }}</td> | |
| <td>y: {{ form.board_tl_y.errors }}{{ form.board_tl_y }}</td> | |
| <td>{{ form.board_tl_units }}</td> | |
| </tr> | |
| <tr> | |
| <th>Stencil size</th> | |
| <td>x: {{ form.stencil_size_x.errors }}{{ form.stencil_size_x }}</td> | |
| <td>y: {{ form.stencil_size_y.errors }}{{ form.stencil_size_y }}</td> | |
| <td>{{ form.stencil_size_units }}</td> | |
| </tr> | |
| {% comment %}<tr> | |
| <th>Options</th> | |
| <td colspan="3">Up is +ve</td> | |
| </tr> | |
| {% endcomment %}<tr> | |
| <th>Board middle</th> | |
| <td colspan="2">{% if board_middle_x %} ({{ board_middle_x }}, {{ board_middle_y }}){% endif %}</td> | |
| <td>{{ form.board_middle_units }}</td> | |
| </tr> | |
| <tr> | |
| <th>Stencil middle</th> | |
| <td colspan="2">{% if stencil_middle_x %} ({{ stencil_middle_x }}, {{ stencil_middle_y }}){% endif %}</td> | |
| <td>{{ form.stencil_middle_units }}</td> | |
| </tr> | |
| <tr> | |
| <th>Stencil size</th> | |
| <td colspan="2">{% if stencil_size_x %} {{ stencil_size_x }} {{ stencil_size_y }}{% endif %}</td> | |
| <td>{{ form.stencil_translation_units }}</td> | |
| </tr> | |
| </table> | |
| <input type="submit" name="go" value="Calculate" /> | |
| {% if tl %} | |
| <h4>cat > edges.kicad_pcb:</h4> | |
| <textarea cols="60" rows="20">(kicad_pcb (version 4) (host pcbnew 4.0.2-1.fc23-product) | |
| (general | |
| (links 0) | |
| (no_connects 0) | |
| (area 0 0 0 0) | |
| (thickness 1.6) | |
| (drawings 8) | |
| (tracks 0) | |
| (zones 0) | |
| (modules 0) | |
| (nets 1) | |
| ) | |
| (page A3) | |
| (layers | |
| (0 F.Cu signal) | |
| (31 B.Cu signal) | |
| (32 B.Adhes user) | |
| (33 F.Adhes user) | |
| (34 B.Paste user) | |
| (35 F.Paste user) | |
| (36 B.SilkS user) | |
| (37 F.SilkS user) | |
| (38 B.Mask user) | |
| (39 F.Mask user) | |
| (40 Dwgs.User user) | |
| (41 Cmts.User user) | |
| (42 Eco1.User user) | |
| (43 Eco2.User user) | |
| (44 Edge.Cuts user) | |
| ) | |
| (setup | |
| (last_trace_width 0.254) | |
| (trace_clearance 0.254) | |
| (zone_clearance 0.508) | |
| (zone_45_only no) | |
| (trace_min 0.254) | |
| (segment_width 0.2) | |
| (edge_width 0.15) | |
| (via_size 0.889) | |
| (via_drill 0.635) | |
| (via_min_size 0.889) | |
| (via_min_drill 0.508) | |
| (uvia_size 0.508) | |
| (uvia_drill 0.127) | |
| (uvias_allowed no) | |
| (uvia_min_size 0.508) | |
| (uvia_min_drill 0.127) | |
| (pcb_text_width 0.3) | |
| (pcb_text_size 1.5 1.5) | |
| (mod_edge_width 0.15) | |
| (mod_text_size 1.5 1.5) | |
| (mod_text_width 0.15) | |
| (pad_size 1.524 1.524) | |
| (pad_drill 0.762) | |
| (pad_to_mask_clearance 0.2) | |
| (aux_axis_origin 0 0) | |
| (visible_elements FFFFFFBF) | |
| (pcbplotparams | |
| (layerselection 0x01000_00000000) | |
| (usegerberextensions true) | |
| (excludeedgelayer true) | |
| (linewidth 0.100000) | |
| (plotframeref false) | |
| (viasonmask false) | |
| (mode 1) | |
| (useauxorigin false) | |
| (hpglpennumber 1) | |
| (hpglpenspeed 20) | |
| (hpglpendiameter 15) | |
| (hpglpenoverlay 2) | |
| (psnegative false) | |
| (psa4output false) | |
| (plotreference true) | |
| (plotvalue true) | |
| (plotinvisibletext false) | |
| (padsonsilk false) | |
| (subtractmaskfromsilk false) | |
| (outputformat 1) | |
| (mirror false) | |
| (drillshape 0) | |
| (scaleselection 1) | |
| (outputdirectory "")) | |
| ) | |
| (net 0 "") | |
| (net_class Default "This is the default net class." | |
| (clearance 0.254) | |
| (trace_width 0.254) | |
| (via_dia 0.889) | |
| (via_drill 0.635) | |
| (uvia_dia 0.508) | |
| (uvia_drill 0.127) | |
| ) | |
| (gr_line (start {{ bln.x }} {{ bln.y }}) (end {{ tls.x }} {{ tls.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_line (start {{ brw.x }} {{ brw.y }}) (end {{ ble.x }} {{ ble.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_line (start {{ trs.x }} {{ trs.y }}) (end {{ brn.x }} {{ brn.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_line (start {{ tle.x }} {{ tle.y }}) (end {{ trw.x }} {{ trw.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_arc (start {{ ble.x }} {{ bln.y }}) (end {{ ble.x }} {{ ble.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_arc (start {{ brw.x }} {{ brn.y }}) (end {{ brn.x }} {{ brn.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_arc (start {{ trw.x }} {{ trs.y }}) (end {{ trw.x }} {{ trw.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| (gr_arc (start {{ tle.x }} {{ tls.y }}) (end {{ tls.x }} {{ tls.y }}) (angle 90) (layer Edge.Cuts) (width 0.15)) | |
| ) | |
| </textarea> | |
| {% endif %} | |
| </form> | |
| {% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| from decimal import Decimal | |
| from copy import copy | |
| from django.shortcuts import render | |
| from django.contrib import messages | |
| from django.contrib.auth.decorators import login_required | |
| from .forms import StencilBorderForm | |
| from groups import group_required | |
| unit_conversions = { | |
| 'cm': Decimal(10), | |
| 'mm': Decimal(1), | |
| 'in': Decimal(25.4), | |
| 'mil': Decimal(25.4)/1000, | |
| } | |
| def convert_to_mm(length, unit): | |
| return Decimal(length) * unit_conversions[unit] | |
| def convert_from_mm(length, unit): | |
| return Decimal(length) / unit_conversions[unit] | |
| # TODO: Handle up is +ve/-ve | |
| # TODO: Generate a gerber file | |
| # TODO: Do the translation in the gerber file | |
| @login_required | |
| @group_required('backend') | |
| def stencil_border(request): | |
| # GET: Show "stencil param" form | |
| # POST: Accept and validate stencil info, then create it. | |
| data = {} | |
| if request.method == 'POST': | |
| # print "order_change: in POST" | |
| form = StencilBorderForm(request.POST) | |
| if form.is_valid(): | |
| print "stencil_border: form is valid" | |
| print "form.cleaned_data=", form.cleaned_data | |
| # error = False | |
| board_size_x = convert_to_mm(form.cleaned_data['board_size_x'], form.cleaned_data['board_size_units']) | |
| board_size_y = convert_to_mm(form.cleaned_data['board_size_y'], form.cleaned_data['board_size_units']) | |
| board_tl_x = convert_to_mm(form.cleaned_data['board_tl_x'], form.cleaned_data['board_tl_units']) | |
| board_tl_y = convert_to_mm(form.cleaned_data['board_tl_y'], form.cleaned_data['board_tl_units']) | |
| stencil_size_x = convert_to_mm(form.cleaned_data['stencil_size_x'], form.cleaned_data['stencil_size_units']) | |
| stencil_size_y = convert_to_mm(form.cleaned_data['stencil_size_y'], form.cleaned_data['stencil_size_units']) | |
| # print "pre: ssx=", stencil_size_x, "ssy=", stencil_size_y | |
| if form.cleaned_data['stencil_size_x'].startswith('+'): | |
| stencil_size_x = (stencil_size_x * 2) + board_size_x | |
| if form.cleaned_data['stencil_size_y'].startswith('+'): | |
| stencil_size_y = (stencil_size_y * 2) + board_size_y | |
| # print "post: ssx=", stencil_size_x, "ssy=", stencil_size_y | |
| board_middle_x = board_tl_x + (board_size_x / 2) | |
| board_middle_y = board_tl_y - (board_size_y / 2) | |
| stencil_middle_x = stencil_size_x / 2 | |
| stencil_middle_y = -stencil_size_y / 2 | |
| stencil_translation_x = board_middle_x - stencil_middle_x | |
| stencil_translation_y = stencil_middle_y - board_middle_y | |
| radius = 5 | |
| # Top left, top right, bottom left, bottom right | |
| tl = {'x': stencil_translation_x, 'y': stencil_translation_y} | |
| tr = {'x': stencil_translation_x + stencil_size_x, 'y': stencil_translation_y} | |
| bl = {'x': stencil_translation_x, 'y': stencil_translation_y + stencil_size_y} | |
| br = {'x': stencil_translation_x + stencil_size_x, 'y': stencil_translation_y + stencil_size_y} | |
| # tle=top left then east, brw=bottom right then west | |
| tle = copy(tl); tle['x'] += radius | |
| tls = copy(tl); tls['y'] += radius | |
| trw = copy(tr); trw['x'] -= radius | |
| trs = copy(tr); trs['y'] += radius | |
| ble = copy(bl); ble['x'] += radius | |
| bln = copy(bl); bln['y'] -= radius | |
| brw = copy(br); brw['x'] -= radius | |
| brn = copy(br); brn['y'] -= radius | |
| data = { | |
| 'form': form, | |
| 'board_middle_x': convert_from_mm(board_middle_x, form.cleaned_data['board_middle_units']), | |
| 'board_middle_y': convert_from_mm(board_middle_y, form.cleaned_data['board_middle_units']), | |
| 'stencil_middle_x': convert_from_mm(stencil_middle_x, form.cleaned_data['stencil_middle_units']), | |
| 'stencil_middle_y': convert_from_mm(stencil_middle_y, form.cleaned_data['stencil_middle_units']), | |
| 'stencil_size_x': convert_from_mm(stencil_size_x, form.cleaned_data['stencil_translation_units']), | |
| 'stencil_size_y': convert_from_mm(stencil_size_y, form.cleaned_data['stencil_translation_units']), | |
| 'tl': tl, | |
| 'bl': bl, | |
| 'tle': tle, | |
| 'tls': tls, | |
| 'trw': trw, | |
| 'trs': trs, | |
| 'ble': ble, | |
| 'bln': bln, | |
| 'brw': brw, | |
| 'brn': brn, | |
| } | |
| # No point redirecting, as we haven't changed anything. | |
| # return HttpResponseRedirect(reverse('backend.views.order', args={order.hash})) | |
| else: | |
| messages.error(request, 'Invalid data') | |
| else: | |
| data['form'] = StencilBorderForm() | |
| return render(request, 'backend/stencil-border.html', data) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment