#lang scheme
(require "../utils.ss")
(require "primitives-new.ss"
"point.ss"
"vector.ss")
(provide (except-out (struct-out operation) make-operation))
(define-struct operation
()
#:transparent)
(define-syntax define-operation
(syntax-rules ()
[(_ name slot ...)
(begin
(provide (struct-out name))
(define-struct (name operation)
(slot ...)
#:transparent))]))
(define-operation null-operation obj)
(define-syntax define-operations
(syntax-rules ()
[(_ operation ...)
(begin (define-operation . operation) ...)]))
(define-operations
(array obj x y z dx dy dz)
(array-polar obj c pt n angle)
(subtraction object objects)
(intersection objects)
(union objects)
(extrusion surf path taper-angle)
(loft objects a1 m1 a2 m2)
(guided-loft objects guides path)
(ruled-loft objects)
(revolution surf axis start-angle end-angle)
(sweep surf path twist scale)
(mirror obj plane) (move obj v)
(offset curve dist)
(rotate obj pt axis-vector angle) (scale obj pt v)
(slice obj plane)
(thicken surf w)
(transform object matrix) (edges obj)
)
(provide unite intersect subtract)
(define (unite . args*)
(if (list? (first args*))
(apply unite (first args*))
(let [(args (remove empty-region args* eq?))]
(cond [(memv universal-region args) universal-region]
[(null? args) empty-region]
[(= 1 (length args))
(car args)]
[(union? (car args))
(make-union (append (cdr args)
(union-objects (car args))))]
[else (make-union args)]))))
(define (intersect . args*)
(let [(args (remove universal-region args* eq?))]
(cond [(memv empty-region args) empty-region]
[(null? args) empty-region]
[(= 1 (length args))
(car args)]
[(intersection? (car args))
(make-intersection (append (cdr args)
(intersection-objects (car args))))]
[else (make-intersection args)])))
(define (subtract o os*)
(let [(os (if (list? os*) (remove empty-region os* eq?) os*))]
(make-subtraction o (ensure-list os))))