Adam James

October 1, 2021

September 2021 Update

This was originally posted on my Patreon feed, but I feel is still useful to post here.

Thank You!

Thank you to @Siyoung Byun. You have been a consistent and patient Patron and I'm extremely grateful for your support. I hope in the near future that I will have more people to thank ;).

A quick thanks to @jmwright for suggesting I fill out a monthly report template as things get finished throughout the month; it's turned this into a fun report and keeps me accountable to myself and those who support me.

Intro
I came into this month hoping to complete lots of work in various areas, but my real life quickly took a turn for the busy. This is ok, as I still managed to accomplish some good work in a few areas.

Forge and SVG-clj
Both libraries end up being developed in parallel for certain features. I noticed that my SVG import feature in the Forge library was breaking, so I had to change my approach to loading and handling path conversions in SVG-clj This turned out to be a bit of tricky work, but I have a working import method in Forge, and a more reliable path handling namespace in SVG-clj! I always love it when I can make parallel improvements like this.

A discussion was started by light-matters in the svg-clj Github asking about importing external SVGs. This led me to exploring improvements for my tools/load-svg function, which relies on Clojure's data.xml library. I noticed some inconsistencies with XML namespaces when parsing on the JVM vs. in a js environment, so there may still be work to do, but I have an import process that can at least get the elements from an SVG for the user to process further. This is done as follows:

  •  slurp the SVG file as a string (CLJ only)
  • SVG string is parsed as XML and immediately converted into a Hiccup data structure
  • all metadata and elements are kept, this shouldn't break svg-clj functions
  • immediately exporting with hiccup to an svg file might break due to XML namespace issues, this is a WIP
  • clojure.zip allows for tree nav and edits, so I have a simple function that matches all nodes that can be edited by the library (eg. circle, polygon, path)
  • fn is get-elems in the utils namespace, and is used in load-svg-elems fn in the tools namespace
  • svg-string parse/get-elems is available in utils so that CLJS users can still build the load functionality, just not relying on (slurp fname)

The idea here is that you can parse SVG strings into a seq. of elements which you can then transform as you desire using the library's functions. I have some ideas related to allowing the user to match on additional attributes such as class or ID to help give some more control to the importing process, but I don't want this to be an area where scope gets out of hand.

I also (finally) fixed up angle-from-pts. Though I'm not sure it's the most optimal solution, I can now correctly get the angle from a triple of points! And I've got a few tests built to confirm this (I'll probably be turning to property based testing here to make it even more robust!).

Forge specific work was less than I hoped this month, but I've been writing and rewriting the design document a lot. I think the real breakthrough will be in discovering the best data structure. I'm fairly sure the data structure will consist of the following parts:

  •  Tree-like structure, probably Hiccup style, maybe just nested maps?
    • I think this should be an acyclic digraph to best align with Clojure's immutable data structure approach
  • Functional Representation (FREP) derived from the tree
    • Theoretically, the entire model can be defined by one (admittedly complex) function taking [x y z] and returning a distance
    • each node of the tree will have an FREP corresponding to the model up to that point.
  • Boundary Representation (BREP) derived from the tree BREP itself is probably a tree structure:
    • vertices (2d and 3d tuples)
    • edges (parametric curves as fns of t from 0 to 1) linked to the vertices
    • faces (parametric surfaces as fns of u v) linked to the edges
    • solids enclosed by faces
  • Engineering Data as a map of attrs per node
    • colours
    • material data
    • misc. metadata

Assuming the above works correctly (and is a good design), I actually have two things here:

  1. A model represented as a tree structure
  2. An internal rep which is derived from this tree
  3. A model fn which treats the internal rep as if it were a regular tree node. That is, other Forge models must be usable directly in a Forge model tree.

Which implies that my library should provide a model namespace that lets a user build up a tree easily with simple functions. My SVG-clj library is a good example of how this might look; chaining functions together with threading macros.

Then, a 'forge internal rep' namespace would handle the tree parsing and fully build out the structure containing FREP, BREP, and engg. data maps.

