Ritorno in argomento perché mi è venuto lo sfizio, diciamo la necessità, dopo aver creato un rullo, e averlo magari modificato, di riportare tutto su un 3D piano.
Molto più complicato, riportare su un foglio la topografia del cilindro.
Ho litigato un bel po' con l'arcotangente, che in LISP non c'è, imbastendo le formule, poi ho rinunciato, optando per un metodo più rustico che fa lavorare il CAD, in breve facendogli disegnare l'arco di ogni punto sul cilindro, facendomene dire la lunghezza "disteso", e riportando detta misura come valore X di spiazzamento di quel punto rispetto all'origine comune a tutti i punti.
Roba non semplice, soprattutto perché una faccia può starsene sul cilindro a cavallo tra meno di 360 gradi e più di 0 gradi, cosa che mi rende l'arco non di banale sviluppo. Da qui, i controlli; il "pure" che mi dice se una faccia è nel range 0-360 oppure no, se quindi uno o più vertici scavalcano i 360 .
Comunque attenzione, il diametro del cilindro DEVE essere obbligatoriamente 2 (raggio 1), e la sua origine, il centro della base, posta a 0,0,0. Deve essere steso come un tappeto arrotolato, ossia da 0,0,0, l'altezza del cilindro sarà posta secondo un Y positivo.
Questo è proprio perché il risultato sarà come srotolare un tappeto a cilindro sul pavimento, posto lungo l'asse Y, stendendendolo sull'asse X. Come quando lo si è creato.
Anche qui, meglio posizionarsi su un nuovo layer prima di lanciare la routine, perché la nuova forma creata non si intrecci con la prima e risulti facilmente selezionabile.
E' un "timbro", quindi è verificato solo per "incisioni" sul diametro del cilindro, che diventeranno volumi positivi posti sul tappeto. Non ho verificato cosa succeda se "dal" cilindro escano protuberanze, perché non era il mio problema. E' un "timbro continuo" 3D. Ciò che è inciso sul cilindro, risulterà in aggetto sul tappeto srotolato con la sua topografia.
Naturalmente grazie se per caso qualcuno avesse idee con un algoritmo più spiccio!
Codice:
(defun MPRINT()
(setq selez nil)
(setq selez(ssget))
(if (/= selez nil)
(progn
(setq l(sslength selez))
(setq l(1- l))
(setq na 0)
(while(<= na l)
(setq ename(ssname selez na))
(setq alist(entget ename))
(if(= "3DFACE"(cdr(assoc 0 alist)))
(progn
(setq A (cdr(assoc 10 alist)) B (cdr(assoc 11 alist)) C (cdr(assoc 12 alist)) D (cdr(assoc 13 alist)))
(setq Ax (car A) Ay (cadr A) Az (caddr A) )
(setq Bx (car B) By (cadr B) Bz (caddr B) )
(setq Cx (car C) Cy (cadr C) Cz (caddr C) )
(setq Dx (car D) Dy (cadr D) Dz (caddr D) )
(if (or (< Az 0)(< Bz 0)(< Cz 0)(< Dz 0))
(setq sud 1)
(setq sud 0)
)
(setq cross 0)
(if (< Az -0.0001)(setq cross (+ 1 cross)))
(if (< Bz -0.0001)(setq cross (+ 1 cross)))
(if (< Cz -0.0001)(setq cross (+ 1 cross)))
(if (< Dz -0.0001)(setq cross (+ 1 cross)))
(if (or (= cross 4)(= cross 0)) (setq pure 1)(setq pure 0))
;................
(setq newAz (- 1 (sqrt (+ (* Ax Ax) (* Az Az))) ))
(setq pointCent (list 100 0 0) )
(setq pointStart (list 101 0 0) )
(setq pointEnd (list (+ 100 Ax) Az 0) )
(if (and (equal Ax 1 0.0001) (= sud 1))
(setq newAx 6.28318531)
(progn
(command "ARC" "C" PointCent PointStart PointEnd)
(setq selez2 (ssget PointStart))
(setq ename2 (ssname selez2 0))
(setq Nalist (entget ename2))
(setq basArc (cdr(assoc 50 Nalist)))
(setq endArc (cdr(assoc 51 Nalist)))
(setq SvilArc (- endArc basArc))
(entdel ename2)
(setq newAx SvilArc)
)
)
(setq newAy Ay) ;solo per leggibilità
;............
(setq newBz (- 1 (sqrt (+ (* Bx Bx) (* Bz Bz))) ))
(setq pointCent (list 100 0 0) )
(setq pointStart (list 101 0 0) )
(setq pointEnd (list (+ 100 Bx) Bz 0) )
(if (and (equal Bx 1 0.0001) (= sud 1))
(setq newBx 6.28318531)
(progn
(command "ARC" "C" PointCent PointStart PointEnd)
(setq selez2 (ssget PointStart))
(setq ename2 (ssname selez2 0))
(setq Nalist(entget ename2))
(setq basArc (cdr(assoc 50 Nalist)))
(setq endArc (cdr(assoc 51 Nalist)))
(setq SvilArc (- endArc basArc))
(setq newBx SvilArc)
(entdel ename2)
)
)
(setq newBy By) ;solo per leggibilità
;............
(setq newCz (- 1 (sqrt (+ (* Cx Cx) (* Cz Cz))) ))
(setq pointCent (list 100 0 0) )
(setq pointStart (list 101 0 0) )
(setq pointEnd (list (+ 100 Cx) Cz 0) )
(if (and (equal Cx 1 0.0001) (= sud 1))
(setq newCx 6.28318531)
(progn
(command "ARC" "C" PointCent PointStart PointEnd)
(setq selez2 (ssget PointStart))
(setq ename2 (ssname selez2 0))
(setq Nalist (entget ename2))
(setq basArc (cdr(assoc 50 Nalist)))
(setq endArc (cdr(assoc 51 Nalist)))
(setq SvilArc (- endArc basArc))
(setq newCx SvilArc)
(entdel ename2)
)
)
(setq newCy Cy) ;solo per leggibilità
;............
(setq newDz (- 1 (sqrt (+ (* Dx Dx) (* Dz Dz))) ))
(setq pointCent (list 100 0 0) )
(setq pointStart (list 101 0 0) )
(setq pointEnd (list (+ 100 Dx) Dz 0) )
(if (and (equal Dx 1 0.0001) (= sud 1))
(setq newDx 6.28318531)
(progn
(command "ARC" "C" PointCent PointStart PointEnd)
(setq selez2 (ssget PointStart))
(setq ename2 (ssname selez2 0))
(setq Nalist(entget ename2))
(setq basArc (cdr(assoc 50 Nalist)))
(setq endArc (cdr(assoc 51 Nalist)))
(setq SvilArc (- endArc basArc))
(setq newDx SvilArc)
(entdel ename2)
)
)
(setq newDy Dy) ;solo per leggibilità
(setq newA (list newAx newAy newAz) )
(setq newB (list newBx newBy newBz) )
(setq newC (list newCx newCy newCz) )
(setq newD (list newDx newDy newDz) )
(if (= 1 pure)
(command "3DFACE" newA newB newC newD "")
(progn
(if (< Ax 0)
(command "3DFACE" newA newB newC newD "")
(progn
(if (< newAx pi) (setq newAx (+ pi pi newAx)))
(if (< newBx pi) (setq newBx (+ pi pi newBx)))
(if (< newCx pi) (setq newCx (+ pi pi newCx)))
(if (< newDx pi) (setq newDx (+ pi pi newDx)))
(setq newA (list newAx newAy newAz) )
(setq newB (list newBx newBy newBz) )
(setq newC (list newCx newCy newCz) )
(setq newD (list newDx newDy newDz) )
(command "3DFACE" newA newB newC newD "")
)
)
)
) ; close if pure
) ; close progn if 3DFACE
) ;endif 3DFACE
(setq na(1+ na))
) ; close while na
) ; close progn selez
) ; close if selez
) ;close defun