├── .gitignore
├── LICENSE
├── LICENSE-models
├── README.md
├── doc
└── intro.md
├── guide
├── README.org
├── application-of-switches-and-caps.jpg
├── circuit-diagram.png
├── diode-diagram-drive-columns.png
├── diode-diagram-drive-rows.png
├── hotglue-left-hand.jpg
├── left-hand-mcp-1.jpg
├── left-hand-mcp-2.jpg
├── left-hand-pcb-pyralux.png
├── madness.jpg
├── right-hand-pcb-1.jpg
├── right-hand-pcb-pyralux.png
├── right-hand-pcb-with-teensy.jpg
├── rows-and-columns-connected-to-chips.jpg
├── teensy-1.jpg
├── teensy-2-fuxor-reziztorrs.jpg
├── thumb-key-wiring.jpg
├── trrs-jack.jpg
├── wiring-create-columns-left.jpg
├── wiring-create-columns-right.jpg
├── wiring-create-rows-both-sides.jpg
├── wiring-create-rows-testing.jpg
├── wiring_create_rows.jpg
└── workbench.jpg
├── project.clj
├── qmk-guide
├── README.md
├── dactyl-breadboard.jpg
├── dactyl-circuit-diagram.png
├── dactyl-keymapping.png
├── dactyl-left-wiring.jpg
├── dactyl-pull-up-resistors.jpg
├── dactyl-right-wiring.jpg
├── digikey-shopping-cart.csv
├── massdrop-ergodox-build-guide.pdf
└── trrs-diagram.jpg
├── resources
├── Cc-by-nc-sa_icon.svg
├── glamourshot.png
├── pcb-left.svg
├── pcb-right.svg
└── prototype.jpg
├── src
└── dactyl_keyboard
│ ├── dactyl.clj
│ ├── lightcycle.clj
│ ├── util.clj
│ └── wrist.clj
├── target
├── repl-port
└── stale
│ └── extract-native.dependencies
└── test
└── dactyl_cave
└── core_test.clj
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | \#*\#
3 |
4 | .repl-*
5 | .nrepl-*
6 |
7 | .lein-*
8 |
9 | /target
10 | /things
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published by
637 | the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/LICENSE-models:
--------------------------------------------------------------------------------
1 | Attribution-ShareAlike 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More_considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution-ShareAlike 4.0 International Public
58 | License
59 |
60 | By exercising the Licensed Rights (defined below), You accept and agree
61 | to be bound by the terms and conditions of this Creative Commons
62 | Attribution-ShareAlike 4.0 International Public License ("Public
63 | License"). To the extent this Public License may be interpreted as a
64 | contract, You are granted the Licensed Rights in consideration of Your
65 | acceptance of these terms and conditions, and the Licensor grants You
66 | such rights in consideration of benefits the Licensor receives from
67 | making the Licensed Material available under these terms and
68 | conditions.
69 |
70 |
71 | Section 1 -- Definitions.
72 |
73 | a. Adapted Material means material subject to Copyright and Similar
74 | Rights that is derived from or based upon the Licensed Material
75 | and in which the Licensed Material is translated, altered,
76 | arranged, transformed, or otherwise modified in a manner requiring
77 | permission under the Copyright and Similar Rights held by the
78 | Licensor. For purposes of this Public License, where the Licensed
79 | Material is a musical work, performance, or sound recording,
80 | Adapted Material is always produced where the Licensed Material is
81 | synched in timed relation with a moving image.
82 |
83 | b. Adapter's License means the license You apply to Your Copyright
84 | and Similar Rights in Your contributions to Adapted Material in
85 | accordance with the terms and conditions of this Public License.
86 |
87 | c. BY-SA Compatible License means a license listed at
88 | creativecommons.org/compatiblelicenses, approved by Creative
89 | Commons as essentially the equivalent of this Public License.
90 |
91 | d. Copyright and Similar Rights means copyright and/or similar rights
92 | closely related to copyright including, without limitation,
93 | performance, broadcast, sound recording, and Sui Generis Database
94 | Rights, without regard to how the rights are labeled or
95 | categorized. For purposes of this Public License, the rights
96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
97 | Rights.
98 |
99 | e. Effective Technological Measures means those measures that, in the
100 | absence of proper authority, may not be circumvented under laws
101 | fulfilling obligations under Article 11 of the WIPO Copyright
102 | Treaty adopted on December 20, 1996, and/or similar international
103 | agreements.
104 |
105 | f. Exceptions and Limitations means fair use, fair dealing, and/or
106 | any other exception or limitation to Copyright and Similar Rights
107 | that applies to Your use of the Licensed Material.
108 |
109 | g. License Elements means the license attributes listed in the name
110 | of a Creative Commons Public License. The License Elements of this
111 | Public License are Attribution and ShareAlike.
112 |
113 | h. Licensed Material means the artistic or literary work, database,
114 | or other material to which the Licensor applied this Public
115 | License.
116 |
117 | i. Licensed Rights means the rights granted to You subject to the
118 | terms and conditions of this Public License, which are limited to
119 | all Copyright and Similar Rights that apply to Your use of the
120 | Licensed Material and that the Licensor has authority to license.
121 |
122 | j. Licensor means the individual(s) or entity(ies) granting rights
123 | under this Public License.
124 |
125 | k. Share means to provide material to the public by any means or
126 | process that requires permission under the Licensed Rights, such
127 | as reproduction, public display, public performance, distribution,
128 | dissemination, communication, or importation, and to make material
129 | available to the public including in ways that members of the
130 | public may access the material from a place and at a time
131 | individually chosen by them.
132 |
133 | l. Sui Generis Database Rights means rights other than copyright
134 | resulting from Directive 96/9/EC of the European Parliament and of
135 | the Council of 11 March 1996 on the legal protection of databases,
136 | as amended and/or succeeded, as well as other essentially
137 | equivalent rights anywhere in the world.
138 |
139 | m. You means the individual or entity exercising the Licensed Rights
140 | under this Public License. Your has a corresponding meaning.
141 |
142 |
143 | Section 2 -- Scope.
144 |
145 | a. License grant.
146 |
147 | 1. Subject to the terms and conditions of this Public License,
148 | the Licensor hereby grants You a worldwide, royalty-free,
149 | non-sublicensable, non-exclusive, irrevocable license to
150 | exercise the Licensed Rights in the Licensed Material to:
151 |
152 | a. reproduce and Share the Licensed Material, in whole or
153 | in part; and
154 |
155 | b. produce, reproduce, and Share Adapted Material.
156 |
157 | 2. Exceptions and Limitations. For the avoidance of doubt, where
158 | Exceptions and Limitations apply to Your use, this Public
159 | License does not apply, and You do not need to comply with
160 | its terms and conditions.
161 |
162 | 3. Term. The term of this Public License is specified in Section
163 | 6(a).
164 |
165 | 4. Media and formats; technical modifications allowed. The
166 | Licensor authorizes You to exercise the Licensed Rights in
167 | all media and formats whether now known or hereafter created,
168 | and to make technical modifications necessary to do so. The
169 | Licensor waives and/or agrees not to assert any right or
170 | authority to forbid You from making technical modifications
171 | necessary to exercise the Licensed Rights, including
172 | technical modifications necessary to circumvent Effective
173 | Technological Measures. For purposes of this Public License,
174 | simply making modifications authorized by this Section 2(a)
175 | (4) never produces Adapted Material.
176 |
177 | 5. Downstream recipients.
178 |
179 | a. Offer from the Licensor -- Licensed Material. Every
180 | recipient of the Licensed Material automatically
181 | receives an offer from the Licensor to exercise the
182 | Licensed Rights under the terms and conditions of this
183 | Public License.
184 |
185 | b. Additional offer from the Licensor -- Adapted Material.
186 | Every recipient of Adapted Material from You
187 | automatically receives an offer from the Licensor to
188 | exercise the Licensed Rights in the Adapted Material
189 | under the conditions of the Adapter's License You apply.
190 |
191 | c. No downstream restrictions. You may not offer or impose
192 | any additional or different terms or conditions on, or
193 | apply any Effective Technological Measures to, the
194 | Licensed Material if doing so restricts exercise of the
195 | Licensed Rights by any recipient of the Licensed
196 | Material.
197 |
198 | 6. No endorsement. Nothing in this Public License constitutes or
199 | may be construed as permission to assert or imply that You
200 | are, or that Your use of the Licensed Material is, connected
201 | with, or sponsored, endorsed, or granted official status by,
202 | the Licensor or others designated to receive attribution as
203 | provided in Section 3(a)(1)(A)(i).
204 |
205 | b. Other rights.
206 |
207 | 1. Moral rights, such as the right of integrity, are not
208 | licensed under this Public License, nor are publicity,
209 | privacy, and/or other similar personality rights; however, to
210 | the extent possible, the Licensor waives and/or agrees not to
211 | assert any such rights held by the Licensor to the limited
212 | extent necessary to allow You to exercise the Licensed
213 | Rights, but not otherwise.
214 |
215 | 2. Patent and trademark rights are not licensed under this
216 | Public License.
217 |
218 | 3. To the extent possible, the Licensor waives any right to
219 | collect royalties from You for the exercise of the Licensed
220 | Rights, whether directly or through a collecting society
221 | under any voluntary or waivable statutory or compulsory
222 | licensing scheme. In all other cases the Licensor expressly
223 | reserves any right to collect such royalties.
224 |
225 |
226 | Section 3 -- License Conditions.
227 |
228 | Your exercise of the Licensed Rights is expressly made subject to the
229 | following conditions.
230 |
231 | a. Attribution.
232 |
233 | 1. If You Share the Licensed Material (including in modified
234 | form), You must:
235 |
236 | a. retain the following if it is supplied by the Licensor
237 | with the Licensed Material:
238 |
239 | i. identification of the creator(s) of the Licensed
240 | Material and any others designated to receive
241 | attribution, in any reasonable manner requested by
242 | the Licensor (including by pseudonym if
243 | designated);
244 |
245 | ii. a copyright notice;
246 |
247 | iii. a notice that refers to this Public License;
248 |
249 | iv. a notice that refers to the disclaimer of
250 | warranties;
251 |
252 | v. a URI or hyperlink to the Licensed Material to the
253 | extent reasonably practicable;
254 |
255 | b. indicate if You modified the Licensed Material and
256 | retain an indication of any previous modifications; and
257 |
258 | c. indicate the Licensed Material is licensed under this
259 | Public License, and include the text of, or the URI or
260 | hyperlink to, this Public License.
261 |
262 | 2. You may satisfy the conditions in Section 3(a)(1) in any
263 | reasonable manner based on the medium, means, and context in
264 | which You Share the Licensed Material. For example, it may be
265 | reasonable to satisfy the conditions by providing a URI or
266 | hyperlink to a resource that includes the required
267 | information.
268 |
269 | 3. If requested by the Licensor, You must remove any of the
270 | information required by Section 3(a)(1)(A) to the extent
271 | reasonably practicable.
272 |
273 | b. ShareAlike.
274 |
275 | In addition to the conditions in Section 3(a), if You Share
276 | Adapted Material You produce, the following conditions also apply.
277 |
278 | 1. The Adapter's License You apply must be a Creative Commons
279 | license with the same License Elements, this version or
280 | later, or a BY-SA Compatible License.
281 |
282 | 2. You must include the text of, or the URI or hyperlink to, the
283 | Adapter's License You apply. You may satisfy this condition
284 | in any reasonable manner based on the medium, means, and
285 | context in which You Share Adapted Material.
286 |
287 | 3. You may not offer or impose any additional or different terms
288 | or conditions on, or apply any Effective Technological
289 | Measures to, Adapted Material that restrict exercise of the
290 | rights granted under the Adapter's License You apply.
291 |
292 |
293 | Section 4 -- Sui Generis Database Rights.
294 |
295 | Where the Licensed Rights include Sui Generis Database Rights that
296 | apply to Your use of the Licensed Material:
297 |
298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
299 | to extract, reuse, reproduce, and Share all or a substantial
300 | portion of the contents of the database;
301 |
302 | b. if You include all or a substantial portion of the database
303 | contents in a database in which You have Sui Generis Database
304 | Rights, then the database in which You have Sui Generis Database
305 | Rights (but not its individual contents) is Adapted Material,
306 |
307 | including for purposes of Section 3(b); and
308 | c. You must comply with the conditions in Section 3(a) if You Share
309 | all or a substantial portion of the contents of the database.
310 |
311 | For the avoidance of doubt, this Section 4 supplements and does not
312 | replace Your obligations under this Public License where the Licensed
313 | Rights include other Copyright and Similar Rights.
314 |
315 |
316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
317 |
318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
328 |
329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
338 |
339 | c. The disclaimer of warranties and limitation of liability provided
340 | above shall be interpreted in a manner that, to the extent
341 | possible, most closely approximates an absolute disclaimer and
342 | waiver of all liability.
343 |
344 |
345 | Section 6 -- Term and Termination.
346 |
347 | a. This Public License applies for the term of the Copyright and
348 | Similar Rights licensed here. However, if You fail to comply with
349 | this Public License, then Your rights under this Public License
350 | terminate automatically.
351 |
352 | b. Where Your right to use the Licensed Material has terminated under
353 | Section 6(a), it reinstates:
354 |
355 | 1. automatically as of the date the violation is cured, provided
356 | it is cured within 30 days of Your discovery of the
357 | violation; or
358 |
359 | 2. upon express reinstatement by the Licensor.
360 |
361 | For the avoidance of doubt, this Section 6(b) does not affect any
362 | right the Licensor may have to seek remedies for Your violations
363 | of this Public License.
364 |
365 | c. For the avoidance of doubt, the Licensor may also offer the
366 | Licensed Material under separate terms or conditions or stop
367 | distributing the Licensed Material at any time; however, doing so
368 | will not terminate this Public License.
369 |
370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
371 | License.
372 |
373 |
374 | Section 7 -- Other Terms and Conditions.
375 |
376 | a. The Licensor shall not be bound by any additional or different
377 | terms or conditions communicated by You unless expressly agreed.
378 |
379 | b. Any arrangements, understandings, or agreements regarding the
380 | Licensed Material not stated herein are separate from and
381 | independent of the terms and conditions of this Public License.
382 |
383 |
384 | Section 8 -- Interpretation.
385 |
386 | a. For the avoidance of doubt, this Public License does not, and
387 | shall not be interpreted to, reduce, limit, restrict, or impose
388 | conditions on any use of the Licensed Material that could lawfully
389 | be made without permission under this Public License.
390 |
391 | b. To the extent possible, if any provision of this Public License is
392 | deemed unenforceable, it shall be automatically reformed to the
393 | minimum extent necessary to make it enforceable. If the provision
394 | cannot be reformed, it shall be severed from this Public License
395 | without affecting the enforceability of the remaining terms and
396 | conditions.
397 |
398 | c. No term or condition of this Public License will be waived and no
399 | failure to comply consented to unless expressly agreed to by the
400 | Licensor.
401 |
402 | d. Nothing in this Public License constitutes or may be interpreted
403 | as a limitation upon, or waiver of, any privileges and immunities
404 | that apply to the Licensor or You, including from the legal
405 | processes of any jurisdiction or authority.
406 |
407 |
408 | =======================================================================
409 |
410 | Creative Commons is not a party to its public
411 | licenses. Notwithstanding, Creative Commons may elect to apply one of
412 | its public licenses to material it publishes and in those instances
413 | will be considered the “Licensor.” The text of the Creative Commons
414 | public licenses is dedicated to the public domain under the CC0 Public
415 | Domain Dedication. Except for the limited purpose of indicating that
416 | material is shared under a Creative Commons public license or as
417 | otherwise permitted by the Creative Commons policies published at
418 | creativecommons.org/policies, Creative Commons does not authorize the
419 | use of the trademark "Creative Commons" or any other trademark or logo
420 | of Creative Commons without its prior written consent including,
421 | without limitation, in connection with any unauthorized modifications
422 | to any of its public licenses or any other arrangements,
423 | understandings, or agreements concerning use of licensed material. For
424 | the avoidance of doubt, this paragraph does not form part of the
425 | public licenses.
426 |
427 | Creative Commons may be contacted at creativecommons.org.
428 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The Ex-Dactyl Keyboard
2 | The Ex-Dactyl is an extended version of Dactyl keyboard, which is a parameterized, split-hand, concave, columnar, ergonomic keyboard.
3 |
4 | 
5 | 
6 |
7 | You can download it from [Thingiverse](https://www.thingiverse.com/thing:3815317)
8 |
9 | ## Assembly
10 |
11 | ### Generating a Design
12 |
13 | **Setting up the Clojure environment**
14 | * [Install the Clojure runtime](https://clojure.org)
15 | * [Install the Leiningen project manager](http://leiningen.org/)
16 | * [Install OpenSCAD](http://www.openscad.org/)
17 |
18 | **Generating the design**
19 | * Run `lein repl`
20 | * Load the file `(load-file "src/dactyl_keyboard/dactyl.clj")`
21 | * This will regenerate the `things/*.scad` files
22 | * Use OpenSCAD to open a `.scad` file.
23 | * Make changes to design, repeat `load-file`, OpenSCAD will watch for changes and rerender.
24 | * When done, use OpenSCAD to export STL files
25 |
26 | **Tips**
27 | * [Some other ways to evaluate the clojure design file](http://stackoverflow.com/a/28213489)
28 | * [Example designing with clojure](http://adereth.github.io/blog/2014/04/09/3d-printing-with-clojure/)
29 |
30 |
31 | ### Printing
32 | Pregenerated STL files are available in the [things/](things/) directory after generation.
33 |
34 | ### Wiring
35 | Masks for the flexible PCBs I used are available for the [left](resources/pcb-left.svg) and [right](resources/pcb-right.svg) side.
36 |
37 | A [very rough guide for the brave is here](guide/README.org#wiring) - It will be improved over time (**TODO**)!
38 |
39 | ## License
40 |
41 | Copyright © 2015 Matthew Adereth
42 |
43 | The source code for generating the models (everything excluding the [things/](things/) and [resources/](resources/) directories is distributed under the [GNU AFFERO GENERAL PUBLIC LICENSE Version 3](LICENSE). The generated models and PCB designs are distributed under the [Creative Commons Attribution-ShareAlike License Version 4.0](LICENSE-models).
44 |
--------------------------------------------------------------------------------
/doc/intro.md:
--------------------------------------------------------------------------------
1 | # Introduction to dactyl-cave
2 |
3 | TODO: write [great documentation](http://jacobian.org/writing/great-documentation/what-to-write/)
4 |
--------------------------------------------------------------------------------
/guide/README.org:
--------------------------------------------------------------------------------
1 | * Preparation and Cost
2 | Get all the parts / raw material:
3 | - For the 3D printing there are two options:
4 | 1. Filament, which is the basis for 3D printing. Luckily I could print at my work-place
5 | which reduced the cost from 210€ to 70€. The kind of filament you need depends on the 3D
6 | printer you have available.
7 | 2. Buy the printout of adareth's model at shapeways for 210€ over here
8 | http://www.shapeways.com/designer/adereth/creations
9 | - Decide on the switches
10 | - If you are going to invest a whole lot of time and money for a custom keyboard instead of
11 | buying one for 10€ I'd recommend to use your favorite switch-type. To make a
12 | well-informed decision I bought a switch-tester for this from massdrop and decided on
13 | Cherry MX Whites. https://www.massdrop.com/buy/varmilo-switch-tester-with-anodized-case
14 | - I ordered 70 Cherry MX Whites from here:
15 | https://mechanicalkeyboards.com/shop/index.php?l=product_detail&p=847
16 | - Decide on the key caps
17 | - On the glamour shot you can see the 1976 keycap set; it used to be sold over here:
18 | http://pimpmykeyboard.com/sa-1976-keycap-set/ but the link is dead right now. You could
19 | try this link: https://www.massdrop.com/buy/nineteenseventysix-sa-keycap-set but it is a
20 | massdrop which is way different from usual online-stores. If you find a site that sells
21 | these, make sure you get the right amount and type of keys according to the layout.
22 | - I got the "TKL Base Set + TKL Modifier" from over here:
23 | http://pimpmykeyboard.com/dsa-pbt-abs-blank-keycap-sets/ but I'm still two long keys
24 | short, I will have to order those specifically and I have a bunch of keys I don't use
25 | left-over.
26 | - The USB-Cable that connects the keyboard to your computer
27 | - It's an USB 2.0 to USB Mini-B cable, make sure you get one that is 2 meters long, it
28 | really makes handling the keyboard so much more comfortable
29 | - https://www.amazon.de/gp/product/B00NH11N5A/
30 | - The main controller (right half)
31 | - A Teensy 2.0, I got that one from here: https://www.pjrc.com/store/teensy.html
32 | - The chip, connectors and cable to give life to the left half
33 | - TRRS cable and jacks
34 | - Got my TRRS cable from here: http://www.digikey.de/product-search/de?keywords=839-1257-ND
35 | - Got my TRRS jacks from here: http://www.digikey.de/product-search/de?keywords=CP-43514-ND
36 | - MCP23018 16 bit IO Expander
37 | - Got mine from here: http://www.digikey.de/product-search/de?keywords=MCP23018-E%2FSP-ND
38 |
39 | What I spend on my keyboard (should give you a rough estimate for your build):
40 | | item | cost |
41 | |-----------------------------------+------|
42 | | filament | 70 |
43 | | switch-tester | 30 |
44 | | key-caps | 70 |
45 | | teensy 2.0 | 30 |
46 | | switches | 60 |
47 | | usb cable | 10 |
48 | | IO Expander, TRRS jacks and cable | 30 |
49 | |-----------------------------------+------|
50 | | overall cost | 300 |
51 | #+TBLFM: @9$2=vsum(@2$2..@8$2)
52 |
53 | My choices / advantages:
54 | - Using the soldering iron at the uni-workshop for free
55 | - 76 Diodes for free
56 | - Soldering wire and copper for free
57 | - All the resistors used for free (5 resistors are used)
58 | - Several files for working out the rough edges of the 3D-printout
59 |
60 | Depending on what you have available you might spend more or less money than me; however, 300€
61 | is a good rough estimate.
62 |
63 | After all the parts have arrived it is safe to move on to the next section.
64 |
65 | * Wiring
66 | It is assumed that you have printed the casing successfully.
67 |
68 | 1) Plug the switches into the casing. No glue is needed; the casing provides the perfect fit.
69 | 2) Put the keycaps on the switches
70 | - Note that in the pictures here some of the long keys on the thumb-part are too short;
71 | that's why it doesn't look symmetrical
72 |
73 | [[file:application-of-switches-and-caps.jpg]]
74 |
75 | Now going further on in the guide there are two options
76 | 1. The first option is to print flexible PCBs. The advantage is that you save a lot of wiring
77 | business, everything looks rather clean and you don't have to worry about your cables being too
78 | thick such that the casing doesn't close. However, if you don't have the means to print out such
79 | PCBs there is the second option, wiring everything by hand.
80 | - The guide for this PCB-option is very rough indeed and it doesn't include the firmware
81 | used. Wiring and firmware play extremely close together--wiring before knowing your
82 | firmware is like buying a shoe without measuring your feet before. For this option,
83 | information about the exact firmware is not published, this in addition to the fact that
84 | the pictures in this rough guide are incomplete makes this option extremely
85 | beginner-unfriendly. Going in blind-sided like this may lead to one of these things:
86 | 1. reprogramming huge parts of the firmware to match your wiring, which comes with a ton of
87 | debugging.
88 | 2. rewiring to adapt to what the firmware expects, which may easily double your work here.
89 | - [[Route 1: Dactyl Flexible PCB Rough Guide]]
90 | 2. The second option is to hand-wire everything. For people like me, who had never soldered before,
91 | this was great pain and pleasure.
92 | - Here too firmware and wiring go hand in hand, you pretty much have to have a detailed look
93 | at the firmware you are using before wiring anything. I provide my modification of the
94 | "ergodox-firmware" over here: https://github.com/BubblesToTheLimit/ergodox-firmware
95 | - TODO: Make a successfull pull-request, such that it is available in the official
96 | ergodox-firmware
97 | - Some of the steps of this guide may not be described in much detail, but in contrast to
98 | option one there is a whole lot more information.
99 | - [[Route 2: Dactyl Hand-Wiring Guide]]
100 |
101 | ** Route 1: Dactyl Flexible PCB Rough Guide
102 | [[workbench.jpg]]
103 |
104 | For now, take a look at the images and try to figure things out; I know that's not great (it's
105 | better than nothing!)
106 |
107 | *** Making the PCB
108 | Get two sheets of 6in square Pyralux™. Use the Toner Transfer method to etch the Pyralux sheets as
109 | you would a usual PCB
110 |
111 | #+BEGIN_QUOTE
112 | NOTE: If you only have an Inkjet make photocopies of the print out. Voilà, Toner based copies!
113 | #+END_QUOTE
114 |
115 | [[http://www.instructables.com/id/Toner-transfer-no-soak-high-quality-double-sided/][Here's a handy toner transfer guide ...]]
116 |
117 | Print these PCB designs out...
118 |
119 | Left hand:
120 |
121 | [[left-hand-pcb-pyralux.png]]
122 |
123 | Right hand:
124 |
125 | [[right-hand-pcb-pyralux.png]]
126 |
127 | When you're done etching, you'll need to carefully cut the pcb into pieces... See the images
128 | below.
129 |
130 | *** Applying the PCB to the electronical parts
131 | The thumb cluster pcb for the left hand:
132 |
133 | [[madness.jpg]]
134 |
135 | Solder the MCP like so:
136 |
137 | [[left-hand-mcp-1.jpg]]
138 | [[left-hand-mcp-2.jpg]]
139 |
140 | Solder the Teensy 2.0 like so:
141 |
142 | [[teensy-1.jpg]]
143 |
144 | The two 2.2kΩ (Red Red Red Gold) pull-up resistors ensure a clear signal between the USB controller and the I/O expander.
145 | [[https://learn.sparkfun.com/tutorials/pull-up-resistors][Read more about pull-up resistors here]].
146 |
147 | [[teensy-2-fuxor-reziztorrs.jpg]]
148 |
149 | Each hand of the keyboard will wire up like so:
150 |
151 | [[right-hand-pcb-1.jpg]]
152 |
153 | Teensy goes here... note the rows soldered to the teensy via the Pyralux:
154 |
155 | [[right-hand-pcb-with-teensy.jpg]]
156 |
157 | Here the left hand:
158 |
159 | [[hotglue-left-hand.jpg]]
160 |
161 | ** Route 2: Dactyl Hand-Wiring Guide
162 | *** Step 1: Creating the rows
163 | Using the copper wire you solder each row together, notice how the thumb-part gets its own
164 | row. If you take a close look you can see how I did do a messy job soldering, I had to redo
165 | some of the parts because they weren't soldered properly. Do this for both sides. It doesn't
166 | matter which of the two available pins of each switch you chose for the row, but for it to
167 | look clean you should decide for either one of them.
168 |
169 | [[file:wiring_create_rows.jpg]]
170 |
171 | [[file:wiring-create-rows-both-sides.jpg]]
172 |
173 | You might want to go ahead and test each one of the 70 switches with a multimeter.
174 |
175 | [[file:wiring-create-rows-testing.jpg]]
176 |
177 | *** Step 2: Create the columns
178 | The next step is to create the columns by soldering the diodes. There are two options for
179 | soldering the diodes, all heading towards the switch or all heading away from the
180 | switch. These two ways are called "row-driven" or "column-driven" and here again it is
181 | cruciual for the firmware and the actual wiring to be on the same page.
182 |
183 | [[file:diode-diagram-drive-columns.png]]
184 |
185 | [[file:diode-diagram-drive-rows.png]]
186 |
187 | If you want to try and use the "tmk_keyboard" firmware which seems to be also interesting you
188 | want to wire the diodes in the according way (check whether the tmk_keyboard firmware expects
189 | a row-driven or a column-driven setup).
190 |
191 | As you can see in these following pictures, I went for the "row-driven" setup (visible by the
192 | direction of the diodes, the black line being towards the key-switches). This first picture
193 | doesn't show how the 6 thumb-keys are actually individually connected to the 6 main columns,
194 | but note the small black line on each diode.
195 |
196 | [[file:wiring-create-columns-left.jpg]]
197 |
198 | This second picture shows how the 6 thumb-keys are actually connected to the 6 main columns.
199 |
200 | [[file:wiring-create-columns-right.jpg]]
201 |
202 | How thumb-keys are wired again depends on the firmware. The following picture shows the wiring
203 | of the thumb keys more clearly and also the part in the code that reflects this wiring
204 | (ergodox-firmware/src/keyboard/dactyl/matrix.h).
205 |
206 | [[file:thumb-key-wiring.jpg]]
207 |
208 | *** Step 3: Put the Teensy and the MCP in place
209 | This next step is to wire the Teensy 2.0 and the MCP 23018 in place.
210 | Everything necessary for that really is the following circuit diagram.
211 |
212 | [[file:circuit-diagram.png]]
213 |
214 | Things to note here:
215 | - The columns for the MCP go from 0 to 6, the columns for the Teensy go from 7 to D (counting
216 | in hexadecimal) which makes great sense, since the MCP is to the left of the Teensy and we
217 | read from left to right.
218 | - When debugging this and using the ergodox-firmware, both sides have to be wired completely
219 | and actually with the TRRS connected. Don't expect the keyboard to work before that. The
220 | reason is that the ergodox-firmware stops completely if either the Teensy or the MCP weren't
221 | initiated properly.
222 | - The LEDs are handy for debugging; definitely go ahead and connect those. When the keyboard
223 | starts successfully two of the LEDs light up shortly.
224 | - From the Teensy over to the MCP go exactly 4 connections. The blue, the red and the two green
225 | ones. This is done using the TRRS jacks and cable.
226 | - Yes, the connection from B4 to VCC doesn't seem to make any sense, but the B4 port actually
227 | gets used directly in the ergodox-firmware, so just connect those connections that make no
228 | sense on first sight and either don't question it or find out why this is necessary by going
229 | through the firmware in great detail.
230 |
231 | This is how the trrs jacks are wired:
232 |
233 | [[file:trrs-jack.jpg]]
234 |
235 | After you are done you might have the following result:
236 |
237 | [[file:rows-and-columns-connected-to-chips.jpg]]
238 |
239 | Good luck!
240 |
--------------------------------------------------------------------------------
/guide/application-of-switches-and-caps.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/application-of-switches-and-caps.jpg
--------------------------------------------------------------------------------
/guide/circuit-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/circuit-diagram.png
--------------------------------------------------------------------------------
/guide/diode-diagram-drive-columns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/diode-diagram-drive-columns.png
--------------------------------------------------------------------------------
/guide/diode-diagram-drive-rows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/diode-diagram-drive-rows.png
--------------------------------------------------------------------------------
/guide/hotglue-left-hand.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/hotglue-left-hand.jpg
--------------------------------------------------------------------------------
/guide/left-hand-mcp-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/left-hand-mcp-1.jpg
--------------------------------------------------------------------------------
/guide/left-hand-mcp-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/left-hand-mcp-2.jpg
--------------------------------------------------------------------------------
/guide/left-hand-pcb-pyralux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/left-hand-pcb-pyralux.png
--------------------------------------------------------------------------------
/guide/madness.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/madness.jpg
--------------------------------------------------------------------------------
/guide/right-hand-pcb-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/right-hand-pcb-1.jpg
--------------------------------------------------------------------------------
/guide/right-hand-pcb-pyralux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/right-hand-pcb-pyralux.png
--------------------------------------------------------------------------------
/guide/right-hand-pcb-with-teensy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/right-hand-pcb-with-teensy.jpg
--------------------------------------------------------------------------------
/guide/rows-and-columns-connected-to-chips.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/rows-and-columns-connected-to-chips.jpg
--------------------------------------------------------------------------------
/guide/teensy-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/teensy-1.jpg
--------------------------------------------------------------------------------
/guide/teensy-2-fuxor-reziztorrs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/teensy-2-fuxor-reziztorrs.jpg
--------------------------------------------------------------------------------
/guide/thumb-key-wiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/thumb-key-wiring.jpg
--------------------------------------------------------------------------------
/guide/trrs-jack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/trrs-jack.jpg
--------------------------------------------------------------------------------
/guide/wiring-create-columns-left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/wiring-create-columns-left.jpg
--------------------------------------------------------------------------------
/guide/wiring-create-columns-right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/wiring-create-columns-right.jpg
--------------------------------------------------------------------------------
/guide/wiring-create-rows-both-sides.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/wiring-create-rows-both-sides.jpg
--------------------------------------------------------------------------------
/guide/wiring-create-rows-testing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/wiring-create-rows-testing.jpg
--------------------------------------------------------------------------------
/guide/wiring_create_rows.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/wiring_create_rows.jpg
--------------------------------------------------------------------------------
/guide/workbench.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/guide/workbench.jpg
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject dactyl-keyboard "0.1.0-SNAPSHOT"
2 | :description "A parametrized, split-hand, concave, columnar, erogonomic keyboard"
3 | :url "http://example.com/FIXME"
4 | :license {:name "Eclipse Public License"
5 | :url "http://www.eclipse.org/legal/epl-v10.html"}
6 | :dependencies [[org.clojure/clojure "1.7.0"]
7 | [unicode-math "0.2.0"]
8 | [scad-clj "0.4.0"]])
9 |
10 |
11 |
--------------------------------------------------------------------------------
/qmk-guide/README.md:
--------------------------------------------------------------------------------
1 | # The EZ Way to QMK
2 |
3 | Do you love your Kinesis Advantage, but also love your Ergodox-EZ? Now you can
4 | have the best of both worlds with your very own QMK running Dactyl! Feels like a
5 | Kinesis, works like an Ergodox-EZ.
6 |
7 | I found this [Massdrop guide](massdrop-ergodox-build-guide.pdf) that shipped with their original
8 | Ergodox to be very helpful.
9 |
10 | ## Shopping List
11 |
12 | ### Things you'll have to find yourself:
13 |
14 | * Case
15 | * 70x Cherry MX compatible Switches
16 | * 6x Cherry ML switches (optional)
17 |
18 |
19 | ### Things you can order from Digikey
20 |
21 | #### An aside on LEDs
22 |
23 | Before you place this order, you'll need to figure out what color you want your
24 | LEDs to be, or if you even want LEDs at all.
25 |
26 | I had a terrible time figuring out how to figure out which resistor to use with
27 | each LED. All I can attest to is that
28 | [These Orange LEDs](http://www.maxkeyboard.com/max-keyboard-orange-3mm-flangeless-replacement-led-for-backlit-mechanical-keyboard-10-pcs.html)
29 | work with
30 | [These 220Ω resistors](http://www.digikey.com/scripts/DkSearch/dksus.dll?Detail&itemSeq=229354283&uq=636318134508631803)
31 | or at least have yet to fail in my Dactyl.
32 |
33 | I was hoping that I could find these LEDs on Digikey for you, but they don't
34 | have ones with the exact specs and I don't know if that breaks the compatibility
35 | with the resistors I found.
36 |
37 | Here's
38 | [the evil mad scientist's guide](http://www.evilmadscientist.com/2012/resistors-for-leds/)
39 | to choosing resistors for LEDs, but every time I did the math, it didn't work
40 | out.
41 |
42 | Seriously, find someone who knows more about this if you're making decisions
43 | here. You're probably already more qualified than me, so open a PR and fix this
44 | session.
45 |
46 | * 70x [1N4148 Diodes](http://www.digikey.com/scripts/DkSearch/dksus.dll?Detail&itemSeq=229354375&uq=636318149504319926)
47 | * 2x [2.2kΩ Pull up Resistors](https://www.digikey.com/product-detail/en/CFR-25JB-52-2K2/2.2KQBK-ND/666)
48 | * 2x [TRRS Jacks](http://www.digikey.com/scripts/DkSearch/dksus.dll?Detail&itemSeq=229354247&uq=636318148338283334)
49 | * 1 [Teensy 2.0](https://www.digikey.com/product-detail/en/adafruit-industries-llc/199/1528-1993-ND/6827126)
50 | * 1 [MCP23018 I/O Expander](https://www.digikey.com/product-detail/en/microchip-technology/MCP23018-E-SP/MCP23018-E-SP-ND/1999505)
51 | * [28 Pin IC Socket](http://www.digikey.com/scripts/DkSearch/dksus.dll?Detail&itemSeq=229356912&uq=636318143621851738)
52 |
53 | If you want everything in this list from [Digikey](https://www.digikey.com), you
54 | can upload [this cart](digikey-shopping-cart.csv).
55 |
56 | ### Things From Amazon
57 |
58 | * 1x [MiniUSB Extender Cable](https://www.amazon.com/gp/product/B00B5HSA3Q)
59 | * Solder/Electrical Tape/Twosided tape
60 | * [30AWG wrapping wire](https://www.amazon.com/gp/product/B00GWFECWO)
61 | * TRRS Cable [this one](https://www.amazon.com/Coiled-3-5mm-Jack-Audio-Cable/dp/B019TRW4HQ)
62 | worked for me, but it's a matter of taste and how much distance you need.
63 |
64 | ## Wiring up the Matrix
65 |
66 | The firmware you choose will determine the wiring of the keyboard. Since the
67 | Ergodox-EZ isn't going anywhere **AND** has first class support in QMK by its
68 | creator, it makes pretty good sense to wire it up the same way.
69 |
70 | Here's what the matrix code for the Ergodox-EZ in QMK looks like:
71 |
72 | ```c
73 | // matrix positions
74 | { // MCP23018
75 | { k00, k10, k20, k30, k40, KC_NO }, \
76 | { k01, k11, k21, k31, k41, k51 }, \
77 | { k02, k12, k22, k32, k42, k52 }, \
78 | { k03, k13, k23, k33, k43, k53 }, \
79 | { k04, k14, k24, k34, k44, k54 }, \
80 | { k05, k15, k25, k35, KC_NO, k55 }, \
81 | { k06, k16, KC_NO, k36, KC_NO, k56 }, \
82 | // Teensy
83 | { k07, k17, KC_NO, k37, KC_NO, k57 }, \
84 | { k08, k18, k28, k38, KC_NO, k58 }, \
85 | { k09, k19, k29, k39, k49, k59 }, \
86 | { k0A, k1A, k2A, k3A, k4A, k5A }, \
87 | { k0B, k1B, k2B, k3B, k4B, k5B }, \
88 | { k0C, k1C, k2C, k3C, k4C, k5C }, \
89 | { k0D, k1D, k2D, k3D, k4D, KC_NO } \
90 | }
91 | ```
92 |
93 | This is a software mapping of 14 rows, even though the physical layout will wind
94 | up with 14 columns. Physically, it looks like this:
95 |
96 | 
97 |
98 | Look at those colors, they'll be consistent throughout this documentation,
99 | including the physical wire we wire it up with.
100 |
101 | ### Rows
102 |
103 | You don't have to decide how to connect the rows to the Teensy or MCP yet. Just
104 | worry about getting the matrix right.
105 |
106 | Wiring rows 0-4 is easy. With the 30AWG wire, I had to cut individual wire
107 | segments from switch to switch. The thumb clusters are Row 5 on each side, so
108 | the same approach will work, it just doesn't look like a row.
109 |
110 | Row 5 is the thumb cluster, so just wire them together and imagine they're in a
111 | row instead of it being more like a circle.
112 |
113 | The rows are just wire. Individual segments connecting two switches. I used a
114 | pair of pointy tweezers to put little hooks on the end of each segment. The idea
115 | is to let the Solder do most of the work. If a day ever comes where you have to
116 | desolder one of these, you'll be glad you didn't aggressively wrap it.
117 |
118 | ### Columns
119 |
120 | The columns need to be wired with diodes. You can probably wire the entire
121 | column with the diode stems, but I chose to add some wire segments so it would
122 | look clearer for this guide.
123 |
124 | 
125 |
126 | The diodes need the black bar facing away from the key. The other guides
127 | disagree, but they don't use QMK.
128 |
129 | To use wire segments here, I soldered the end of the diode with the black bar to
130 | the wire first, then placed the other stem on the switch, positioned the diode
131 | where I wanted it and then bet the diode stem into a hook around the switch
132 | terminal.
133 |
134 | I also made a habit of keeping the trimmed diode stems to use as bridges if
135 | needed later.
136 |
137 | **Note:** Column 6 only has one key at this point.
138 |
139 | ### Ergodox Compatibility Inner Columns
140 |
141 | **This is an optional step, and can be done as a mod after you're done** so
142 | there's no pressure to make this decision now.
143 |
144 | Ergodoxes have an additional three keys in columns 6 & 7. Do you want them on
145 | your Dactyl?
146 |
147 | I own an Ergodox-EZ as well, and want to use the same keymap for both. So I
148 | added the extra switches below the thumb clusters as Cherry ML switches. If you
149 | don't care about a consistent experience between a Dactyl and Ergodox, or even
150 | if you do, it's a matter of personal preference.
151 |
152 | Wherever you put them, they're wired into rows 0,1 and 3. Either way, you need
153 | to wire columns 6 and 7 to the top inner most key in the thumb cluster, so
154 | columns 6 & 7 are going to be live.
155 |
156 | If you go with MLs, you can put them wherever you want, but be careful measuring
157 | where the holes go, you only get one shot.
158 |
159 | **TODO:** CherryML switch hole specs.
160 |
161 | ## The Matrix Has You
162 |
163 | Actually, you have it! Congratulations on having gotten this far.
164 |
165 | ## Wiring The Right Half
166 |
167 | ### Wiring the Teensy
168 |
169 | We have to start off with the obligatory wiring diagram
170 |
171 | 
172 |
173 | Notice the row numbers are different from the other guides to match the QMK
174 | key codes we're using.
175 |
176 | I started off by breadboarding this whole project, but I also burnt out the
177 | teensy's bootloader.
178 | [My misadventures wiring a Dactyl](http://joedevivo.com/2017/05/20/building-a-qmk-dactyl.html)
179 | are a fun read if you feel like this is too hard. I've been there.
180 |
181 | Here's the pinout mappings for the rows and columns:
182 |
183 | | Row | Wire Color | Teensy Pin |
184 | |---------|------------|------------|
185 | | 0 | Yellow | PF0 |
186 | | 1 | Orange | PF1 |
187 | | 2 | Green | PF4 |
188 | | 3 | Brown | PF5 |
189 | | 4 | Blue | PF6 |
190 | | 5 | Purple | PF7 |
191 |
192 |
193 | | Column | Wire Color | Teensy Pin |
194 | |--------|------------|------------|
195 | | 7 | Red | PB0 |
196 | | 8 | Yellow | PB1 |
197 | | 9 | Orange | PB2 |
198 | | A | Green | PB3 |
199 | | B | Brown | PD2 |
200 | | C | Blue | PD3 |
201 | | D | Purple | PC6 |
202 |
203 | Wiring the teensy involves looping the 30AWG wire through the Teensy's pinouts,
204 | I went through twice, and then dabbed a little solder. If you are ok with
205 | possibly wasting a little wire, you can use longer wire to solder up the Teensy
206 | and then breadboard with those wires. There's no room for pins in the case, so
207 | this is the best way to test it out.
208 |
209 | Here's my breadboarded version, almost done. (missing the reset wire to the MCP
210 | in this photo)
211 |
212 | 
213 |
214 | Yours will look similar, but with the Teensy coming from off board with a bunch
215 | of wires. You don't have to breadboard the columns and rows for the teensy, you
216 | can test them by clipping them to the right spot on the matrix you built.
217 |
218 | Columns and rows run by the MCP (Greetings, program!) will be accessible via the
219 | breadboard.
220 |
221 | Here's what that looks like wired in.
222 |
223 | 
224 |
225 | Fortunately, QMK *will* let you just run the right half, so you can check in at
226 | this point and see how that all works,
227 |
228 | ### The TRRS Jack
229 |
230 | In an effort to move some of the bulk away from the Teensy, I put the pull up
231 | resistors as close to the jack as I could.
232 |
233 | 
234 |
235 | I wired the two 2.2k resistors to the bottom two terminals on the TRRS jack,
236 | then wired the SCL(PD0) and SDA(PD1) to the resistor leg going into the jack.
237 | Then soldered the outside legs together and ran a wire from Vcc to those outside
238 | legs, and from them to a third terminal on the TRRS jack. Now all you need is to
239 | run GND to the fourth terminal.
240 |
241 | 
242 |
243 | ## Wiring The Left Half
244 |
245 | ### Wiring the I/O Expander
246 |
--------------------------------------------------------------------------------
/qmk-guide/dactyl-breadboard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-breadboard.jpg
--------------------------------------------------------------------------------
/qmk-guide/dactyl-circuit-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-circuit-diagram.png
--------------------------------------------------------------------------------
/qmk-guide/dactyl-keymapping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-keymapping.png
--------------------------------------------------------------------------------
/qmk-guide/dactyl-left-wiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-left-wiring.jpg
--------------------------------------------------------------------------------
/qmk-guide/dactyl-pull-up-resistors.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-pull-up-resistors.jpg
--------------------------------------------------------------------------------
/qmk-guide/dactyl-right-wiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/dactyl-right-wiring.jpg
--------------------------------------------------------------------------------
/qmk-guide/digikey-shopping-cart.csv:
--------------------------------------------------------------------------------
1 | Index,Quantity,Part Number,Description,Customer Reference,Available Quantity,Backorder Quantity,Unit Price USD,Extended Price USD,
2 | 1,2,CP-43514-ND,CONN JACK 4COND 3.5MM R/A,,2,0,1.06000,2.12,
3 | 2,2,2.2KQBK-ND,RES 2.2K OHM 1/4W 5% AXIAL,,2,0,0.10000,0.20,
4 | 3,3,220QBK-ND,RES 220 OHM 1/4W 5% AXIAL,,3,0,0.10000,0.30,
5 | 4,1,1528-1993-ND,TEENSY (ATMEGA32U4 USB DEV BOARD,,1,0,19.94000,19.94,
6 | 5,100,1N4148FS-ND,DIODE GEN PURP 100V 200MA DO35,,100,0,0.03080,3.08,
7 | 6,10,ED3050-5-ND,CONN IC DIP SOCKET 28POS TIN,,10,0,0.31500,3.15,
8 | 7,1,MCP23018-E/SP-ND,IC I/O EXPANDER I2C 16B 28SDIP,,1,0,1.56000,1.56,
9 |
--------------------------------------------------------------------------------
/qmk-guide/massdrop-ergodox-build-guide.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/massdrop-ergodox-build-guide.pdf
--------------------------------------------------------------------------------
/qmk-guide/trrs-diagram.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/qmk-guide/trrs-diagram.jpg
--------------------------------------------------------------------------------
/resources/Cc-by-nc-sa_icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
25 |
--------------------------------------------------------------------------------
/resources/glamourshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/resources/glamourshot.png
--------------------------------------------------------------------------------
/resources/prototype.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSChyi/ex-dactyl-keyboard/1b2f6eb881d64e4b05f281d210fe5cb40e3f27a1/resources/prototype.jpg
--------------------------------------------------------------------------------
/src/dactyl_keyboard/lightcycle.clj:
--------------------------------------------------------------------------------
1 | (ns dactyl-keyboard.lightcycle
2 | (:refer-clojure :exclude [use import])
3 | (:require [scad-clj.scad :refer :all]
4 | [scad-clj.model :refer :all]
5 | [dactyl-keyboard.util :refer :all]
6 | [unicode-math.core :refer :all]))
7 |
8 | ;;;;;;;;;;;;;;;;;
9 | ;; Switch Hole ;;
10 | ;;;;;;;;;;;;;;;;;
11 |
12 | (def keyswitch-height 14.4) ;; Was 14.1, then 14.25
13 | (def keyswitch-width 14.4)
14 |
15 | (def sa-profile-key-height 12.7)
16 |
17 | (def plate-thickness 4)
18 | (def mount-width (+ keyswitch-width 3))
19 | (def mount-height (+ keyswitch-height 3))
20 |
21 | #_(def single-plate
22 | (let [top-wall (->> (cube (+ keyswitch-width 3) 1.5 plate-thickness)
23 | (translate [0
24 | (+ (/ 1.5 2) (/ keyswitch-height 2))
25 | (/ plate-thickness 2)]))
26 | left-wall (->> (cube 1.5 (+ keyswitch-height 3) plate-thickness)
27 | (translate [(+ (/ 1.5 2) (/ keyswitch-width 2))
28 | 0
29 | (/ plate-thickness 2)]))
30 | side-nub (->> (binding [*fn* 30] (cylinder 1 2.75))
31 | (rotate (/ π 2) [1 0 0])
32 | (translate [(+ (/ keyswitch-width 2)) 0 1])
33 | (hull (->> (cube 1.5 2.75 plate-thickness)
34 | (translate [(+ (/ 1.5 2) (/ keyswitch-width 2))
35 | 0
36 | (/ plate-thickness 2)]))))
37 | plate-half (union top-wall left-wall (with-fn 100 side-nub))]
38 | (union plate-half
39 | (->> plate-half
40 | (mirror [1 0 0])
41 | (mirror [0 1 0])))))
42 |
43 | (def alps-width 15.6)
44 | (def alps-notch-width 15.5)
45 | (def alps-notch-height 1)
46 | (def alps-height 13)
47 |
48 | (def single-plate
49 | (let [top-wall (->> (cube (+ keyswitch-width 3) 2.2 plate-thickness)
50 | (translate [0
51 | (+ (/ 2.2 2) (/ alps-height 2))
52 | (/ plate-thickness 2)]))
53 | left-wall (union (->> (cube 1.5 (+ keyswitch-height 3) plate-thickness)
54 | (translate [(+ (/ 1.5 2) (/ 15.6 2))
55 | 0
56 | (/ plate-thickness 2)]))
57 | (->> (cube 1.5 (+ keyswitch-height 3) 1.0)
58 | (translate [(+ (/ 1.5 2) (/ alps-notch-width 2))
59 | 0
60 | (- plate-thickness
61 | (/ alps-notch-height 2))]))
62 | )
63 | plate-half (union top-wall left-wall)]
64 | (union plate-half
65 | (->> plate-half
66 | (mirror [1 0 0])
67 | (mirror [0 1 0])))))
68 |
69 |
70 | ;;;;;;;;;;;;;;;;
71 | ;; SA Keycaps ;;
72 | ;;;;;;;;;;;;;;;;
73 |
74 | (def sa-length 18.25)
75 | (def sa-double-length 37.5)
76 | (def sa-cap {1 (let [bl2 (/ 18.5 2)
77 | m (/ 17 2)
78 | key-cap (hull (->> (polygon [[bl2 bl2] [bl2 (- bl2)] [(- bl2) (- bl2)] [(- bl2) bl2]])
79 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
80 | (translate [0 0 0.05]))
81 | (->> (polygon [[m m] [m (- m)] [(- m) (- m)] [(- m) m]])
82 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
83 | (translate [0 0 6]))
84 | (->> (polygon [[6 6] [6 -6] [-6 -6] [-6 6]])
85 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
86 | (translate [0 0 12])))]
87 | (->> key-cap
88 | (translate [0 0 (+ 5 plate-thickness)])
89 | (color [220/255 163/255 163/255 1])))
90 | 2 (let [bl2 (/ sa-double-length 2)
91 | bw2 (/ 18.25 2)
92 | key-cap (hull (->> (polygon [[bw2 bl2] [bw2 (- bl2)] [(- bw2) (- bl2)] [(- bw2) bl2]])
93 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
94 | (translate [0 0 0.05]))
95 | (->> (polygon [[6 16] [6 -16] [-6 -16] [-6 16]])
96 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
97 | (translate [0 0 12])))]
98 | (->> key-cap
99 | (translate [0 0 (+ 5 plate-thickness)])
100 | (color [127/255 159/255 127/255 1])))
101 | 1.5 (let [bl2 (/ 18.25 2)
102 | bw2 (/ 28 2)
103 | key-cap (hull (->> (polygon [[bw2 bl2] [bw2 (- bl2)] [(- bw2) (- bl2)] [(- bw2) bl2]])
104 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
105 | (translate [0 0 0.05]))
106 | (->> (polygon [[11 6] [-11 6] [-11 -6] [11 -6]])
107 | (extrude-linear {:height 0.1 :twist 0 :convexity 0})
108 | (translate [0 0 12])))]
109 | (->> key-cap
110 | (translate [0 0 (+ 5 plate-thickness)])
111 | (color [240/255 223/255 175/255 1])))})
112 |
113 | ;;;;;;;;;;;;;;;;;;;;;;;;;
114 | ;; Placement Functions ;;
115 | ;;;;;;;;;;;;;;;;;;;;;;;;;
116 |
117 | (def columns (range 0 6))
118 | (def rows (range 1 5))
119 |
120 | (def α (/ π 12))
121 | (def β (/ π 36))
122 | (def cap-top-height (+ plate-thickness sa-profile-key-height))
123 | (def row-radius (+ (/ (/ (+ mount-height 1/2) 2)
124 | (Math/sin (/ α 2)))
125 | cap-top-height))
126 | (def column-radius (+ (/ (/ (+ mount-width 2.0) 2)
127 | (Math/sin (/ β 2)))
128 | cap-top-height))
129 |
130 | (defn key-place [column row shape]
131 | (let [row-placed-shape (->> shape
132 | (translate [0 0 (- row-radius)])
133 | (rotate (* α (- 2 row)) [1 0 0])
134 | (translate [0 0 row-radius]))
135 | column-offset (cond
136 | (= column 2) [0 2.82 -3.0] ;;was moved -4.5
137 | (>= column 4) [0 -5.8 5.64]
138 | :else [0 0 0])
139 | column-angle (* β (- 2 column))
140 | placed-shape (->> row-placed-shape
141 | (translate [0 0 (- column-radius)])
142 | (rotate column-angle [0 1 0])
143 | (translate [0 0 column-radius])
144 | (translate column-offset))]
145 | (->> placed-shape
146 | (rotate (/ π 12) [0 1 0])
147 | (translate [0 0 13]))))
148 |
149 | (defn case-place [column row shape]
150 | (let [row-placed-shape (->> shape
151 | (translate [0 0 (- row-radius)])
152 | (rotate (* α (- 2 row)) [1 0 0])
153 | (translate [0 0 row-radius]))
154 | column-offset [0 -4.35 5.64]
155 | column-angle (* β (- 2 column))
156 | placed-shape (->> row-placed-shape
157 | (translate [0 0 (- column-radius)])
158 | (rotate column-angle [0 1 0])
159 | (translate [0 0 column-radius])
160 | (translate column-offset))]
161 | (->> placed-shape
162 | (rotate (/ π 12) [0 1 0])
163 | (translate [0 0 13]))))
164 |
165 | (def key-holes
166 | (apply union
167 | (for [column columns
168 | row rows
169 | :when (or (not= column 0)
170 | (not= row 4))]
171 | (->> single-plate
172 | (key-place column row)))))
173 |
174 | (def caps
175 | (apply union
176 | (for [column columns
177 | row rows
178 | :when (or (not= column 0)
179 | (not= row 4))]
180 | (->> (sa-cap (if (= column 5) 1 1))
181 | (key-place column row)))))
182 |
183 | ;;;;;;;;;;;;;;;;;;;;
184 | ;; Web Connectors ;;
185 | ;;;;;;;;;;;;;;;;;;;;
186 |
187 | (def web-thickness 3.5)
188 | (def post-size 0.1)
189 | (def web-post (->> (cube post-size post-size web-thickness)
190 | (translate [0 0 (+ (/ web-thickness -2)
191 | plate-thickness)])))
192 |
193 | (def post-adj (/ post-size 2))
194 | (def web-post-tr (translate [(- (/ mount-width 2) post-adj) (- (/ mount-height 2) post-adj) 0] web-post))
195 | (def web-post-tl (translate [(+ (/ mount-width -2) post-adj) (- (/ mount-height 2) post-adj) 0] web-post))
196 | (def web-post-bl (translate [(+ (/ mount-width -2) post-adj) (+ (/ mount-height -2) post-adj) 0] web-post))
197 | (def web-post-br (translate [(- (/ mount-width 2) post-adj) (+ (/ mount-height -2) post-adj) 0] web-post))
198 |
199 | (def connectors
200 | (apply union
201 | (concat
202 | ;; Row connections
203 | (for [column (drop-last columns)
204 | row rows
205 | :when (or (not= column 0)
206 | (not= row 4))]
207 | (triangle-hulls
208 | (key-place (inc column) row web-post-tl)
209 | (key-place column row web-post-tr)
210 | (key-place (inc column) row web-post-bl)
211 | (key-place column row web-post-br)))
212 |
213 | ;; Column connections
214 | (for [column columns
215 | row (drop-last rows)
216 | :when (or (not= column 0)
217 | (not= row 3))]
218 | (triangle-hulls
219 | (key-place column row web-post-bl)
220 | (key-place column row web-post-br)
221 | (key-place column (inc row) web-post-tl)
222 | (key-place column (inc row) web-post-tr)))
223 |
224 | ;; Diagonal connections
225 | (for [column (drop-last columns)
226 | row (drop-last rows)
227 | :when (or (not= column 0)
228 | (not= row 3))]
229 | (triangle-hulls
230 | (key-place column row web-post-br)
231 | (key-place column (inc row) web-post-tr)
232 | (key-place (inc column) row web-post-bl)
233 | (key-place (inc column) (inc row) web-post-tl))))))
234 |
235 | ;;;;;;;;;;;;
236 | ;; Thumbs ;;
237 | ;;;;;;;;;;;;
238 |
239 | (defn thumb-place [column row shape]
240 | (let [cap-top-height (+ plate-thickness sa-profile-key-height)
241 | α (/ π 12)
242 | row-radius (+ (/ (/ (+ mount-height 1) 2)
243 | (Math/sin (/ α 2)))
244 | cap-top-height)
245 | β (/ π 36)
246 | column-radius (+ (/ (/ (+ mount-width 2) 2)
247 | (Math/sin (/ β 2)))
248 | cap-top-height)
249 | #_(+ (/ (/ (+ pillar-width 5) 2)
250 | (Math/sin (/ β 2)))
251 | cap-top-height)]
252 | (->> shape
253 | (translate [0 0 (- row-radius)])
254 | (rotate (* α row) [1 0 0])
255 | (translate [0 0 row-radius])
256 | (translate [0 0 (- column-radius)])
257 | (rotate (* column β) [0 1 0])
258 | (translate [0 0 column-radius])
259 | (translate [mount-width 0 0])
260 | (rotate (* π (- 1/4 3/16)) [0 0 1])
261 | (rotate (/ π 12) [1 1 0])
262 | (translate [-52 -45 40]))))
263 |
264 | (defn thumb-2x-column [shape]
265 | (thumb-place 0 -1/2 (rotate (/ π 2) [0 0 1] shape)))
266 |
267 | (defn thumb-2x+1-column [shape]
268 | (union (thumb-place 1 -1/2 (rotate (/ π 2) [0 0 1] shape))
269 | (thumb-place 1 1 shape)))
270 |
271 | (defn thumb-1x-column [shape]
272 | (union (thumb-place 2 -1 shape)
273 | (thumb-place 2 0 shape)
274 | (thumb-place 2 1 shape)))
275 |
276 |
277 |
278 | (= (* 2 sa-length)
279 | sa-double-length)
280 | (def double-plates
281 | (let [plate-height (/ (- sa-double-length mount-height) 2)
282 | top-plate (->> (cube mount-width plate-height web-thickness)
283 | (translate [0 (/ (+ plate-height mount-height) 2)
284 | (- plate-thickness (/ web-thickness 2))]))
285 | stabilizer-cutout (union (->> (cube 14.2 3.5 web-thickness)
286 | (translate [0.5 12 (- plate-thickness (/ web-thickness 2))])
287 | (color [1 0 0 1/2]))
288 | (->> (cube 16 3.5 web-thickness)
289 | (translate [0.5 12 (- plate-thickness (/ web-thickness 2) 1.4)])
290 | (color [1 0 0 1/2])))
291 | ;;top-plate (difference top-plate stabilizer-cutout)
292 | ]
293 | (color [1 0 0] (union top-plate (mirror [0 1 0] top-plate)))))
294 |
295 | (defn extended-plate-height [size] (/ (- (* (+ 1 sa-length) size) mount-height) 2))
296 |
297 | (defn extended-plates [size]
298 | (let [plate-height (extended-plate-height size)
299 | top-plate (->> (cube mount-width plate-height web-thickness)
300 | (translate [0 (/ (+ plate-height mount-height) 2)
301 | (- plate-thickness (/ web-thickness 2))]))]
302 | (color [0 1 1] (union top-plate (mirror [0 1 0] top-plate)))
303 | ))
304 |
305 | (defn thumb-layout [shape]
306 | (union
307 | (thumb-place 0 -1/2 (union shape (extended-plates 2)))
308 |
309 | (thumb-place 1 7/8 (union shape (extended-plates 1.25)))
310 | (thumb-place 1 -5/8 (union shape (extended-plates 1.75)))
311 |
312 | (thumb-place 2 -3/4 (union shape (extended-plates 1.5)))
313 | (thumb-place 2 3/4 (union shape (extended-plates 1.5)))
314 | ))
315 |
316 | (defn thumb-layout-bottom [shape]
317 | (union
318 | (thumb-place 0 -1/2 shape)
319 |
320 | (thumb-place 1 7/8 shape)
321 | (thumb-place 1 -5/8 shape)
322 |
323 | (thumb-place 2 -3/4 shape)
324 | (thumb-place 2 3/4 shape)
325 | ))
326 |
327 | (def thumbcaps
328 | (union
329 | (thumb-2x-column (sa-cap 2))
330 | (thumb-place 1 -1/2 (sa-cap 2))
331 | (thumb-place 1 1 (sa-cap 1))
332 | (thumb-1x-column (sa-cap 1))))
333 |
334 | (def thumb-connectors
335 | (union
336 | #_(apply union
337 | (concat
338 | (for [column [2] row [1]]
339 | (triangle-hulls (thumb-place column row web-post-br)
340 | (thumb-place column row web-post-tr)
341 | (thumb-place (dec column) row web-post-bl)
342 | (thumb-place (dec column) row web-post-tl)))
343 | (for [column [2] row [0 1]]
344 | (triangle-hulls
345 | (thumb-place column row web-post-bl)
346 | (thumb-place column row web-post-br)
347 | (thumb-place column (dec row) web-post-tl)
348 | (thumb-place column (dec row) web-post-tr)))))
349 | (let [thumb-tl #(->> web-post-tl
350 | (translate [0 (extended-plate-height %) 0]))
351 | thumb-bl #(->> web-post-bl
352 | (translate [0 (- (extended-plate-height %)) 0]))
353 | thumb-tr #(->> web-post-tr
354 | (translate [0 (extended-plate-height %) 0]))
355 | thumb-br #(->> web-post-br
356 | (translate [0 (- (extended-plate-height %)) 0]))]
357 | (union
358 |
359 | ;;Connecting the double to 1.75
360 | (triangle-hulls (thumb-place 0 -1/2 (thumb-tl 2))
361 | (thumb-place 0 -1/2 (thumb-bl 2))
362 | (thumb-place 1 -5/8 (thumb-br 1.75))
363 | (thumb-place 0 -1/2 (thumb-tl 2))
364 | (thumb-place 1 -5/8 (thumb-tr 1.75))
365 | (thumb-place 1 7/8 (thumb-br 1.25)))
366 |
367 | (triangle-hulls (thumb-place 1 7/8 (thumb-br 1.25))
368 | (thumb-place 1 7/8 (thumb-bl 1.25))
369 | (thumb-place 1 -5/8 (thumb-tr 1.75))
370 | (thumb-place 1 -5/8 (thumb-tl 1.75)))
371 |
372 | (triangle-hulls (thumb-place 2 3/4 (thumb-br 1.5))
373 | (thumb-place 2 3/4 (thumb-bl 1.5))
374 | (thumb-place 2 -3/4 (thumb-tr 1.5))
375 | (thumb-place 2 -3/4 (thumb-tl 1.5)))
376 |
377 | (triangle-hulls (thumb-place 2 3/4 (thumb-br 1.5))
378 | (thumb-place 2 3/4 (thumb-bl 1.5))
379 | (thumb-place 2 -3/4 (thumb-tr 1.5))
380 | (thumb-place 2 -3/4 (thumb-tl 1.5)))
381 |
382 | (triangle-hulls (thumb-place 2 -3/4 (thumb-br 1.5))
383 | (thumb-place 1 -5/8 (thumb-bl 1.75))
384 | (thumb-place 2 -3/4 (thumb-tr 1.5))
385 | (thumb-place 1 -5/8 (thumb-tl 1.75))
386 | (thumb-place 2 3/4 (thumb-br 1.5))
387 | (thumb-place 1 7/8 (thumb-bl 1.25))
388 | (thumb-place 2 3/4 (thumb-tr 1.5))
389 | (thumb-place 1 7/8 (thumb-tl 1.25))
390 | )
391 |
392 |
393 | ;;Connecting the thumb to everything
394 | (triangle-hulls (thumb-place 0 -1/2 (thumb-br 2))
395 | (key-place 1 4 web-post-bl)
396 | (thumb-place 0 -1/2 (thumb-tr 2))
397 | (key-place 1 4 web-post-tl)
398 | (key-place 1 3 web-post-bl)
399 | (thumb-place 0 -1/2 (thumb-tr 2))
400 | (key-place 0 3 web-post-br)
401 | (key-place 0 3 web-post-bl)
402 | (thumb-place 0 -1/2 (thumb-tr 2))
403 | (thumb-place 0 -1/2 (thumb-tl 2))
404 | (key-place 0 3 web-post-bl)
405 | (thumb-place 1 -5/8 (thumb-tr 1.75))
406 | (thumb-place 1 7/8 (thumb-br 1.25))
407 | (key-place 0 3 web-post-bl)
408 | (key-place 0 3 web-post-tl)
409 | (thumb-place 1 7/8 (thumb-br 1.25))
410 | (thumb-place 1 7/8 (thumb-tr 1.25))
411 | )))))
412 |
413 | (def thumb
414 |
415 | (union
416 | (thumb-layout (rotate (/ Math/PI 2) [0 0 1] single-plate))
417 | (color [1 0 0] thumb-connectors)
418 |
419 | #_(thumb-place 0 -1/2 (extended-plates 2))
420 | #_(thumb-place 1 -1/2 double-plates)))
421 |
422 | ;;;;;;;;;;
423 | ;; Case ;;
424 | ;;;;;;;;;;
425 |
426 | ;; In column units
427 | (def right-wall-column (+ (last columns) 0.55))
428 | (def left-wall-column (- (first columns) 1/2))
429 | (def thumb-back-y 0.93)
430 | (def thumb-right-wall (- -1/2 0.05))
431 | (def thumb-front-row (+ -1 0.07))
432 | (def thumb-left-wall-column (+ 5/2 0.05))
433 | (def back-y (+ (first rows) #_0.02 -0.15))
434 |
435 | (defn range-inclusive [start end step]
436 | (concat (range start end step) [end]))
437 |
438 | (def wall-step 0.2)
439 | (def wall-sphere-n 20) ;;Sphere resolution, lower for faster renders
440 |
441 | (defn wall-sphere-at [coords]
442 | (->> (sphere 1)
443 | (translate coords)
444 | (with-fn wall-sphere-n)))
445 |
446 | (defn scale-to-range [start end x]
447 | (+ start (* (- end start) x)))
448 |
449 | (defn wall-sphere-bottom [front-to-back-scale]
450 | (wall-sphere-at [0
451 | (scale-to-range
452 | (+ (/ mount-height -2) -3.5)
453 | (+ (/ mount-height 2) 5.0)
454 | front-to-back-scale)
455 | -6]))
456 |
457 | (defn wall-sphere-top [front-to-back-scale]
458 | (wall-sphere-at [0
459 | (scale-to-range
460 | (+ (/ mount-height -2) -3.5)
461 | (+ (/ mount-height 2) 3.5)
462 | front-to-back-scale)
463 | 5]))
464 |
465 | (def wall-sphere-top-back (wall-sphere-top 1))
466 | (def wall-sphere-bottom-back (wall-sphere-bottom 1))
467 | (def wall-sphere-bottom-front (wall-sphere-bottom 0))
468 | (def wall-sphere-top-front (wall-sphere-top 0))
469 |
470 | (defn top-case-cover [place-fn sphere
471 | x-start x-end
472 | y-start y-end
473 | step]
474 | (apply union
475 | (for [x (range-inclusive x-start (- x-end step) step)
476 | y (range-inclusive y-start (- y-end step) step)]
477 | (hull (place-fn x y sphere)
478 | (place-fn (+ x step) y sphere)
479 | (place-fn x (+ y step) sphere)
480 | (place-fn (+ x step) (+ y step) sphere)))))
481 |
482 | (def front-wall
483 | (let [step wall-step ;;0.1
484 | wall-step 0.05 ;;0.05
485 | place case-place
486 | top-cover (fn [x-start x-end y-start y-end]
487 | (top-case-cover place wall-sphere-top-front
488 | x-start x-end y-start y-end
489 | wall-step))]
490 | (union
491 | (apply union
492 | (for [x (range-inclusive 0.7 (- right-wall-column step) step)]
493 | (hull (place x 4 wall-sphere-top-front)
494 | (place (+ x step) 4 wall-sphere-top-front)
495 | (place x 4 wall-sphere-bottom-front)
496 | (place (+ x step) 4 wall-sphere-bottom-front))))
497 | (apply union
498 | (for [x (range-inclusive 0.5 0.7 0.01)]
499 | (hull (place x 4 wall-sphere-top-front)
500 | (place (+ x step) 4 wall-sphere-top-front)
501 | (place 0.7 4 wall-sphere-bottom-front))))
502 | (top-cover 0.5 1.7 3.6 4)
503 | (top-cover 1.59 2.41 3.42 4) ;; was 3.32
504 | (top-cover 2.39 3.41 3.6 4)
505 | (apply union
506 | (for [x (range 2 5)]
507 | (union
508 | (hull (place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
509 | (place (+ x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
510 | (key-place x 4 web-post-bl)
511 | (key-place x 4 web-post-br))
512 | (hull (place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
513 | (key-place x 4 web-post-bl)
514 | (key-place (- x 1) 4 web-post-br)))))
515 | (hull (place right-wall-column 4 (translate [0 1 1] wall-sphere-bottom-front))
516 | (place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front))
517 | (key-place 5 4 web-post-bl)
518 | (key-place 5 4 web-post-br))
519 | (hull (place (+ 4 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
520 | (place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front))
521 | (key-place 4 4 web-post-br)
522 | (key-place 5 4 web-post-bl))
523 | (hull (place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front))
524 | (place 1.7 4 (translate [0 1 1] wall-sphere-bottom-front))
525 | (key-place 1 4 web-post-bl)
526 | (key-place 1 4 web-post-br)))))
527 |
528 | (def back-wall
529 | (let [back-row (first rows)
530 | step wall-step
531 | wall-sphere-top-backtep 0.05
532 | place case-place
533 | front-top-cover (fn [x-start x-end y-start y-end]
534 | (apply union
535 | (for [x (range-inclusive x-start (- x-end wall-sphere-top-backtep) wall-sphere-top-backtep)
536 | y (range-inclusive y-start (- y-end wall-sphere-top-backtep) wall-sphere-top-backtep)]
537 | (hull (place x y wall-sphere-top-back)
538 | (place (+ x wall-sphere-top-backtep) y wall-sphere-top-back)
539 | (place x (+ y wall-sphere-top-backtep) wall-sphere-top-back)
540 | (place (+ x wall-sphere-top-backtep) (+ y wall-sphere-top-backtep) wall-sphere-top-back)))))]
541 | (union
542 | (apply union
543 | (for [x (range-inclusive left-wall-column (- right-wall-column step) step)]
544 | (hull (place x back-y wall-sphere-top-back)
545 | (place (+ x step) back-y wall-sphere-top-back)
546 | (place x back-y wall-sphere-bottom-back)
547 | (place (+ x step) back-y wall-sphere-bottom-back))))
548 | ;; (front-top-cover left-wall-column 1.56 back-y (+ back-y 0.06))
549 | #_(front-top-cover left-wall-column right-wall-column back-y (+ back-y 0.06))
550 | ;; (front-top-cover 1.56 2.44 back-y (+ back-y 0.06))
551 | (front-top-cover 3.56 4.44 back-y (+ back-y 0.2))
552 | (front-top-cover 4.3 right-wall-column back-y (+ back-y 0.2))
553 |
554 |
555 | (hull (place left-wall-column back-y (translate [1 -1 1] wall-sphere-bottom-back))
556 | (place (+ left-wall-column 1) back-y (translate [0 -1 1] wall-sphere-bottom-back))
557 | (key-place 0 back-row web-post-tl)
558 | (key-place 0 back-row web-post-tr))
559 |
560 | (hull (place 5 back-y (translate [0 -1 1] wall-sphere-bottom-back))
561 | (place right-wall-column back-y (translate [0 -1 1] wall-sphere-bottom-back))
562 | (key-place 5 back-row web-post-tl)
563 | (key-place 5 back-row web-post-tr))
564 |
565 | (apply union
566 | (for [x (range 1 5)]
567 | (union
568 | (hull (place (- x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
569 | (place (+ x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
570 | (key-place x back-row web-post-tl)
571 | (key-place x back-row web-post-tr))
572 | (hull (place (- x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
573 | (key-place x back-row web-post-tl)
574 | (key-place (- x 1) back-row web-post-tr)))))
575 | (hull (place (- 5 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
576 | (place 5 back-y (translate [0 -1 1] wall-sphere-bottom-back))
577 | (key-place 4 back-row web-post-tr)
578 | (key-place 5 back-row web-post-tl)))))
579 |
580 | (def right-wall
581 | (let [place case-place]
582 | (union
583 | (apply union
584 | (map (partial apply hull)
585 | (partition 2 1
586 | (for [scale (range-inclusive 0 1 0.01)]
587 | (let [x (scale-to-range 4 back-y scale)]
588 | (hull (place right-wall-column x (wall-sphere-top scale))
589 | (place right-wall-column x (wall-sphere-bottom scale))))))))
590 |
591 | (apply union
592 | (concat
593 | (for [x (range 1 5)]
594 | (union
595 | (hull (place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2)))
596 | (key-place 5 x web-post-br)
597 | (key-place 5 x web-post-tr))))
598 | (for [x (range 1 4)]
599 | (union
600 | (hull (place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2)))
601 | (place right-wall-column (inc x) (translate [-1 0 1] (wall-sphere-bottom 1/2)))
602 | (key-place 5 x web-post-br)
603 | (key-place 5 (inc x) web-post-tr))))
604 | [(union
605 | (hull (place right-wall-column (first rows) (translate [-1 0 1] (wall-sphere-bottom 1/2)))
606 | (place right-wall-column back-y (translate [-1 -1 1] (wall-sphere-bottom 1)))
607 | (key-place 5 (first rows) web-post-tr))
608 | (hull (place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2)))
609 | (place right-wall-column 4 (translate [-1 1 1] (wall-sphere-bottom 0)))
610 | (key-place 5 4 web-post-br)))])))))
611 |
612 | (def left-wall
613 | (let [place case-place]
614 | (union
615 | (apply union
616 | (for [x (range-inclusive (dec (first rows)) (- 1.6666 wall-step) wall-step)]
617 | (hull (place left-wall-column x wall-sphere-top-front)
618 | (place left-wall-column (+ x wall-step) wall-sphere-top-front)
619 | (place left-wall-column x wall-sphere-bottom-front)
620 | (place left-wall-column (+ x wall-step) wall-sphere-bottom-front))))
621 | (hull (place left-wall-column (dec (first rows)) wall-sphere-top-front)
622 | (place left-wall-column (dec (first rows)) wall-sphere-bottom-front)
623 | (place left-wall-column back-y wall-sphere-top-back)
624 | (place left-wall-column back-y wall-sphere-bottom-back))
625 | #_(color [0 1 0] (hull (place left-wall-column 0 (translate [1 -1 1] wall-sphere-bottom-back))
626 | (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back))
627 | (key-place 0 0 web-post-tl)
628 | (key-place 0 0 web-post-bl)))
629 | (color [0 1 0] (hull (place left-wall-column 1 (translate [1 -1 1] wall-sphere-bottom-back))
630 | (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back))
631 | (key-place 0 1 web-post-tl)
632 | (key-place 0 1 web-post-bl)))
633 | (color [1 0 0] (hull (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back))
634 | (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
635 | (key-place 0 1 web-post-bl)
636 | (key-place 0 2 web-post-bl)))
637 | (color [1 1 0] (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
638 | (key-place 0 2 web-post-bl)
639 | (key-place 0 3 web-post-tl)))
640 | (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
641 | (thumb-place 1 1 web-post-tr)
642 | (key-place 0 3 web-post-tl))
643 | (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
644 | (thumb-place 1 1 web-post-tr)
645 | (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))))))
646 |
647 | (def thumb-back-wall
648 | (let [step wall-step
649 | top-step 0.05
650 | front-top-cover (fn [x-start x-end y-start y-end]
651 | (apply union
652 | (for [x (range-inclusive x-start (- x-end top-step) top-step)
653 | y (range-inclusive y-start (- y-end top-step) top-step)]
654 | (hull (thumb-place x y wall-sphere-top-back)
655 | (thumb-place (+ x top-step) y wall-sphere-top-back)
656 | (thumb-place x (+ y top-step) wall-sphere-top-back)
657 | (thumb-place (+ x top-step) (+ y top-step) wall-sphere-top-back)))))
658 | back-y thumb-back-y]
659 | (union
660 | (apply union
661 | (for [x (range-inclusive 1/2 (- (+ 5/2 0.05) step) step)]
662 | (hull (thumb-place x back-y wall-sphere-top-back)
663 | (thumb-place (+ x step) back-y wall-sphere-top-back)
664 | (thumb-place x back-y wall-sphere-bottom-back)
665 | (thumb-place (+ x step) back-y wall-sphere-bottom-back))))
666 | (hull (thumb-place 1/2 back-y wall-sphere-top-back)
667 | (thumb-place 1/2 back-y wall-sphere-bottom-back)
668 | (case-place left-wall-column 1.6666 wall-sphere-top-front))
669 | (hull (thumb-place 1/2 back-y wall-sphere-bottom-back)
670 | (case-place left-wall-column 1.6666 wall-sphere-top-front)
671 | (case-place left-wall-column 1.6666 wall-sphere-bottom-front))
672 | (hull
673 | (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
674 | (thumb-place 1 1 web-post-tr)
675 | (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
676 | (thumb-place 1 1 web-post-tl))
677 | (hull
678 | (thumb-place (+ 5/2 0.05) thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back))
679 | (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
680 | (thumb-place 1 1 web-post-tl)
681 | (thumb-place 2 1 web-post-tl)))))
682 |
683 | (def thumb-left-wall
684 | (let [step wall-step
685 | place thumb-place]
686 | (union
687 | (apply union
688 | (for [x (range-inclusive (+ -1 0.07) (- 1.95 step) step)]
689 | (hull (place thumb-left-wall-column x wall-sphere-top-front)
690 | (place thumb-left-wall-column (+ x step) wall-sphere-top-front)
691 | (place thumb-left-wall-column x wall-sphere-bottom-front)
692 | (place thumb-left-wall-column (+ x step) wall-sphere-bottom-front))))
693 | (hull (place thumb-left-wall-column 1.95 wall-sphere-top-front)
694 | (place thumb-left-wall-column 1.95 wall-sphere-bottom-front)
695 | (place thumb-left-wall-column thumb-back-y wall-sphere-top-back)
696 | (place thumb-left-wall-column thumb-back-y wall-sphere-bottom-back))
697 |
698 | (hull
699 | (thumb-place thumb-left-wall-column thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back))
700 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
701 | (thumb-place 2 1 web-post-tl)
702 | (thumb-place 2 1 web-post-bl))
703 | (hull
704 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
705 | (thumb-place 2 0 web-post-tl)
706 | (thumb-place 2 1 web-post-bl))
707 | (hull
708 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
709 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
710 | (thumb-place 2 0 web-post-tl)
711 | (thumb-place 2 0 web-post-bl))
712 | (hull
713 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
714 | (thumb-place 2 -1 web-post-tl)
715 | (thumb-place 2 0 web-post-bl))
716 | (hull
717 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
718 | (thumb-place thumb-left-wall-column (+ -1 0.07) (translate [1 1 1] wall-sphere-bottom-front))
719 | (thumb-place 2 -1 web-post-tl)
720 | (thumb-place 2 -1 web-post-bl)))))
721 |
722 | (def thumb-front-wall
723 | (let [step wall-step ;;0.1
724 | wall-sphere-top-fronttep 0.05 ;;0.05
725 | place thumb-place
726 | plate-height (/ (- sa-double-length mount-height) 2)
727 | thumb-tl (->> web-post-tl
728 | (translate [0 plate-height 0]))
729 | thumb-bl (->> web-post-bl
730 | (translate [0 (- plate-height) 0]))
731 | thumb-tr (->> web-post-tr
732 | (translate [-0 plate-height 0]))
733 | thumb-br (->> web-post-br
734 | (translate [-0 (- plate-height) 0]))]
735 | (union
736 | (apply union
737 | (for [x (range-inclusive thumb-right-wall (- (+ 5/2 0.05) step) step)]
738 | (hull (place x thumb-front-row wall-sphere-top-front)
739 | (place (+ x step) thumb-front-row wall-sphere-top-front)
740 | (place x thumb-front-row wall-sphere-bottom-front)
741 | (place (+ x step) thumb-front-row wall-sphere-bottom-front))))
742 |
743 | (hull (place thumb-right-wall thumb-front-row wall-sphere-top-front)
744 | (place thumb-right-wall thumb-front-row wall-sphere-bottom-front)
745 | (case-place 0.5 4 wall-sphere-top-front))
746 | (hull (place thumb-right-wall thumb-front-row wall-sphere-bottom-front)
747 | (case-place 0.5 4 wall-sphere-top-front)
748 | (case-place 0.7 4 wall-sphere-bottom-front))
749 |
750 | (hull (place thumb-right-wall thumb-front-row wall-sphere-bottom-front)
751 | (key-place 1 4 web-post-bl)
752 | (place 0 -1/2 thumb-br)
753 | (place 0 -1/2 web-post-br)
754 | (case-place 0.7 4 wall-sphere-bottom-front))
755 |
756 | (hull (place (+ 5/2 0.05) thumb-front-row (translate [1 1 1] wall-sphere-bottom-front))
757 | (place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
758 | (place 2 -1 web-post-bl)
759 | (place 2 -1 web-post-br))
760 |
761 | (hull (place thumb-right-wall thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
762 | (place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
763 | (place 0 -1/2 thumb-bl)
764 | (place 0 -1/2 thumb-br))
765 | (hull (place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
766 | (place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
767 | (place 0 -1/2 thumb-bl)
768 | (place 1 -1/2 thumb-bl)
769 | (place 1 -1/2 thumb-br)
770 | (place 2 -1 web-post-br)))))
771 |
772 | (def new-case
773 | (union front-wall
774 | right-wall
775 | back-wall
776 | left-wall
777 | thumb-back-wall
778 | thumb-left-wall
779 | thumb-front-wall))
780 |
781 | ;;;;;;;;;;;;
782 | ;; Bottom ;;
783 | ;;;;;;;;;;;;
784 |
785 |
786 | (def bottom-key-guard (->> (cube mount-width mount-height web-thickness)
787 | (translate [0 0 (+ (- (/ web-thickness 2)) -4.5)])))
788 | (def bottom-front-key-guard (->> (cube mount-width (/ mount-height 2) web-thickness)
789 | (translate [0 (/ mount-height 4) (+ (- (/ web-thickness 2)) -4.5)])))
790 |
791 | (def bottom-plate
792 | (union
793 | (apply union
794 | (for [column columns
795 | row (drop-last rows) ;;
796 | :when (or (not= column 0)
797 | (not= row 4))]
798 | (->> bottom-key-guard
799 | (key-place column row))))
800 | (thumb-layout-bottom (rotate (/ π 2) [0 0 1] bottom-key-guard))
801 | (apply union
802 | (for [column columns
803 | row [(last rows)] ;;
804 | :when (or (not= column 0)
805 | (not= row 4))]
806 | (->> bottom-front-key-guard
807 | (key-place column row))))
808 | (let [shift #(translate [0 0 (+ (- web-thickness) -5)] %)
809 | web-post-tl (shift web-post-tl)
810 | web-post-tr (shift web-post-tr)
811 | web-post-br (shift web-post-br)
812 | web-post-bl (shift web-post-bl)
813 | half-shift-correction #(translate [0 (/ mount-height 2) 0] %)
814 | half-post-br (half-shift-correction web-post-br)
815 | half-post-bl (half-shift-correction web-post-bl)
816 | row-connections (concat
817 | (for [column (drop-last columns)
818 | row (drop-last rows)
819 | :when (or (not= column 0)
820 | (not= row 4))]
821 | (triangle-hulls
822 | (key-place (inc column) row web-post-tl)
823 | (key-place column row web-post-tr)
824 | (key-place (inc column) row web-post-bl)
825 | (key-place column row web-post-br)))
826 | (for [column (drop-last columns)
827 | row [(last rows)]
828 | :when (or (not= column 0)
829 | (not= row 4))]
830 | (triangle-hulls
831 | (key-place (inc column) row web-post-tl)
832 | (key-place column row web-post-tr)
833 | (key-place (inc column) row half-post-bl)
834 | (key-place column row half-post-br))))
835 | column-connections (for [column columns
836 | row (drop-last rows)
837 | :when (or (not= column 0)
838 | (not= row 3))]
839 | (triangle-hulls
840 | (key-place column row web-post-bl)
841 | (key-place column row web-post-br)
842 | (key-place column (inc row) web-post-tl)
843 | (key-place column (inc row) web-post-tr)))
844 | diagonal-connections (for [column (drop-last columns)
845 | row (drop-last rows)
846 | :when (or (not= column 0)
847 | (not= row 3))]
848 | (triangle-hulls
849 | (key-place column row web-post-br)
850 | (key-place column (inc row) web-post-tr)
851 | (key-place (inc column) row web-post-bl)
852 | (key-place (inc column) (inc row) web-post-tl)))
853 | main-keys-bottom (concat row-connections
854 | column-connections
855 | diagonal-connections)
856 | front-wall (concat
857 | (for [x (range 2 5)]
858 | (union
859 | (hull (case-place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
860 | (case-place (+ x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
861 | (key-place x 4 half-post-bl)
862 | (key-place x 4 half-post-br))
863 | (hull (case-place (- x 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
864 | (key-place x 4 half-post-bl)
865 | (key-place (- x 1) 4 half-post-br))))
866 | [(hull (case-place right-wall-column 4 (translate [0 1 1] wall-sphere-bottom-front))
867 | (case-place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front))
868 | (key-place 5 4 half-post-bl)
869 | (key-place 5 4 half-post-br))
870 | (hull (case-place (+ 4 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
871 | (case-place (- right-wall-column 1) 4 (translate [0 1 1] wall-sphere-bottom-front))
872 | (key-place 4 4 half-post-br)
873 | (key-place 5 4 half-post-bl))])
874 | right-wall (concat
875 | (for [x (drop-last rows)]
876 | (hull (case-place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2)))
877 | (key-place 5 x web-post-br)
878 | (key-place 5 x web-post-tr)))
879 | (for [x (drop-last rows)]
880 | (hull (case-place right-wall-column x (translate [-1 0 1] (wall-sphere-bottom 1/2)))
881 | (case-place right-wall-column (inc x) (translate [-1 0 1] (wall-sphere-bottom 1/2)))
882 | (key-place 5 x web-post-br)
883 | (key-place 5 (inc x) web-post-tr)))
884 | [(union
885 | (hull (case-place right-wall-column (first rows) (translate [-1 0 1] (wall-sphere-bottom 1/2)))
886 | (case-place right-wall-column back-y (translate [-1 -1 1] (wall-sphere-bottom 1)))
887 | (key-place 5 (first rows) web-post-tr)
888 | )
889 | (hull (case-place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2)))
890 | (case-place right-wall-column 4 (translate [0 1 1] (wall-sphere-bottom 0)))
891 | (key-place 5 4 half-post-br)
892 | )
893 | (hull (case-place right-wall-column 4 (translate [-1 0 1] (wall-sphere-bottom 1/2)))
894 | (key-place 5 4 half-post-br)
895 | (key-place 5 4 web-post-tr)))])
896 | back-wall (concat
897 | (for [x (range 1 6)]
898 | (union
899 | (hull (case-place (- x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
900 | (case-place (+ x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
901 | (key-place x (first rows) web-post-tl)
902 | (key-place x (first rows) web-post-tr))
903 | (hull (case-place (- x 1/2) back-y (translate [0 -1 1] wall-sphere-bottom-back))
904 | (key-place x (first rows) web-post-tl)
905 | (key-place (- x 1) (first rows) web-post-tr))))
906 | [(hull (case-place left-wall-column back-y (translate [1 -1 1] wall-sphere-bottom-back))
907 | (case-place (+ left-wall-column 1) back-y (translate [0 -1 1] wall-sphere-bottom-back))
908 | (key-place 0 (first rows) web-post-tl)
909 | (key-place 0 (first rows) web-post-tr))])
910 | left-wall (let [place case-place]
911 | [(hull (place left-wall-column 1 (translate [1 -1 1] wall-sphere-bottom-back))
912 | (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back))
913 | (key-place 0 1 web-post-tl)
914 | (key-place 0 1 web-post-bl))
915 | #_(hull (place left-wall-column 1 (translate [1 0 1] wall-sphere-bottom-back))
916 | (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back))
917 | (key-place 0 0 web-post-bl)
918 | (key-place 0 1 web-post-bl))
919 | (hull (place left-wall-column 2 (translate [1 0 1] wall-sphere-bottom-back))
920 | (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
921 | (key-place 0 1 web-post-bl)
922 | (key-place 0 2 web-post-bl))
923 | (hull (place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
924 | (key-place 0 2 web-post-bl)
925 | (key-place 0 3 web-post-tl))])
926 |
927 | #_(union
928 | (thumb-place 0 -1/2 shape)
929 |
930 | (thumb-place 1 7/8 shape)
931 | (thumb-place 1 -5/8 shape)
932 |
933 | (thumb-place 2 -3/4 shape)
934 | (thumb-place 2 3/4 shape)
935 | )
936 |
937 |
938 | thumb-tl #(->> web-post-tl
939 | (translate [0 (extended-plate-height %) 0]))
940 | thumb-bl #(->> web-post-bl
941 | (translate [0 (- (extended-plate-height %)) 0]))
942 | thumb-tr #(->> web-post-tr
943 | (translate [0 (extended-plate-height %) 0]))
944 | thumb-br #(->> web-post-br
945 | (translate [0 (- (extended-plate-height %)) 0]))
946 |
947 | thumbs [(triangle-hulls (thumb-place 0 -1/2 web-post-tl)
948 | (thumb-place 0 -1/2 web-post-bl)
949 | (thumb-place 1 -5/8 web-post-tr)
950 | (thumb-place 1 -5/8 web-post-br))
951 | (hull (thumb-place 1 -5/8 web-post-tr)
952 | (thumb-place 1 -5/8 web-post-tl)
953 | (thumb-place 1 7/8 web-post-bl)
954 | (thumb-place 1 7/8 web-post-br))
955 | (hull (thumb-place 2 -3/4 web-post-tr)
956 | (thumb-place 2 -3/4 web-post-tl)
957 | (thumb-place 2 3/4 web-post-bl)
958 | (thumb-place 2 3/4 web-post-br))
959 | (triangle-hulls (thumb-place 2 3/4 web-post-tr)
960 | (thumb-place 1 7/8 web-post-tl)
961 | (thumb-place 2 3/4 web-post-br)
962 | (thumb-place 1 7/8 web-post-bl)
963 | (thumb-place 2 -3/4 web-post-tr)
964 | (thumb-place 1 -5/8 web-post-tl)
965 | (thumb-place 2 -3/4 web-post-br)
966 | (thumb-place 1 -5/8 web-post-bl)
967 | )]
968 | thumb-back-wall [(hull
969 | (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
970 | (thumb-place 1 7/8 web-post-tr)
971 | (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
972 | (thumb-place 1 7/8 web-post-tl))
973 |
974 | (hull
975 | (thumb-place (+ 5/2 0.05) thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back))
976 | (thumb-place 3/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
977 | (thumb-place 1 7/8 web-post-tl)
978 | (thumb-place 2 3/4 web-post-tr))
979 |
980 | (hull
981 | (thumb-place (+ 5/2 0.05) thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back))
982 | (thumb-place 2 3/4 web-post-tl)
983 | (thumb-place 2 3/4 web-post-tr))
984 |
985 | (hull
986 | (thumb-place 1/2 thumb-back-y (translate [0 -1 1] wall-sphere-bottom-back))
987 | (case-place left-wall-column 1.6666 (translate [1 0 1] wall-sphere-bottom-front))
988 | (key-place 0 3 web-post-tl)
989 | (thumb-place 1 7/8 web-post-tr))
990 | ]
991 | thumb-left-wall [(hull
992 | (thumb-place thumb-left-wall-column thumb-back-y (translate [1 -1 1] wall-sphere-bottom-back))
993 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
994 | (thumb-place 2 1 web-post-tl)
995 | (thumb-place 2 1 web-post-bl))
996 | (hull
997 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
998 | (thumb-place 2 0 web-post-tl)
999 | (thumb-place 2 1 web-post-bl))
1000 | (hull
1001 | (thumb-place thumb-left-wall-column 0 (translate [1 0 1] wall-sphere-bottom-back))
1002 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
1003 | (thumb-place 2 0 web-post-tl)
1004 | (thumb-place 2 0 web-post-bl))
1005 | (hull
1006 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
1007 | (thumb-place 2 -1 web-post-tl)
1008 | (thumb-place 2 0 web-post-bl))
1009 | (hull
1010 | (thumb-place thumb-left-wall-column -1 (translate [1 0 1] wall-sphere-bottom-back))
1011 | (thumb-place thumb-left-wall-column (+ -1 0.07) (translate [1 1 1] wall-sphere-bottom-front))
1012 | (thumb-place 2 -1 web-post-tl)
1013 | (thumb-place 2 -1 web-post-bl))]
1014 | thumb-front-wall [(hull (thumb-place (+ 5/2 0.05) thumb-front-row (translate [1 1 1] wall-sphere-bottom-front))
1015 | (thumb-place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
1016 | (thumb-place 2 -3/4 web-post-bl)
1017 | (thumb-place 2 -3/4 web-post-br))
1018 |
1019 | (hull (thumb-place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
1020 | (thumb-place (+ 3/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
1021 | (thumb-place 1 -5/8 web-post-bl)
1022 | (thumb-place 1 -5/8 web-post-br)
1023 | (thumb-place 2 -3/4 web-post-br))
1024 |
1025 | (hull (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front))
1026 | (thumb-place (+ 1/2 0.05) thumb-front-row (translate [0 1 1] wall-sphere-bottom-front))
1027 | (thumb-place 0 -1/2 web-post-bl)
1028 | (thumb-place 1 -5/8 web-post-br)
1029 | (thumb-place 0 -1/2 web-post-br))]
1030 | thumb-inside [(triangle-hulls
1031 | (thumb-place 1 7/8 web-post-tr)
1032 | (key-place 0 3 web-post-tl)
1033 | (thumb-place 1 7/8 web-post-br)
1034 | (key-place 0 3 web-post-bl)
1035 | (thumb-place 1 -5/8 web-post-tr)
1036 | (thumb-place 0 -1/2 web-post-tl)
1037 | (key-place 0 3 web-post-bl)
1038 | (thumb-place 0 -1/2 web-post-tr)
1039 | (key-place 0 3 web-post-br)
1040 | (key-place 1 3 web-post-bl)
1041 | (thumb-place 0 -1/2 web-post-tr)
1042 | (key-place 1 4 web-post-tl)
1043 | (key-place 1 4 half-post-bl))
1044 |
1045 | (hull
1046 | (thumb-place 0 -1/2 web-post-tr)
1047 | (thumb-place 0 -1/2 web-post-br)
1048 | (key-place 1 4 half-post-bl))
1049 |
1050 | (hull
1051 | (key-place 1 4 half-post-bl)
1052 | (key-place 1 4 half-post-br)
1053 | (case-place (- 2 1/2) 4 (translate [0 1 1] wall-sphere-bottom-front))
1054 | (case-place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front)))
1055 |
1056 | (hull
1057 | (thumb-place 0 -1/2 web-post-br)
1058 | (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front))
1059 | (key-place 1 4 half-post-bl)
1060 | )
1061 |
1062 | (hull
1063 | (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front))
1064 | (case-place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front))
1065 | (thumb-place 0 -1/2 web-post-br)
1066 | (thumb-place 0 -1/2 web-post-tr)
1067 | )
1068 |
1069 | #_ (hull
1070 | (case-place 0.7 4 (translate [0 1 1] wall-sphere-bottom-front))
1071 | (thumb-place 0 -1/2 web-post-br)
1072 | (thumb-place 0 -1/2 web-post-tr)
1073 |
1074 | )
1075 |
1076 |
1077 | #_ (hull
1078 | (thumb-place 0 -1 web-post-br)
1079 | (thumb-place 0 -1/2 web-post-br)
1080 | (thumb-place thumb-right-wall thumb-front-row (translate [-1 1 1] wall-sphere-bottom-front))
1081 | (key-place 1 4 half-post-bl)
1082 | )
1083 |
1084 |
1085 |
1086 | ]
1087 | stands (let [bumper-diameter 9.6
1088 | bumper-radius (/ bumper-diameter 2)
1089 | stand-diameter (+ bumper-diameter 2)
1090 | stand-radius (/ stand-diameter 2)
1091 | stand-at #(difference (->> (sphere stand-radius)
1092 | (translate [0 0 (+ (/ stand-radius -2) -4.5)])
1093 | %
1094 | (bottom-hull))
1095 | (->> (cube stand-diameter stand-diameter stand-radius)
1096 | (translate [0 0 (/ stand-radius -2)])
1097 | %)
1098 | (->> (sphere bumper-radius)
1099 | (translate [0 0 (+ (/ stand-radius -2) -4.5)])
1100 | %
1101 | (bottom 1.5)))]
1102 | [(stand-at #(key-place 0 1 %))
1103 | (stand-at #(thumb-place 1 -1/2 %))
1104 | (stand-at #(key-place 5 1 %))
1105 | (stand-at #(key-place 5 3 %))])]
1106 | (apply union
1107 | (concat
1108 | main-keys-bottom
1109 | front-wall
1110 | right-wall
1111 | back-wall
1112 | left-wall
1113 | thumbs
1114 | thumb-back-wall
1115 | thumb-left-wall
1116 | thumb-front-wall
1117 | thumb-inside
1118 | stands)))))
1119 |
1120 | (def screw-hole (->> (cylinder 1.5 60)
1121 | (translate [0 0 3/2])
1122 | (with-fn wall-sphere-n)))
1123 |
1124 | (def screw-holes
1125 | (union
1126 | (key-place (+ 4 1/2) 3/2 screw-hole)
1127 | (key-place (+ 4 1/2) (+ 3 1/2) screw-hole)
1128 | (thumb-place 2 0 screw-hole)))
1129 |
1130 | (defn circuit-cover [width length height]
1131 | (let [cover-sphere-radius 1
1132 | cover-sphere (->> (sphere cover-sphere-radius)
1133 | (with-fn 20))
1134 | cover-sphere-z (+ (- height) (- cover-sphere-radius))
1135 | cover-sphere-x (+ (/ width 2) cover-sphere-radius)
1136 | cover-sphere-y (+ (/ length 2) (+ cover-sphere-radius))
1137 | cover-sphere-tl (->> cover-sphere
1138 | (translate [(- cover-sphere-x) (- cover-sphere-y) cover-sphere-z])
1139 | (key-place 1/2 3/2))
1140 | cover-sphere-tr (->> cover-sphere
1141 | (translate [cover-sphere-x (- cover-sphere-y) cover-sphere-z])
1142 | (key-place 1/2 3/2))
1143 | cover-sphere-br (->> cover-sphere
1144 | (translate [cover-sphere-x cover-sphere-y cover-sphere-z])
1145 | (key-place 1/2 3/2))
1146 | cover-sphere-bl (->> cover-sphere
1147 | (translate [(- cover-sphere-x) cover-sphere-y cover-sphere-z])
1148 | (key-place 1/2 3/2))
1149 |
1150 | lower-to-bottom #(translate [0 0 (+ (- cover-sphere-radius) -5.5)] %)
1151 | bl (->> cover-sphere lower-to-bottom (key-place 0 1/2))
1152 | br (->> cover-sphere lower-to-bottom (key-place 1 1/2))
1153 | tl (->> cover-sphere lower-to-bottom (key-place 0 5/2))
1154 | tr (->> cover-sphere lower-to-bottom (key-place 1 5/2))
1155 |
1156 | mlb (->> cover-sphere
1157 | (translate [(- cover-sphere-x) 0 (+ (- height) -1)])
1158 | (key-place 1/2 3/2))
1159 | mrb (->> cover-sphere
1160 | (translate [cover-sphere-x 0 (+ (- height) -1)])
1161 | (key-place 1/2 3/2))
1162 |
1163 | mlt (->> cover-sphere
1164 | (translate [(+ (- cover-sphere-x) -4) 0 -6])
1165 | (key-place 1/2 3/2))
1166 | mrt (->> cover-sphere
1167 | (translate [(+ cover-sphere-x 4) 0 -6])
1168 | (key-place 1/2 3/2))]
1169 | (union
1170 | (hull cover-sphere-bl cover-sphere-br cover-sphere-tl cover-sphere-tr)
1171 | (hull cover-sphere-br cover-sphere-bl bl br)
1172 | (hull cover-sphere-tr cover-sphere-tl tl tr)
1173 | (hull cover-sphere-tl tl mlb mlt)
1174 | (hull cover-sphere-bl bl mlb mlt)
1175 | (hull cover-sphere-tr tr mrb mrt)
1176 | (hull cover-sphere-br br mrb mrt))))
1177 |
1178 | (def io-exp-width 10)
1179 | (def io-exp-height 8)
1180 | (def io-exp-length 36)
1181 |
1182 | (def teensy-width 20)
1183 | (def teensy-height 12)
1184 | (def teensy-length 33)
1185 |
1186 | (def io-exp-cover (circuit-cover io-exp-width io-exp-length io-exp-height))
1187 | (def teensy-cover (circuit-cover teensy-width teensy-length teensy-height))
1188 |
1189 | (def trrs-diameter 6.6)
1190 | (def trrs-radius (/ trrs-diameter 2))
1191 | (def trrs-hole-depth 10)
1192 |
1193 | (def trrs-hole (->> (union (cylinder trrs-radius trrs-hole-depth)
1194 | (->> (cube trrs-diameter (+ trrs-radius 5) trrs-hole-depth)
1195 | (translate [0 (/ (+ trrs-radius 5) 2) 0])))
1196 | (rotate (/ π 2) [1 0 0])
1197 | (translate [0 (+ (/ mount-height 2) 4) (- trrs-radius)])
1198 | (with-fn 50)))
1199 |
1200 | (def trrs-hole-just-circle
1201 | (->> (cylinder trrs-radius trrs-hole-depth)
1202 | (rotate (/ π 2) [1 0 0])
1203 | (translate [0 (+ (/ mount-height 2) 4) (- trrs-radius)])
1204 | (with-fn 50)
1205 | (key-place 1/2 0)))
1206 |
1207 | (def trrs-box-hole (->> (cube 14 14 7 )
1208 | (translate [0 1 -3.5])))
1209 |
1210 |
1211 | (def trrs-cutout
1212 | (->> (union trrs-hole
1213 | trrs-box-hole)
1214 | (key-place 1/2 1)))
1215 |
1216 | (def teensy-pcb-thickness 1.6)
1217 | (def teensy-offset-height 5)
1218 |
1219 | (def teensy-pcb (->> (cube 18 30.5 teensy-pcb-thickness)
1220 | (translate [0 0 (+ (/ teensy-pcb-thickness -2) (- teensy-offset-height))])
1221 | (key-place 1/2 3/2)
1222 | (color [1 0 0])))
1223 |
1224 | (def teensy-support
1225 | (difference
1226 | (union
1227 | (->> (cube 3 3 9)
1228 | (translate [0 0 -2])
1229 | (key-place 1/2 3/2)
1230 | (color [0 1 0]))
1231 | (hull (->> (cube 3 6 9)
1232 | (translate [0 0 -2])
1233 | (key-place 1/2 2)
1234 | (color [0 0 1]))
1235 | (->> (cube 3 3 (+ teensy-pcb-thickness 3))
1236 | (translate [0 (/ 30.5 -2) (+ (- teensy-offset-height)
1237 | #_(/ (+ teensy-pcb-thickness 3) -2)
1238 | )])
1239 | (key-place 1/2 3/2)
1240 | (color [0 0 1]))))
1241 | teensy-pcb
1242 | (->> (cube 18 30.5 teensy-pcb-thickness)
1243 | (translate [0 1.5 (+ (/ teensy-pcb-thickness -2) (- teensy-offset-height) -1)])
1244 | (key-place 1/2 3/2)
1245 | (color [1 0 0]))))
1246 |
1247 | (def usb-cutout
1248 | (let [hole-height 6.2
1249 | side-radius (/ hole-height 2)
1250 | hole-width 10.75
1251 | side-cylinder (->> (cylinder side-radius teensy-length)
1252 | (with-fn 20)
1253 | (translate [(/ (- hole-width hole-height) 2) 0 0]))]
1254 | (->> (hull side-cylinder
1255 | (mirror [-1 0 0] side-cylinder))
1256 | (rotate (/ π 2) [1 0 0])
1257 | (translate [0 (/ teensy-length 2) (- side-radius)])
1258 | (translate [0 0 (- 1)])
1259 | (translate [0 0 (- teensy-offset-height)])
1260 | (key-place 1/2 3/2))))
1261 |
1262 | ;;;;;;;;;;;;;;;;;;
1263 | ;; Final Export ;;
1264 | ;;;;;;;;;;;;;;;;;;
1265 |
1266 | (def dactyl-top-right
1267 | (difference
1268 | (union key-holes
1269 | connectors
1270 | thumb
1271 | new-case
1272 | teensy-support
1273 | #_caps)
1274 | trrs-hole-just-circle
1275 | screw-holes))
1276 |
1277 | (def dactyl-bottom-right
1278 | (difference
1279 | (union
1280 | teensy-cover
1281 | (difference
1282 | bottom-plate
1283 | (hull teensy-cover)
1284 | new-case
1285 | teensy-cover
1286 | trrs-cutout
1287 | (->> (cube 1000 1000 10) (translate [0 0 -5]))
1288 | screw-holes))
1289 | usb-cutout
1290 | dactyl-top-right))
1291 |
1292 | (def dactyl-bottom-left
1293 | (mirror [-1 0 0]
1294 | (union
1295 | io-exp-cover
1296 | (difference
1297 | bottom-plate
1298 | (hull io-exp-cover)
1299 | new-case
1300 | io-exp-cover
1301 | trrs-cutout
1302 | (->> (cube 1000 1000 10) (translate [0 0 -5]))
1303 | screw-holes))))
1304 |
1305 |
1306 |
1307 | (def dactyl-top-left
1308 | (mirror [-1 0 0]
1309 | (difference
1310 | (union key-holes
1311 | connectors
1312 | thumb
1313 | new-case)
1314 | trrs-hole-just-circle
1315 | screw-holes)))
1316 |
1317 | (comment
1318 | (spit "things/lightcycle-cherry-top-right.scad"
1319 | (write-scad dactyl-top-right))
1320 |
1321 | (spit "things/lightcycle-cherry-bottom-right.scad"
1322 | (write-scad dactyl-bottom-right))
1323 |
1324 | (spit "things/lightcycle-cherry-top-left.scad"
1325 | (write-scad dactyl-top-left))
1326 |
1327 | (spit "things/lightcycle-cherry-bottom-left.scad"
1328 | (write-scad dactyl-bottom-left)))
1329 |
1330 | (spit "things/lightcycle-matias-top-right.scad"
1331 | (write-scad dactyl-top-right))
1332 |
1333 | (spit "things/lightcycle-matias-bottom-right.scad"
1334 | (write-scad dactyl-bottom-right))
1335 |
1336 | (spit "things/lightcycle-matias-top-left.scad"
1337 | (write-scad dactyl-top-left))
1338 |
1339 | (spit "things/lightcycle-matias-bottom-left.scad"
1340 | (write-scad dactyl-bottom-left))
1341 |
--------------------------------------------------------------------------------
/src/dactyl_keyboard/util.clj:
--------------------------------------------------------------------------------
1 | (ns dactyl-keyboard.util
2 | (:refer-clojure :exclude [use import])
3 | (:require [scad-clj.model :refer :all]))
4 |
5 | (defn triangle-hulls [& shapes]
6 | (apply union
7 | (map (partial apply hull)
8 | (partition 3 1 shapes))))
9 |
10 | (defn bottom [height p]
11 | (->> (project p)
12 | (extrude-linear {:height height :twist 0 :convexity 0})
13 | (translate [0 0 (/ height 2)])))
14 |
15 | (defn bottom-hull [p]
16 | (hull p (bottom 1 p)))
17 |
--------------------------------------------------------------------------------
/src/dactyl_keyboard/wrist.clj:
--------------------------------------------------------------------------------
1 | (ns dactyl-keyboard.wrist
2 | (:refer-clojure :exclude [use import])
3 | (:require [scad-clj.scad :refer :all]
4 | [scad-clj.model :refer :all]
5 | [unicode-math.core :refer :all]
6 | [dactyl-keyboard.util :refer :all]))
7 |
8 | (def pad-corner-r 11)
9 | (def pad-width 95)
10 | (def pad-length 76.5)
11 |
12 | (def stand-height 45)
13 | (def stand-thickness 1.5)
14 |
15 | (def bumper-diameter 9.6)
16 | (def bumper-radius (/ bumper-diameter 2))
17 | (def bumper-height 2)
18 |
19 | (def corner-circle (->> (cylinder pad-corner-r stand-thickness)
20 | (translate [(- (/ pad-width 2) pad-corner-r)
21 | (- (/ pad-length 2) pad-corner-r)
22 | (+ stand-height (/ stand-thickness 2))])))
23 |
24 | (def corner {:back-right corner-circle
25 | :back-left (->> corner-circle (mirror [-1 0 0]))
26 | :front-right (->> corner-circle (mirror [0 -1 0]))
27 | :front-left (->> corner-circle (mirror [0 -1 0]) (mirror [-1 0 0])) })
28 |
29 | (def corner-circle-bottom (->>
30 | (difference
31 | (cylinder pad-corner-r stand-height)
32 | (translate [0 0 (- (/ stand-height 2))]
33 | (cylinder bumper-radius bumper-height)
34 | )
35 | )
36 | (translate [(- (/ pad-width 2) pad-corner-r)
37 | (- (/ pad-length 2) pad-corner-r)
38 | (/ stand-height 2)])))
39 |
40 | (def corner-bottom {:back-right corner-circle-bottom
41 | :back-left (->> corner-circle-bottom (mirror [-1 0 0]))
42 | :front-right (->> corner-circle-bottom (mirror [0 -1 0]))
43 | :front-left (->> corner-circle-bottom (mirror [0 -1 0]) (mirror [-1 0 0])) })
44 |
45 | (def wrist-rest
46 | (union (hull (corner :back-right)
47 | (corner :back-left)
48 | (corner :front-right)
49 | (corner :front-left))
50 | (corner-bottom :back-right)
51 | (corner-bottom :back-left)
52 | (corner-bottom :front-right)
53 | (corner-bottom :front-left)))
54 |
55 | (spit "things/wrist.scad"
56 | (write-scad wrist-rest))
57 |
--------------------------------------------------------------------------------
/target/repl-port:
--------------------------------------------------------------------------------
1 | 49375
--------------------------------------------------------------------------------
/target/stale/extract-native.dependencies:
--------------------------------------------------------------------------------
1 | ([:dependencies ([cider/cider-nrepl "0.10.0"] [org.clojure/clojure "1.7.0"] [unicode-math/unicode-math "0.2.0"] [scad-clj/scad-clj "0.4.0"] [org.clojure/tools.nrepl "0.2.12" :exclusions ([org.clojure/clojure]) :scope "test"] [clojure-complete/clojure-complete "0.2.3" :exclusions ([org.clojure/clojure]) :scope "test"])])
--------------------------------------------------------------------------------
/test/dactyl_cave/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns dactyl-cave.core-test
2 | (:require [clojure.test :refer :all]
3 | [dactyl-cave.core :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------