Importers are responsible for building Forge internal reps. Users then can use them directly in building Forge Models, because the model's tree functions must handle the internal rep

Exporters then can use the tree directly (in the case of the OpenSCAD export) or the internal rep (in case of more complicated exports like STEP files), or combinations of both.

If this seems a bit loose, that's because I'm still in the process of discovery and thinking. I have a good feeling that I'm on the right track, but explaining the ideas cleanly is still eluding me. I'm not worried though - I'm confident there's utility and value to this library, it's now a matter of delivering!

Side Projects


This is a Babashka script project that pulls feed.atom from https://world.hey.com/adam.james, checks for changes if a feed has already been pulled, and pulls, parses, and saves new articles.

This project is part of my effort to improve my design and execution skills. It's nice because it has a clear scope and obvious completion point. Its utility can be verified easily (does it actually work to download new articles?).

I'm happy with how this project has turned out, and recognize some key areas where I can improve for my next projects:

  • Write tests before and during programming sessions. I did some 'post-facto' test writing, which is fine, but probably leads to ineffective tests overall.
  • Commit early and often. Use branches more effectively to isolate features and bug fixes.

I'll see how things go with other projects next month!

Oh, and here's the interactive RSS-Saver blog post. Keep your eyes open for more posts like this, because they're really fun to work on.


This is a tool I'm working on to help produce interactive CLJS blog posts. It's getting a bit of attention, so I really have to make sure it works well. That'll be part of the coming month's responsibilities.

User scientific-coder on GitHub has asked about the status of the 'advanced build' feature of Radish, which is meant to detect and compile dependencies from your .org files automatically. It 'works on my machine', but that's obviously unacceptable for other users. I'll be working on this!

They also pointed out some inconsistent writing in the readme. Yet another area where I can improve as a dev: written communication. 


Cypress is a library I started to collect various generative art functions and ideas. The output so far is quite enjoyable, and I'm excited to build some interactive sites as my art work evolves.

I love how this project is evolving already. People really liked it when I shared on Twitter, which is always exciting. But beyond vanity, it's already forced me to figure out the delaunay triangulation and Convex hull algorithms, both of which are critical building blocks for union, difference, and intersection functions of polygons. These are functions I'll be carefully adding into SVG-clj next month.

An interactive post for this 'polygen' idea is in the works for the next month!

Looking Forward

I'm hoping to accomplish at least some of the following things in October.

  •  bring svg-clj to a stable, usable release beyond 0.0.3-SNAPSHOT.
  • finish truss-clj as a Forge example project
  • make at least 2 youtube videos
  • produce at least 2 'open design' projects
  • finish 1 more side project similar in size to RSS-Saver
  • further improve the look and feel of my Twitch Streams
  • experiment with non-programming streams (I have some gaming ideas for fun/charity)

Conclusion

I feel alright about my month's productivity, though it's clear I still need to improve my project and time management. October should be another opportunity to improve. I'm weirdly proud of the fact that I am actually keeping a Todo list for my various projects. It's a step towards more professional behaviour.

A TODO list freaked me out for a bit as it reminds me of my (miserable) experiences working in offices - a thing I'm trying to avoid by building a more independent career. But I want to be a good contributor to society throughout my life, so some semblance of organization is clearly necessary. I'm just saying, this is a big deal for me and I'm proud of it as a positive change.

Anyway,

That is all for this month. Please let me know if you have any questions or comments.

Support

If you want to support my work, you can provide a one time donation here:
https://ko-fi.com/adamjames

Or you can become a Patron of mine here:
https://www.patreon.com/adam_james

Support is never required by me, and anything I write or produce publicly (not explicitly as a paid product) is always free to consume with no obligation or expectation. I want to be a maker and a creator, and much of the time sharing work is reward enough. 

At the same time, we live in a world where money is very important, and I won't lie and say I don't need some. If you feel so inclined to share a donation, just know that I am extremely grateful.