Missing IMathOps :- method for java.lang.Double when using csg/mesh->csg
When trying to convert a mesh (tested with either basic-mesh or gmesh) to a CSG node (using csg/mesh->csg) to compute the union of several nodes, I receive the following error. No implementation of method: :- of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double. Further investigation shows that it's happening in the ortho-normal function, which is being used when computing the plane for each polygon. At first glance, this seems to be a reoccurrence of #40, which featured the same error with :+ instead. I've reproduced the stack trace below.
Show: Project-Only All
Hide: Clojure Java REPL Tooling Duplicates (15 frames hidden)
1. Unhandled java.lang.IllegalArgumentException
No implementation of method: :- of protocol: #'thi.ng.math.core/IMathOps
found for class: java.lang.Double
core_deftype.clj: 583 clojure.core/-cache-protocol-fn
core_deftype.clj: 575 clojure.core/-cache-protocol-fn
core.cljc: 8 thi.ng.math.core$eval19046$fn__19138$G__19023__19161/invoke
utils.cljc: 306 thi.ng.geom.utils$ortho_normal/invokeStatic
utils.cljc: 303 thi.ng.geom.utils$ortho_normal/invoke
plane.cljc: 32 thi.ng.geom.plane$plane_from_points/invokeStatic
plane.cljc: 29 thi.ng.geom.plane$plane_from_points/invoke
plane.cljc: 30 thi.ng.geom.plane$plane_from_points/invokeStatic
plane.cljc: 29 thi.ng.geom.plane$plane_from_points/invoke
csg.cljc: 169 thi.ng.geom.mesh.csg$csg_polygon/invokeStatic
csg.cljc: 164 thi.ng.geom.mesh.csg$csg_polygon/invoke
csg.cljc: 212 thi.ng.geom.mesh.csg$mesh__GT_csg$fn__24580/invoke
core.clj: 2755 clojure.core/map/fn
LazySeq.java: 42 clojure.lang.LazySeq/sval
LazySeq.java: 51 clojure.lang.LazySeq/seq
RT.java: 535 clojure.lang.RT/seq
core.clj: 137 clojure.core/seq
core.clj: 137 clojure.core/seq
csg.cljc: 176 thi.ng.geom.mesh.csg$csg_node/invokeStatic
csg.cljc: 171 thi.ng.geom.mesh.csg$csg_node/invoke
csg.cljc: 213 thi.ng.geom.mesh.csg$mesh__GT_csg/invokeStatic
csg.cljc: 209 thi.ng.geom.mesh.csg$mesh__GT_csg/invoke
core.clj: 2753 clojure.core/map/fn
LazySeq.java: 42 clojure.lang.LazySeq/sval
LazySeq.java: 51 clojure.lang.LazySeq/seq
LazySeq.java: 73 clojure.lang.LazySeq/first
RT.java: 692 clojure.lang.RT/first
core.clj: 55 clojure.core/first
core.clj: 55 clojure.core/first
core.clj: 53 solar-stl.core/parse-roof
core.clj: 45 solar-stl.core/parse-roof
REPL: 266 solar-stl.core/eval25749
REPL: 266 solar-stl.core/eval25749
Compiler.java: 7177 clojure.lang.Compiler/eval
Compiler.java: 7132 clojure.lang.Compiler/eval
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
core.clj: 1973 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 437 clojure.main/repl/read-eval-print/fn
main.clj: 437 clojure.main/repl/read-eval-print
main.clj: 458 clojure.main/repl/fn
main.clj: 458 clojure.main/repl
main.clj: 368 clojure.main/repl
RestFn.java: 137 clojure.lang.RestFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 660 clojure.core/apply
regrow.clj: 20 refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 202 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 201 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 831 java.lang.Thread/run
Further investigation reveals that the BasicMesh may be generating wrong. I get the following results when I inspect the generation of the mesh in CIDER:
Class: thi.ng.geom.types.BasicMesh
Contents:
:vertices = #{ 0.0 -1.5668 -8.6965 2.7351 -12.0802 ... }
:faces = #{ [[-8.6965 3.1084 6.294]] [[6.2429 -12.0802 0.0]] [[-19.2099 -1.0464 2.7351]] [[6.2429 -12.0802 2.7351]] [[2.0882 -1.5668 6.294]] }
:fnormals = {}
The mesh is being generated by having the following sequence of faces passed in, using the form (g/into (bm/basic-mesh) faces), where faces is defined as follows:
( ( [ 2.0882 -1.5668 6.294 ] [ -8.6965 3.1084 6.294 ] [ -19.2099 -1.0464 2.7351 ] [ 6.2429 -12.0802 2.7351 ] )
[ [ 2.0882 -1.5668 6.294 ] [ 2.0882 -1.5668 0.0 ] [ -8.6965 3.1084 0.0 ] [ -8.6965 3.1084 6.294 ] ]
[ [ -8.6965 3.1084 6.294 ] [ -8.6965 3.1084 0.0 ] [ -19.2099 -1.0464 0.0 ] [ -19.2099 -1.0464 2.7351 ] ]
[ [ -19.2099 -1.0464 2.7351 ] [ -19.2099 -1.0464 0.0 ] [ 6.2429 -12.0802 0.0 ] [ 6.2429 -12.0802 2.7351 ] ]
[ [ 6.2429 -12.0802 2.7351 ] [ 6.2429 -12.0802 0.0 ] [ 2.0882 -1.5668 0.0 ] [ 2.0882 -1.5668 6.294 ] ]
( [ 6.2429 -12.0802 0.0 ] [ -19.2099 -1.0464 0.0 ] [ -8.6965 3.1084 0.0 ] [ 2.0882 -1.5668 0.0 ] ) )
Okay, finally tested and found where the problem is. On line 18 of basicmesh.cljc, where you define the parameters for add-face*, you're excessively deconstructing the passed face.
https://github.com/thi-ng/geom/blob/85783a1f87670c5821473298fa0b491bd40c3028/src/thi/ng/geom/basicmesh.cljc#L17-L22
After removing the extra sequence deconstruction around fverts, the problem disappeared.
And of course after fixing that I get a stack overflow.
Hi @seylerius - I'm in the middle of a relocation and will take a while until I can look into this. In the meanwhile, please post a minimal example to reproduce your issue, thanks! 👍