GithubHelp home page GithubHelp logo

thi-ng / geom Goto Github PK

View Code? Open in Web Editor NEW
940.0 51.0 79.0 5.25 MB

2D/3D geometry toolkit for Clojure/Clojurescript

License: Apache License 2.0

Shell 0.03% Clojure 99.82% HTML 0.15%
geometry visualization mesh-generation opengl webgl voxel svg stl obj ply

geom's People

Contributors

benalbrecht avatar cassiel avatar dgtized avatar dimovich avatar fdb avatar gitter-badger avatar jgmize avatar postspectacular avatar reitzensteinm avatar rovanion avatar stwind avatar zackteo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geom's Issues

pluggable element-wise matrix operations

This is maybe too specific to my use case but I'll try anyway.

I'm tied of manually constructing matrices in GLSL code. I'd rather symbolically compute some matrix and use gamma to emit the code. I especially don't want to rewrite the logic for various eg rotation or perspective transformations. Too easy to get it wrong unless you've done it before.

Although geom supports pluggable *,+ etc, that only applies at the matrix level. Operations on elements bottom out at macromath, which in principle is pluggable but the geom matrix types have been hardwired to specific operations.

So: can we have matrix types where the user supplies the elementwise arithmetic operations? If its an easy thing to do I think it would be quite cool.

update overview diagram

  • needs to reflect new structure
  • make nodes clickable (link to source file)
  • automate generation (walk ns tree?, add meta to exclude namespace?)
  • script could also be used to generate textual master TOC

CLJS serialization story for SVG

For CLJ hiccup serializes SVG's as in

#?(:clj
   (defn serialize
     ^String [svg] (str xml-preamble (html {:mode :xml} svg))))

I have tried multiple alternatives for CLJS (hiccups, hipo and sablono for react), which AFAIK each miss an :xml mode.
sablono works properly for the area and line plot example, but fails when used with the bar graph.

In Om the following returns a valid react component based on the line-plot example:

(ns geom-test.geom
  (:require
    [om.core :as om :include-macros true]
    [sablono.core :refer-macros [html]]
    [thi.ng.geom.viz.core :as viz]
    [thi.ng.geom.svg.core :as svg]
    [thi.ng.math.core :as m :refer [PI]]))

(defn test-equation
  [t] (let [x (m/mix (- PI) PI t)] [x (* (Math/cos (* 0.5 x)) (Math/sin (* x x x)))]))

(def viz-spec
  {:x-axis (viz/linear-axis
             {:domain [(- PI) PI] :range [50 580] :major (/ PI 2) :minor (/ PI 4) :pos 250})
   :y-axis (viz/linear-axis
             {:domain     [-1 1] :range [250 20] :major 0.2 :minor 0.1 :pos 50
              :label-dist 15 :label {:text-anchor "end"}})
   :grid   {:attribs {:stroke "#caa"}
            :minor-y true}
   :data   [{:values  (map test-equation (m/norm-range 200))
             :attribs {:fill "none" :stroke "#0af"}
             :layout  viz/svg-line-plot}]})

(defn line-plot [_ owner]
  (om/component
    (html
      [:svg {:width 600 :height 320}
       (viz/svg-plot2d-cartesian viz-spec)])))

Add :fn opt to tessellate, detangle from `subdivide`

Adding tessellation :fn arg as opt is a good thing, but currently causes (for many, not all impls) to run subdivide first and the default config for that is 2x2, causing extraneous /unwanted results...

Options:

  1. remove call to subdivide from within tessellate. That means user code wanting both will have to be rewritten as:
(-> (g/subdivide _ {}) (mapcat #(g/tessellate _)))
  1. set subdivide default res to 1, causing no subdivision (not great...)

SVG rendered incorrectly in continental Europe

I tried generating the scatter-linear.svg example from thi.ng.geom.viz.core:

schermafbeelding 2016-02-25 om 23 07 35

Apparently, string formatting is locale-dependent, and my locale uses the comma as decimal mark. The SVG file rendered well after doing:

    (import '(java.util Locale))
    (Locale/setDefault (Locale. "en" "US"))

ClassCastException in fit-all-into-aabb

(thi.ng.geom.aabb/fit-all-into-aabb
(thi.ng.geom.aabb/aabb)
[(thi.ng.geom.triangle/triangle3 [[0 0 0] [0.3 0.3 0] [0.3 0 1]])])

--> ClassCastException thi.ng.geom.core.vector.Vec3 cannot be cast to java.lang.Number clojure.lang.Numbers.minus (Numbers.java:135)

inconsistent results in `subdivide` for rects divided six or seven times

Expected:

(count (geom/subdivide (rect/rect 1) {:cols 5, :rows 1})) => 5
(count (geom/subdivide (rect/rect 1) {:cols 6, :rows 1})) => 6
(count (geom/subdivide (rect/rect 1) {:cols 7, :rows 1})) => 7
(count (geom/subdivide (rect/rect 1) {:cols 8, :rows 1})) => 8

Actual:

(count (geom/subdivide (rect/rect 1) {:cols 5, :rows 1})) => 5
(count (geom/subdivide (rect/rect 1) {:cols 6, :rows 1})) => 7
(count (geom/subdivide (rect/rect 1) {:cols 7, :rows 1})) => 8
(count (geom/subdivide (rect/rect 1) {:cols 8, :rows 1})) => 8

The root cause seems to be in these two lines with the following results:

((juxt count last) (range 0.0 1.0 (/ 1.0 5))) => [5 0.8]
((juxt count last) (range 0.0 1.0 (/ 1.0 6))) => [7 0.9999999999999999]
((juxt count last) (range 0.0 1.0 (/ 1.0 7))) => [8 0.9999999999999998]
((juxt count last) (range 0.0 1.0 (/ 1.0 8))) => [8 0.875]

colorbar

Hi,

How to add a colorbar to a heatmap plot?

Thanks!

Is there an example which uses multiple textures?

I'm terribly sorry that I'm posing what's essentially a support question here on the issue tracker. But we've been unable to figure out how to use multiple textures with geom and have equally been able to find an example either among your workshops or in the given WebGL examples.

More specifically: What is it that determines :target of the map returned by buf/load-texture? Because for our application it's always the same value, i.e. all textures get loaded into the same texture unit.

Or it may be that I'm misunderstanding the purpose of :target Reading into the code of load-texture and then make-texture in buffers.cljc I see that :target is always set to glc/texture-2d, i.e. 3553.

Looked up the documentation on glBindTexture which seemed to indicate that I had completely misunderstood the purpose of :target which brings my question back to 0.

On with my adventure through your code: Through a refresh of my WebGL knowledge I found that it's gl.activeTexture() which selects which texture unit the texture is uploaded to, and in your buffers.cljc that's called in bind. Thing is that make-texture which in turn is what's called from load-texture doesn't pass on a second argument unit to bind which means that texture unit 0 is only ever used. It seems to me like some modifications to thi.ng/geom are requiered to use multiple textures.

How to load textures from file?

The samples say use:

[thi.ng.geom.gl.buffers :as glbuf]

...

(let [file-tex  (glbuf/load-texture gl {:callback (fn [tex img] (vreset! tex-ready true))
                                        :src      "img/cubev.png"
                                        :flip     true})]

But I just get a thi.ng.geom.gl.buffers not found. I've found this with all namespaces that start with thi.ng.geom.gl. Is it possible I am missing a dependency? Or samples are outdated?

legend?

Hi, thanks for the cool library!

I couldn't find any reference, therefore I'm asking here: is it possible, and if yes, what's the recommended way to draw a legend to the plot generated with geom.viz module?

Does not compile in CLJS

geom/color/math, none compiles from a .cljs file

lein deps:

                 [org.clojure/clojure "1.7.0"]
                 [org.clojure/clojurescript "1.7.122"]
                 [figwheel-sidecar "0.4.0"]
                 [thi.ng/color "1.0.0"]

Filename: core.cljs

Content:

(ns geom-test.core
  (:require [thi.ng.color.core :as col]))

Exception:

Exception in thread "main" clojure.lang.ExceptionInfo: No such namespace: thi.ng.color.core, could not locate thi/ng/color/core.cljs, thi/ng/color/core.cljc, or Closure namespace "thi.ng.color.core" {:tag :cljs/analysis-error}, compiling:(/Users/den/Dropbox/dev/code/vimsical/geom-test/script/repl.clj:3:1)
    at clojure.lang.Compiler.load(Compiler.java:7239)
    at clojure.lang.Compiler.loadFile(Compiler.java:7165)
    at clojure.main$load_script.invoke(main.clj:275)
    at clojure.main$script_opt.invoke(main.clj:337)
    at clojure.main$main.doInvoke(main.clj:421)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: clojure.lang.ExceptionInfo: No such namespace: thi.ng.color.core, could not locate thi/ng/color/core.cljs, thi/ng/color/core.cljc, or Closure namespace "thi.ng.color.core" {:tag :cljs/analysis-error}
    at clojure.core$ex_info.invoke(core.clj:4593)
    at cljs.analyzer$error.invoke(analyzer.cljc:543)
    at cljs.analyzer$error.invoke(analyzer.cljc:541)
    at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1649)
    at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2485)
    at cljs.analyzer$analyze_STAR_$fn__2091.invoke(analyzer.cljc:2566)
    at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
    at clojure.core$reduce.invoke(core.clj:6518)
    at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2566)
    at cljs.analyzer$analyze.invoke(analyzer.cljc:2581)
    at cljs.analyzer$analyze_file$fn__2142.invoke(analyzer.cljc:2825)
    at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2820)
    at figwheel_sidecar.repl$analyze_build.invoke(repl.clj:242)
    at figwheel_sidecar.repl$analyze_builds.invoke(repl.clj:247)
    at figwheel_sidecar.repl$run_autobuilder_helper.invoke(repl.clj:295)
    at figwheel_sidecar.repl$start_autobuild.invoke(repl.clj:366)
    at figwheel_sidecar.repl$start_repl.invoke(repl.clj:466)
    at figwheel_sidecar.repl$cljs_repl.invoke(repl.clj:488)
    at figwheel_sidecar.repl$cljs_repl.invoke(repl.clj:475)
    at figwheel_sidecar.repl_api$cljs_repl.invoke(repl_api.clj:77)
    at user$eval16094.invoke(repl.clj:3)
    at clojure.lang.Compiler.eval(Compiler.java:6782)
    at clojure.lang.Compiler.load(Compiler.java:7227)
    ... 14 more```

WebGL context as dynamic var

Currently I have to manage the reference to GL context in every namespace that uses thi.ng.geom.webgl. It would clean the user code a lot if we could remove all the occurrences of gl symbol that are not context creation. Having written a small WebGL library in CLJS myself, I used a dynamic var in the core module, to allow users bind it to their WebGL context somewhere in the app initialization. Then all other namespaces that need GL context, can simply use the symbol required. Eg.

;; core namespace
(ns thi.ng.geom.webgl.core)
(def ^dynamic *gl* nil)

;; any other thi.ng namespace
(ns thi.ng.geom.webgl.buffers
  (:require [thi.ng.geom.webgl.core :refer [*gl*]]))
(defn make-attribute-buffer
  [target draw-type data]
  (let [buffer (.createBuffer *gl*)]
    (.bindBuffer *gl* target buffer)
    (.bufferData *gl* target data draw-type)
    buffer))

;; user code
(ns example.gfx
  (:require [thi.ng.geom.webgl.core :as gl :refer [*gl*]]))
(defn -main [canvas]
  (binding [*gl* (gl/gl-context canvas)]
    ;; very interesting graphics goes here
    ))

[CLJS] `lin-tick-marks` with `0` delta causes overflow

Hi Karsten, just tracked down this error after tracing it to linear-axis in thi.ng.geom.viz.core.
In Java an exception is thrown, but in browser (Chrome, at least) it just overflows and ramps the memory usage up super quick. Happy to PR if you'd advise on how you'd like it fixed. Zero check and empty list return?

(defn lin-tick-marks
  [[d1 d2] delta]
  (if (zero? delta)
    '()
    (let [dr (- d2 d1)
          d1' (m/roundto d1 delta)]
      (filter #(do (println % (m/in-range? d1 d2 %))
                   (m/in-range? d1 d2 %)) (range d1' (+ d2 delta) delta)))))

`filter-attribs` excludes using attribute names with names shorter than three characters

(defn filter-attribs
  [attribs]
  (loop [acc (transient attribs), ks (keys attribs)]
    (if ks
      (recur
       (if (= "__" (subs (name (first ks)) 0 2)) (dissoc! acc (first ks)) acc)
       (next ks))
      (persistent! acc))))

The call to subs prevents passing in keys such as :x or :y in the attribute map of a SVG hiccup vector. It would be handy to be able to use these with svg/group.

gmesh - compute-vertex-normals broken?

In cljs this throws "Invalid arity: 0"

(defn test-gmesh
  []
  (-> (gmesh)
      (g/add-face [(vec3 0 0 0) (vec3 1 0 0) (vec3 1 1 0)])
      (g/compute-vertex-normals)))

Am I missing something here? (like the mesh needing to be a manifold?)

Edit: (gmesh.cljx#243)

(transduce ntx g/+ (vec3 0 0 0))

Seems to fix the issue.

[org.clojure/clojure "1.7.0-beta3"]
[org.clojure/clojurescript "0.0-3291"]
[thi.ng/geom "0.0.783"]

[lein-cljsbuild "1.0.5"]

Butterfly subdivision produces faces with nils

(-> (cuboid 40)
    (g/as-mesh {:mesh (gm/gmesh)})
    sd/butterfly)

;;=>

{:vertices
 {nil
  #{{:next [0.0 20.0 40.0], :prev [0.0 40.0 40.0], :f [[0.0 40.0 40.0] nil [0.0 20.0 40.0]]}
;; [...]

mesh->csg stack overflow

(-> (cuboid 80)
    (g/as-mesh {:mesh (gm/gmesh)})
    csg/mesh->csg)

... works as expected, but if I try to catmull-clark the mesh before converting to CSG, like this:

(-> (cuboid 80)
    (g/as-mesh {:mesh (gm/gmesh)})
    sd/catmull-clark
    csg/mesh->csg)

... I get this stack overflow:

                       RT.java:  721  clojure.lang.RT/get
                      csg.cljc:   58  thi.ng.geom.mesh.csg$split_poly/invoke
                      csg.cljc:  143  thi.ng.geom.mesh.csg$csg_node$fn__18902/invoke
         PersistentVector.java:  333  clojure.lang.PersistentVector/reduce
                      core.clj: 6518  clojure.core/reduce
                      csg.cljc:  142  thi.ng.geom.mesh.csg$csg_node/invoke

... do more complicated meshes push the recursive csg-node function too deep?

workshop bug: basic

hey there, this is the bug which we found on the workshop in bratislava

doing (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}) (g/translate [0 0 10])) will result in an error

here's the stack

            IllegalArgumentException No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double  clojure
            .core/-cache-protocol-fn (core_deftype.clj:568)
            ws-bra-1.core=> *e
            #error {
             :cause "No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double"
             :via
             [{:type java.lang.IllegalArgumentException
               :message "No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double"
               :at [clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 568]}]
             :trace
             [[clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 568]
              [clojure.core$_cache_protocol_fn invoke "core_deftype.clj" 560]
              [thi.ng.math.core$eval1449$fn__1450$G__1424__1473 invoke "core.cljc" 8]
              [thi.ng.geom.basicmesh$eval8466$fn__8507$fn__8508 invoke "basicmesh.cljc" 129]
              [thi.ng.geom.utils$transform_mesh$fn__7797 invoke "utils.cljc" 426]
              [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
              [clojure.core.protocols$fn__6742 invokeStatic "protocols.clj" 75]
              [clojure.core.protocols$fn__6742 invoke "protocols.clj" 75]
              [clojure.core.protocols$fn__6684$G__6679__6697 invoke "protocols.clj" 13]
              [clojure.core$reduce invokeStatic "core.clj" 6545]
              [clojure.core$reduce invoke "core.clj" 6527]
              [thi.ng.geom.utils$transform_mesh invokeStatic "utils.cljc" 425]
              [thi.ng.geom.utils$transform_mesh invoke "utils.cljc" 417]
              [thi.ng.geom.basicmesh$eval8466$fn__8507 invoke "basicmesh.cljc" 129]
              [thi.ng.geom.core$eval3115$fn__3116$G__3106__3137 invoke "core.cljc" 43]
              [ws_bra_1.core$make_rings_along_curve$fn__14626 invoke "core.clj" 59]
              [clojure.core$map_indexed$mapi__7050$fn__7051 invoke "core.clj" 7022]
              [clojure.lang.LazySeq sval "LazySeq.java" 40]
              [clojure.lang.LazySeq seq "LazySeq.java" 49]
              [clojure.lang.RT seq "RT.java" 521]
              [clojure.core$seq__4357 invokeStatic "core.clj" 137]
              [clojure.core$print_sequential invokeStatic "core_print.clj" 46]
              [clojure.core$fn__6072 invokeStatic "core_print.clj" 153]
              [clojure.core$fn__6072 invoke "core_print.clj" 153]
              [clojure.lang.MultiFn invoke "MultiFn.java" 233]
              [clojure.tools.nrepl.middleware.pr_values$pr_values$fn$reify__614 send "pr_values.clj" 35]
              [clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__648$fn__661 invoke "interruptible_eval.clj" 113]
              [clojure.main$repl$read_eval_print__7408 invoke "main.clj" 241]
              [clojure.main$repl$fn__7417 invoke "main.clj" 258]
              [clojure.main$repl invokeStatic "main.clj" 258]
              [clojure.main$repl doInvoke "main.clj" 174]
              [clojure.lang.RestFn invoke "RestFn.java" 1523]
              [clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__648 invoke "interruptible_eval.clj" 87]
              [clojure.lang.AFn applyToHelper "AFn.java" 152]
              [clojure.lang.AFn applyTo "AFn.java" 144]
              [clojure.core$apply invokeStatic "core.clj" 646]
              [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
              [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
              [clojure.lang.RestFn invoke "RestFn.java" 425]
              [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
              [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
              [clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__693$fn__696 invoke "interruptible_eval.clj" 222]
              [clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__688 invoke "interruptible_eval.clj" 190]
              [clojure.lang.AFn run "AFn.java" 22]
              [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
              [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
              [java.lang.Thread run "Thread.java" 745]]}
            ws-bra-1.core=>

            ws-bra-1.core=> (-> (circle 20) (g/as-pol
            g/as-polar     g/as-polygon
            ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4))
            #thi.ng.geom.types.Polygon2{:points [[20.0 0.0] [1.2246467991473533E-15 20.0] [-20.0 2.4492935982947065E-15] [-3.673940397442059E-15 -20.0]]
            }
            ws-bra-1.core=> (require 'ws-bra-1.core :reload)

            CompilerException java.lang.IllegalArgumentException: No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for cla
            ss: java.lang.Double, compiling:(ws_bra_1/core.clj:63:1)
            ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude)
            g/extrude         g/extrude-shell
            ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}))
            #thi.ng.geom.types.BasicMesh{:vertices #{0.0 1.0 20.0 [-3.673940397442059E-15 -20.0 0.0] [-20.0 2.4492935982947065E-15 0.0] [-20.0 2.4492935
            982947065E-15 1.0] [-3.673940397442059E-15 -20.0 1.0] [20.0 0.0 1.0] [1.2246467991473533E-15 20.0 1.0] [20.0 0.0 0.0] [1.2246467991473533E-1
            5 20.0 0.0]}, :faces #{#object[thi.ng.geom.meshface.MeshFace 0x1e1905bf "[[[-20.0 2.4492935982947065E-15 0.0] [-3.673940397442059E-15 -20.0
            0.0] [-3.673940397442059E-15 -20.0 1.0] [-20.0 2.4492935982947065E-15 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x6bfd871b "[[[-3.67394
            0397442059E-15 -20.0 0.0] [20.0 0.0 0.0] [20.0 0.0 1.0] [-3.673940397442059E-15 -20.0 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x762cb
            26f "[[[1.2246467991473533E-15 20.0 0.0] [-20.0 2.4492935982947065E-15 0.0] [-20.0 2.4492935982947065E-15 1.0] [1.2246467991473533E-15 20.0
            1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x2657b8ec "[[[20.0 0.0 0.0] [1.2246467991473533E-15 20.0 0.0] [1.2246467991473533E-15 20.0 1
            .0] [20.0 0.0 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x70357564 "[([-3.673940397442059E-15 -20.0 0.0] [-20.0 2.4492935982947065E-15
            0.0] [1.2246467991473533E-15 20.0 0.0] [20.0 0.0 0.0])]"] #object[thi.ng.geom.meshface.MeshFace 0x77f7e126 "[[20.0 0.0 1.0]]"]}, :fnormals {
            }}
            ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}) (g/translate [0 0 10]))
            IllegalArgumentException No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double  clojure
            .core/-cache-protocol-fn (core_deftype.clj:568)

Getting error on latest clojurescript

As the title says, I am getting and error when using the latest version of clojurescript 1.10.x
with thi.ng/geom. When using together with figwheel i get this following error.

 ----  Could not Analyze  resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc   line:437  column:41  ----

  Can't recur here at line 437 resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc

  435                          (set! (.-onselectstart canvas) (constantly false))
  436                          (if ctx ctx (recur (next ids))))
  437                        (catch js/Error e (recur (next ids))))))]
                                               ^--- Can't recur here at line 437 resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc
  438          (or ctx (err/unsupported! "WebGL not available"))))))
  439  #?(:clj
  440     (defn clear-color-buffer

----  Analysis Error : Please see resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc  ----

I use this version [org.clojure/clojurescript "1.9.89"] to make it work.

`PArea` implementation for custom `gmesh` fails

I'm writing a CLJS program that makes a mesh for a dodecahedron by calculating all of its faces, but I'm unable to get its surface area with a call to thi.ng.geom.core/area. I've reduced my program to what's necessary to reproduce the problem below

(ns dodecahedron.core
  (:require [thi.ng.math.core :as math]
            [thi.ng.geom.core :as geom]
            [thi.ng.geom.gmesh :as gmesh]
            [thi.ng.geom.types.utils :as tu]))

(def ^:const τ math/TWO_PI)

;; spherical coordinates are in the physics convention
;; (radial distance, polar angle, azimuthal)
(defn ->cartesian [[r theta phi]]
  [(* r (js/Math.sin theta) (js/Math.cos phi))
   (* r (js/Math.sin theta) (js/Math.sin phi))
   (* r (js/Math.cos theta))])

(defn dodecahedron [s]
  (let [r (* math/SQRT3 math/PHI s 0.5)
        theta (js/Math.asin (/ (* math/SQRT3 math/PHI)))
        central-angle (/ τ 5)
        offset (* central-angle 0.5)
        quad #(let [a (* % central-angle)]
                (vector [r (* 2 theta) a]
                        [r (* 4 theta) a]
                        [r (* 5 theta) (+ a offset)]
                        [r (* 7 theta) (+ a offset)]))
        spherical-coords (mapcat quad (range 5))
        cart-coords (map ->cartesian spherical-coords)
        [b a f z g k p t l q r s h m i n c d e j] cart-coords
        faces [[a b c d e] [k g b a f] [q l g k p] [m h l q r] [d c h m i] [l h c b g]
               [z f a e j] [t p k f z] [s r q p t] [n i m r s] [j e d i n] [t z j n s]]]
    (tu/into-mesh (gmesh/gmesh) gmesh/add-face faces)))
(geom/area (dodecahedron 5))
#object[Error Error: No protocol method PMathOps.- defined for type cljs.core/PersistentVector: [3.142002665914173 2.2827985598928664 -5.831362385532202]]
     cljs.core/missing-protocol (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:261:4)
     Function.thi.ng.geom.core._.cljs$core$IFn$_invoke$arity$2 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core.cljc:6:1)
     thi.ng.geom.core/- (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core.cljc:6:1)
     thi.ng.geom.core.utils/norm-sign3 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core/utils.cljc:259:28)
     Function.thi$ng$geom$core$utils$tri_area3 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core/utils.cljc:265:19)
     Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:3448:18)
     cljs$core$apply (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:3439:1)
     Function.G__7855__2 (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:4202:24)

Am i constructing the mesh incorrectly in some way? Or is this a legitimate bug in the area implementation?

make final decision about arities of various protocol methods

Currently common protocol methods like translate, scale and the various basic vector math ops allow specifying coordinate args as vectors or individual coords, e.g.

(g/translate (a/aabb 1) (vec3 10 20 30))
(g/translate (a/aabb 1) [10 20 30])
(g/translate (a/aabb 1) 10 20 30)

About the last case:

Pros:

  • in some cases avoids construction of temp vectors, though most internal usage doesn't make use of this arity option, since args are mostly vectors already

Cons:

  • considerable additional effort required for maintaining 3-arities of each implementation
  • currently missing implementations of this aritiy in various types
  • extra argument type checking required for last case

Proposal:

  • remove protocol 4-arg arity (w/ individual coords) from protocols and enforce usage of vector args

Thoughts?

[CLJS] Replacement for byte-array in commits->matrix for GitHub heatmap?

Hi there - thanks for the amazing tools. 😄 I've got a bar graph working in my reagent project and am now looking at adding the GitHub-commit style visualisation.

  1. When it comes to the commits->matrix function I'm stuck as byte-array doesn't exist in ClojureScript. I tried binding mat to ((nd/ndarray :int32 (repeat (* 7 weeks) 0) [7 weeks]) but it didn't make any difference - I get a weird error down the line:
[Error] TypeError: f.call is not a function. (In 'f.call(null,x)', 'f.call' is undefined)
	(anonymous function) (core.js:125)
	(anonymous function) (core.js:980)
	(anonymous function) (core.js:18375:140)
	(anonymous function) (core.js:7888:101)
	cljs$core$IFn$_invoke$arity$3 (core.js:7889)
	cljs$core$IReduce$_reduce$arity$3 (core.js:11385)
	cljs$core$IFn$_invoke$arity$3 (core.js:7983)
	cljs$core$IFn$_invoke$arity$2 (core.js:18374:82)
	cljs$core$mapv (core.js:18355)
	thi$ng$geom$viz$core$svg_axis_STAR_ (core.js:950:502)
	thi$ng$geom$viz$core$svg_x_axis_cartesian (core.js:968)
	thi$ng$geom$viz$core$svg_plot2d_cartesian (core.js:1063:172)
	**manul_frontend$core$github (core.js:660:274)**
	manul_frontend$core$home_page (core.js:687:1182)
	G__9104__1 (core.js:3733:125)
	G__9104 (core.js:3886)
	(anonymous function) (component.js:127)
	reagent$impl$component$wrap_render (component.js:150)
	reagent$impl$component$do_render (component.js:196)
	(anonymous function) (component.js:222)
	reagent$ratom$in_context (ratom.js:61)
	reagent$ratom$deref_capture (ratom.js:70)
	reagent$ratom$run_in_reaction (ratom.js:1424)
	home-page_render (component.js:220)
	measureLifeCyclePerf (react-dom.inc.js:4529)
	_renderValidatedComponentWithoutOwnerOrContext (react-dom.inc.js:5249)
	_renderValidatedComponent (react-dom.inc.js:5276)
	performInitialMount (react-dom.inc.js:4816)
	mountComponent (react-dom.inc.js:4712)
	mountComponent (react-dom.inc.js:11542)
	mountChildren (react-dom.inc.js:10429)
	_createInitialChildren (react-dom.inc.js:6164)
	mountComponent (react-dom.inc.js:5983)
	mountComponent (react-dom.inc.js:11542)
	performInitialMount (react-dom.inc.js:4825)
	mountComponent (react-dom.inc.js:4712)
	mountComponent (react-dom.inc.js:11542)
	performInitialMount (react-dom.inc.js:4825)
	mountComponent (react-dom.inc.js:4712)
	mountComponent (react-dom.inc.js:11542)
	mountComponentIntoNode (react-dom.inc.js:9757)
	perform (react-dom.inc.js:14724)
	batchedMountComponentIntoNode (react-dom.inc.js:9779)
	perform (react-dom.inc.js:14724)
	_renderNewRootComponent (react-dom.inc.js:9973)
	_renderSubtreeIntoContainer (react-dom.inc.js:10054)
	reagent$dom$render_comp (dom.js:49)
	cljs$core$IFn$_invoke$arity$3 (dom.js:121)
	reagent$dom$render (dom.js:102)
	cljs$core$IFn$_invoke$arity$2 (dom.js:112)
	reagent$dom$render (dom.js:98)
	cljs$core$IFn$_invoke$arity$2 (core.js:182)
	reagent$core$render (core.js:168)
	manul_frontend$core$mount_root (core.js:750)
	cljs$core$IFn$_invoke$arity$2 (core.js:13060)
	cljs$core$apply (core.js:13028)
	G__35851__delegate (build_app.js:11)
	cljs$lang$applyTo (build_app.js:27)
	cljs$core$IFn$_invoke$arity$2 (core.js:13057)
	cljs$core$apply (core.js:13028)
	(anonymous function) (file_reloading.js:2046)

Can I drop in a replacement for byte-array? I used int64 because int32 is not available in the CLJS version of ndarray.

  1. I've also tried binding commits to my raw data in the actual example hm-github.clj (so running on Clojure, not ClojureScript) and it actually doesn't work, saying CompilerException java.lang.IllegalArgumentException: Value out of range for byte: 228, compiling:(/Users/farhan/code/geom/geom-viz/babel/examples/hm-github.clj:57:1) - I definitely never had 228 commits in a day! But I guess the use of a byte array assumes a certain number of commits per day? Maybe if you can talk me through generally what's happening in this code I can fix it myself...

It's worth mentioning that my timestamp data is from another source, not GitHub commits. Here is the data as a list:

(1467504000 1467504000 1467849600 1467936000 1467936000 1468108800 1468108800 1468108800 1468108800 1468108800 1468368000 1468368000 1468454400 1468454400 1468454400 1468454400 1468454400 1467849600 1468627200 1468627200 1468627200 1479600000 1468540800 1468540800 1468713600 1468713600 1468713600 1468886400 1468886400 1468972800 1468972800 1469059200 1469059200 1469059200 1469145600 1469232000 1469232000 1469232000 1469577600 1469577600 1469750400 1469750400 1470182400 1470182400 1470268800 1470268800 1470268800 1470268800 1470355200 1470355200 1470528000 1470528000 1470528000 1470528000 1471132800 1471132800 1471132800 1471478400 1471478400 1471478400 1473292800 1473292800 1473292800 1473292800 1474416000 1474416000 1476316800 1476316800 1476316800 1476316800 1477094400 1477094400 1477699200 1477699200 1477785600 1477785600 1477785600 1477958400 1477958400 1477958400 1478044800 1478044800 1478044800 1478044800 1478131200 1478131200 1478131200 1478217600 1478217600 1478304000 1478304000 1478390400 1478390400 1478649600 1478649600 1478736000 1478736000 1478736000 1478822400 1478822400 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1479254400 1479254400 1479254400 1479340800 1479340800 1479340800 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479686400 1479686400 1479686400 1486771200 1486771200 1486857600 1486857600 1486944000 1486944000 1487203200 1487203200 1487203200 1487376000 1487376000 1487376000 1487721600 1487721600 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487980800 1487980800 1487980800 1488240000 1488326400 1488326400 1488326400 1488412800 1488412800 1488412800 1488412800 1488758400 1488758400 1488758400 1488931200 1488931200 1488931200 1489363200 1489363200 1489363200 1489536000 1489536000 1490227200 1490227200 1490227200 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490832000 1490832000 1490832000 1491696000 1491696000 1492214400 1492214400 1492819200 1492819200 1492819200 1492819200 1492819200 1492819200 1492819200 1495065600 1495065600 1495065600 1495324800 1495324800 1495324800 1495324800 1495324800 1495411200 1495411200 1496275200 1496275200 1496275200 1496275200 1497830400 1497830400 1497830400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498694400 1498694400 1498694400 1499558400 1499558400 1500681600 1500681600 1500681600 1500681600 1500681600 1500681600 1500681600 1501891200 1501891200 1502064000 1502064000 1502064000 1502323200 1502323200 1502323200 1502928000 1502928000 1502928000 1502928000)

Thanks for any help you can give.

Alternatively, could you maybe show me the code for this stuff on the thi.ng homepage?

screen shot 2017-08-29 at 23 14 03

CSG - Maximum call stack size exceeded

I'm aware the below polygons aren't a valid 'solid', omitting some polygons for clarity.
In my 'real' code I'm using g/extrude some-poly {:depth 280} on some 100 different extruded polygons, which all are succeeding apart from the one below.

This fails with "call stack size exceeded":

(def polys
  [
  [(vec3 942 440 0) (vec3 879 515 0) (vec3 884 527 0) (vec3 954 445 0)]
  [(vec3 942 440 0) (vec3 879 515 0) (vec3 879 515 280) (vec3 942 440 280)]
  ])

(mesh->csg
  (reduce
    (fn [m f]
      (g/add-face m f))
    (basic-mesh)
    polys))

But with the first polygon only mesh->csg succeeds:

(def polys
  [
  [(vec3 942 440 0) (vec3 879 515 0) (vec3 884 527 0) (vec3 954 445 0)]
  ])

With the second polygon only mesh->csg throws "call stack size exceeded" (?!)

(def polys
  [
  [(vec3 942 440 0) (vec3 879 515 0) (vec3 879 515 280) (vec3 942 440 280)]
  ])

This is bizarre :-) Seems the call to csg-node ends up in an endless loop.
Question of course is: how the hell can that happen with a single polygon?

It looks like some specific polygon orientations induce the problem.

Below the full "problem" mesh:

#thi.ng.geom.types.BasicMesh{
:vertices #{
  #<[942 440.8021545410156 0]>
  #<[879.2171630859375 515 0]> 
  #<[884.7828369140625 527 0]>
  #<[954 445.1978454589844 0]> 
  #<[884.7828369140625 527 280]>
  #<[954 445.1978454589844 280]> 
  #<[879.2171630859375 515 280]> 
  #<[942 440.8021545410156 280]>},
:faces #{
  (#<[942 440.8021545410156 0]> #<[879.2171630859375 515 0]> 
   #<[884.7828369140625 527 0]>   #<[954 445.1978454589844 0]>) 
     [#<[954 445.1978454589844 0]> 
      #<[884.7828369140625 527 0]> 
      #<[884.7828369140625 527 280]> 
      #<[954 445.1978454589844 280]>]
     [#<[884.7828369140625 527 0]> 
      #<[879.2171630859375 515 0]> 
      #<[879.2171630859375 515 280]> 
      #<[884.7828369140625 527 280]>] 
     [#<[879.2171630859375 515 0]> 
      #<[942 440.8021545410156 0]> 
      #<[942 440.8021545410156 280]> 
      #<[879.2171630859375 515 280]>] 
    [#<[942 440.8021545410156 0]> 
     #<[954 445.1978454589844 0]> 
     #<[954 445.1978454589844 280]>
     #<[942 440.8021545410156 280]>]
    [#<[954 445.1978454589844 280]> 
     #<[884.7828369140625 527 280]> 
     #<[879.2171630859375 515 280]>
     #<[942 440.8021545410156 280]>]}, :fnormals {}, :attribs {}}

The polygon used with (g/extrude poly {:depth 280})

#thi.ng.geom.types.Polygon2{
:points [
#<[942 440.8021545410156]> 
#<[879.2171630859375 515]> 
#<[884.7828369140625 527]> 
#<[954 445.1978454589844]>]}

Isosurface bug under CLJS?

The simple voxel eroded cube demonstration works a treat with clojure, but throws this exception when run with clojurescript in the browser:

Uncaught TypeError: vertices__$1.call is not a functionthi.ng.geom.voxel.isosurface.cell_vertice_builder @ isosurface.cljc:360(anonymous function) @ core.cljs:2138cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 @ core.cljs:2138cljs.core.LazySeq.cljs$core$IReduce$_reduce$arity$3 @ core.cljs:3047cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 @ core.cljs:2182cljs$core$reduce @ core.cljs:2153thi$ng$geom$voxel$isosurface$surface_mesh @ isosurface.cljc:391(anonymous function) @ voxels.cljs:24
reload.cljs:62 Reload

Material to getting start

Hi!
Sorry, I understand that this is not the right place where to ask this.
I'm a big fan of processing.org and toxiclibs but I'm a little bit bored about java as a language itself.

So here is a question: is there any tutorial or getting started or any other kind of advice to use thi.ng?

converting sphere to mesh produces incomplete mesh

Some of the triangles are missing, e.g.

(ns foo.core
  (:require [thi.ng.geom.sphere :as sphere]
            [thi.ng.geom.core :as g]))

(def sm (-> (sphere/sphere 2) (g/as-mesh {:res 3})))

(count (:faces sm)) ;; ==> 9

Visual inspection of the mesh in a stl viewer shows 3 triangles at each of the "poles". It seems there ought to be 6 triangles around the "equator", but I see only 3, leaving three holes.

question about drawing 3d objects in worldwind

I don't have too much opengl experience but I'm looking to do some visualisations using geom and worldwind.

I saw that both libraries use org.jogamp.jogl/jogl-all, if that helps integration at all.

I'm hoping to get some tips on how and where to start.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.