#lang scheme
(require "../../common/main-new.ss")
(provide (all-from-out "../../common/main-new.ss")
(all-from-out "acad-utils.ss")
start-backend
(rename-out [draw-top-level draw])
command
command-join
com-stats
)
(require "../../utils.ss")
(require "acad-utils.ss"
"primitives.ss"
"com-utils.ss")
(require "base.ss")
(require "marshal.ss")
(define command prim:command)
(define (command* . args)
(apply prim:command args)
(entlast))
(define tag list)
(define tagged-object first)
(define tagged-tag second)
(define cache #f)
(define (clean-cache)
(hash-for-each cache
(lambda (key val)
(with-handlers
((exn:fail?
(lambda (_) #t)))
(invoke Delete
val))))
(set! cache #f))
(define make-hash* make-hash)
(define hash-ref* hash-ref)
(define hash-set!* hash-set!)
(define copy-entity* copy-entity)
(define (turn-off-caching)
(let ([f (lambda args #f)])
(set! make-hash* f)
(set! clean-cache f)
(set! hash-ref* f)
(set! copy-entity* (lambda args (first args)))
(set! hash-set!* f)))
(define (draw-new o)
(case* o
[list? => (lambda (o)
(let ([os (map draw-new o)])
(apply command* "._UNION" (append os (list "\r")))
(car os)))]
[arc? => draw-arc]
[line? => draw-line]
[ellipse? => draw-ellipse]
[region? => draw-region]
[spline? => draw-spline]
[3dface? => draw-3dface]
[box? => draw-box]
[e-cone? => draw-e-cone]
[pyramid? => draw-pyramid]
[sphere? => draw-sphere]
[subtraction? => apply-subtraction]
[extrusion? => apply-extrusion]
[intersection? => apply-intersection]
[loft? => apply-loft]
[guided-loft? => apply-guided-loft]
[ruled-loft? => apply-ruled-loft]
[array? => apply-array]
[move? => apply-move]
[revolution? => apply-revolution]
[slice? => apply-slice]
[sweep? => apply-sweep]
[thicken? => apply-thicken]
[union? => apply-union]
[else
(error "Not implemented: "
(vector-ref (struct->vector o) 0))]
))
(define (draw-top-level object)
(set! cache (make-hash*))
(init-layer-stack)
(let ([res (draw object)])
(clean-cache)
(destroy-layer-stack)
res))
(define (draw object)
(let ([obj (hash-ref* cache object #f)])
(if obj
(set! obj (copy-entity* obj))
(begin
(set! obj (draw-new object))
(when (operation? object)
(hash-set!* cache
object
(copy-entity* obj)))))
obj))
(define-syntax define-unimplemented-draw
(lambda (stx)
(syntax-case stx ()
[(_ name)
(with-syntax
([draw-name
(datum->syntax
#'name
(string->symbol
(string-append "draw-"
(symbol->string
(syntax->datum #'name)))))])
#`(define (draw-name . args)
(error "Drawing objects of type " 'name " is not implemented.")))]
[(_ name names ...)
#'(begin
(define-unimplemented-draw name)
(define-unimplemented-draw names ...))])))
(define-unimplemented-draw
array-polar
donut
mesh
parametric
plane
polar
poly
polyface-mesh
polygon
prism
ray
superellipsoid
text
torus
wedge
xline)
(define-syntax define-unimplemented-apply
(lambda (stx)
(syntax-case stx ()
[(_ name)
(with-syntax
([draw-name
(datum->syntax
#'name
(string->symbol
(string-append "apply-"
(symbol->string
(syntax-e #'name)))))])
#`(define (apply-name . args)
(error "Can't apply functions of type " 'name " -- not implemented.")))]
[(_ name names ...)
#'(begin
(define-unimplemented-apply name)
(define-unimplemented-apply names ...))])))
(define-unimplemented-apply
extrusion
intersection
region
revolution
subtraction
union
)
(define (draw-3dface f)
(command* "._3dface" (3dface-p1 f) (3dface-p2 f)
(3dface-p3 f) (3dface-p4 f) ""))
(define (draw-arc a)
(let ([c (arc-c a)]
[r (arc-r a)]
[sa (arc-start-angle a)]
[ea (arc-end-angle a)])
(command* "._ARC" (to-point-2d (+pol c r sa))
(to-point-2d (+pol c r (/ (abs (- ea sa)) 2)))
(to-point-2d (+pol c r ea)))))
(define (draw-box b)
(command* "._BOX" "_C" (box-c b) "_L" (box-l b) (box-w b) (box-h b)))
(define (draw-e-cone c)
(cond [(= (e-cone-r1 c) (e-cone-r2 c))
(if (= (e-cone-r1 c) (e-cone-r1* c))
(command* "._CYLINDER" (e-cone-c1 c) (e-cone-r1 c)
"_A" (e-cone-c2 c))
(command* "._CYLINDER" "_E" "_C"
(e-cone-c1 c) (e-cone-r1 c)
"_T" (e-cone-c2 c)))]
[else
(if (= (e-cone-r1 c) (e-cone-r1* c))
(command* "._CONE" (e-cone-c1 c) (e-cone-r1 c)
"_T" (e-cone-r2 c) "_A" (e-cone-c2 c)) (command* "._CONE" "_E" "_C" (e-cone-c1 c) (e-cone-r1 c)
(e-cone-r1* c)
"_T" (e-cone-r2 c) (e-cone-c2 c)))]))
(define (draw-ellipse e)
(if (= (ellipse-r1 e) (ellipse-r2 e))
(command* "._CIRCLE" (ellipse-c e) (ellipse-r1 e))
(command* "._ELLIPSE" "_C" (ellipse-c e) (ellipse-r1 e) (ellipse-r2 e))))
(define (draw-line l)
(define (pts-list->vector l)
(let* ([len (length l)]
[3*len (* 3 len)]
[v (make-vector 3*len)])
(define (pts-list->vector-aux l i)
(if (eq? l '())
v
(let ([p (first l)])
(vector-set! v i (exact->inexact (cz p)))
(vector-set! v (- i 1) (exact->inexact (cy p)))
(vector-set! v (- i 2) (exact->inexact (cx p)))
(pts-list->vector-aux (rest l) (- i 3)))))
(pts-list->vector-aux l (sub1 3*len))))
(let ([plv (pts-list->vector (line-pts l))])
(invoke Add3Dpoly
(acad-mspace)
plv)))
(define (draw-pyramid p)
(command* "._PYRAMID"
"_S" (pyramid-s p) (pyramid-c1 p) (pyramid-r1 p)
"_T" (pyramid-r2 p) "_A" (pyramid-c2 p)))
(define (draw-region r)
(let ([res
(if (list? (region-l r))
(apply command* "._REGION" (append (map draw (region-l r)) (list "\r")))
(command* "._REGION" (draw (region-l r)) "\r"))])
(command* "._CONVTOSURFACE" res "\r")))
(define (draw-spline s)
(define (pts-list->vector l)
(let* ([len (length l)]
[3*len (* 3 len)]
[v (make-vector 3*len)])
(define (pts-list->vector-aux l i)
(if (eq? l '())
v
(let ([p (first l)])
(vector-set! v i (exact->inexact (cz p)))
(vector-set! v (- i 1) (exact->inexact (cy p)))
(vector-set! v (- i 2) (exact->inexact (cx p)))
(pts-list->vector-aux (rest l) (- i 3)))))
(pts-list->vector-aux l (sub1 3*len))))
(let ([plv (pts-list->vector (spline-pts s))])
(invoke AddSpline
(acad-mspace)
plv
(marshal (spline-start-tg s))
(marshal (spline-end-tg s)))))
(define (draw-sphere s)
(command* "._SPHERE" (sphere-c s) (sphere-r s)))
(define (apply-array a)
(let ([o (draw (array-obj a))])
(command* "._3Darray" o ""
"_R" (array-x a) (array-y a) (array-z a)
(array-dx a) (array-dy a) (array-dz a))))
(define (apply-subtraction d)
(let [(o (draw (subtraction-object d)))]
(apply command* "._SUBTRACT"
o "" (append (map draw (subtraction-objects d))
(list "\r")))
o))
(define (apply-extrusion e)
(if (point? (extrusion-path e))
(command* "._EXTRUDE" (draw (extrusion-surf e)) "\r"
"_D" (extrusion-path e) (extrusion-taper-angle e)) (command* "._EXTRUDE" (draw (extrusion-surf e)) "\r"
"_T" (graus<-radianos (extrusion-taper-angle e)) "_P" (draw (extrusion-path e)))))
(define (apply-intersection i)
(let [(os (map draw (intersection-objects i)))]
(apply command* "._INTERSECT"
(append os (list "\r")))
(car os)))
(define (apply-layer l)
(let ([obj '()])
(with-layer
(layer-name l)
(set! obj (draw (layer-obj l))))
obj))
(define (apply-loft l)
(command "._LOFTNORMALS" 6)
(command "._LOFTMAG1" (loft-m1 l))
(command "._LOFTANG1" (graus<-radianos (loft-a1 l)))
(command "._LOFTMAG2" (loft-m2 l))
(command "._LOFTANG2" (graus<-radianos (loft-a2 l)))
(let ([cmd-str (command-join " "
(map marshal->string*
(list* "._LOFT"
(append (map draw (loft-objects l))
(list "" "")))))])
(command* (string-append "(command " cmd-str ")"))))
(define (apply-guided-loft l)
(command "._LOFTNORMALS" 6)
(apply command* "._LOFT"
(append (map draw (guided-loft-objects l))
(list "\r")
(if (and (list? (guided-loft-guides l))
(not (null? (guided-loft-guides l)))
(zero? (length (guided-loft-guides l))))
(list "_P" (draw (guided-loft-path l)))
(list* "_G" (append (map draw (guided-loft-guides l)) (list "\r")))))))
(define (apply-ruled-loft l)
(command "._LOFTNORMALS" 0)
(let* ([objs (map draw (ruled-loft-objects l))]
[cmd-str (command-join " "
(map marshal->string*
(list* "._LOFT"
(append objs
(list "\r" "_C")))))])
(command* (string-append "(command " cmd-str ")"))))
(define (apply-move m)
(display "moving...")(newline)
(command* "._move" (draw (move-obj m)) ""
"_D" (marshal->string (move-v m))))
(define (apply-revolution r)
(command* "._REVOLVE" (draw (revolution-surf r)) "\r"
(axis-p (revolution-axis r)) (p+v (axis-p (revolution-axis r)) (axis-v (revolution-axis r))) "_ST" (graus<-radianos (revolution-start-angle r)) (graus<-radianos (revolution-end-angle r))))
(define (apply-slice s)
(let [(o (draw (slice-obj s)))]
(command* "._SLICE" o "\r" "_Zaxis"
(plane-p (slice-plane s))
(p+v (plane-p (slice-plane s)) (plane-n (slice-plane s)))
(p+v (plane-p (slice-plane s)) (v*r (plane-n (slice-plane s)) -1)))))
(define (apply-sweep s)
(command* "._SWEEP" (draw (sweep-surf s)) "\r"
"_T" (graus<-radianos (sweep-twist s)) "_S" (sweep-scale s) (draw (sweep-path s))))
(define (apply-thicken t)
(let ([obj (draw (thicken-surf t))])
(command* "._THICKEN" obj "\r" (thicken-w t))))
(define (apply-union u)
(let [(os (map draw (union-objects u)))]
(apply command* "._UNION" (append os (list "\r")))
(car os)))
(define top-level-print-hook-initialized #f)
(register-top-level-print-hook
'autocad
(lambda (obj)
(when (not top-level-print-hook-initialized)
(set! top-level-print-hook-initialized #t)
(erase-all))
(if (or (primitive? obj) (operation? obj))
(draw obj)
((current-print) obj))))
(set-top-level-print-mode 'autocad)