This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2015-12-05

## Channels

- # admin-announcements (8)
- # beginners (73)
- # boot (14)
- # cljsrn (4)
- # clojure (157)
- # clojure-indonesia (1)
- # clojure-poland (1)
- # clojure-russia (3)
- # clojurecup (32)
- # clojurescript (123)
- # clojurex (4)
- # core-async (8)
- # cursive (7)
- # datavis (26)
- # datomic (5)
- # hoplon (2)
- # off-topic (3)
- # om (41)
- # portland-or (6)
- # random (1)
- # re-frame (11)
- # slack-help (3)
- # specter (1)

After several rounds of refactoring I've gotten Catmull-Clark down to this (and I'm pretty happy with it):

```
(defn catmull-clark
"Return a mesh with additional faces and edge points for a smoothing effect."
[{:keys [faces edges vertices] :as mesh} & {:keys [get-f-point get-e-point get-v-point]}]
(let [get-fp (fn [mesh face]
(calc-vertex face))
get-ep (fn [edge e-faces f-points]
(gu/centroid (concat (vec edge) (mapv f-points e-faces))))
get-vp (fn [mesh vertex]
(let [f (gu/centroid (mapv gu/centroid
(gm/vertex-faces* mesh vertex)))
vn (gm/vertex-neighbors* mesh vertex)
n (count vn)
r (gu/centroid (mapv #(g/mix vertex %) vn))]
(g/addm (g/madd r 2.0 f) (g/* vertex (- n 3)) (/ 1.0 n))))
get-f-point (or get-f-point get-fp)
get-e-point (or get-e-point get-ep)
get-v-point (or get-v-point get-vp)
new-face (fn [[p c n] f-point e-points]
[(e-points #{p c}) c (e-points #{c n}) f-point])
new-faces (fn [face f-point e-points]
(mapv #(new-face % f-point e-points) (face-loop-triples face)))
subdivide (fn [[face f-point] e-points]
(new-faces face f-point e-points))
v-replace (fn [face vert-map] (replace vert-map face))
f-points (into {} (map (fn [face]
[face (get-f-point mesh face)]) faces))
e-points (into {} (map (fn [[edge e-faces]]
[edge (get-e-point edge e-faces f-points)]) edges))
v-points (into {} (map (fn [vertex]
[vertex (get-v-point mesh vertex)]) (keys vertices)))]
(->> (mapcat #(subdivide % e-points) f-points)
(map #(v-replace % v-points))
(g/into (g/clear* mesh)))))
```

And here is an example showing how to create a variant by supplying an alternate function:

```
(defn not-quite-catmull-clark
"Return a mesh with additional faces and edge points for a smoothing effect."
[mesh]
(let [get-e-point (fn [edge _ _] (gu/centroid (vec edge)))]
(catmull-clark mesh :get-e-point get-e-point)))
```

I wish @toxi were here to answer some basic question about http://thi.ng geom. ðŸ˜ž

It's frustrating trying to figure out how to do something I know is easy, I just haven't done it before so I'm not sure what particular method of which protocol is going to do the trick. I have a vertex and I have the centroid of the mesh and now I need to calculate a new vertex that is a certain distance closer to the mesh centroid by a fixed (not proportional) amount.

I might get a clue from one of the extrusion functions, since basically I'm working on "skeletonizing" a mesh, which is kind of like a fancy extrusion of sorts.

I think we forgot to mention to @toxi that once you show your face in *#C0F0V8DT5*, you're obligated to be here at all times ðŸ˜‰

2D extrude didn't help because that's super easy as it just does a simple offset along the z axis

convex-hull on a polygon sounded like it might hold a clue, but it just looks like Greek to me... ðŸ˜ž

It's probably just a simple vector math operation - guess I get to learn more about vec3

I think I'm going to give up until @toxi comes back because that matrix math stuff doesn't look fun.

except that requires me to tessellate the mesh, which I don't want to do at this point of the process...

@toxi: when you are here some time I might still need help with skeletonizing a mesh. To begin I'd be happy with just creating a shell or inset hull of the shape, then I won't have any trouble putting holes into each face.

I don't want to triangulate my faces until I have to. If I know the face is planar I want to be able to get a normal for it. I see `vertices-planar?`

but it doesn't seem to be used anywhere.