Disegno Automatico 1999-2000
Camillo Trevisan

Esempio di modellazione solida

L'oggetto
L'esercizio  consiste nel costruire il modello solido di una scala a chiocciola e di una rampa.

 

La scala a chiocciola

Questo è un tipico problema ricorsivo: infatti, ciascun gradino della scala può essere costruito a partire dal precedente operando una copia del gradino, ruotando la copia di N gradi (l'apertura angolare del gradino) e traslandolo verso l'alto di M unità (l'altezza del gradino).
Per ottenere il risultato voluto con il minimo dispendio di tempo è utile costruire uno 'script di comandi'. 

SCRIPT DI COMANDI

Un "file script" è un file in formato ASCII che contiene una serie strutturata di comandi e relative opzioni. Quando è necessario eseguire operazioni ripetitive questa opportunità consente di abbattere i tempi di creazione di entità o di editing.

Accade spesso di dover ripetere decine o centinaia di volte la stessa operazione di editing o creazione di entità. Ad esempio la copia multipla di un oggetto grafico in corrispondenza di punti dati o il cambio di alcune caratteristiche di entità che non possa essere fatto "all'ingrosso".
AutoCAD è in grado di leggere ed eseguire comandi scritti in un file ASCII e dunque di semplice creazione. Tutto ciò che può essere immesso da tastiera può anche essere trascritto su file, avente un qualsiasi nome base e suffisso .SCR.
Il file viene richiamato mediante il comando SCRIPT che apre un apposito dialog-box. Da quel momento AutoCAD legge i comandi e le relative opzioni e, se non incontra errori, esegue le operazioni indicate.

Un file script non è paragonabile ad un programma, nel senso che non è in grado di prendere decisioni o di proporre alternative: esegue semplicemente una lista di comandi predefiniti in tutto e per tutto.
I file possono però essere scritti da un apposito programma che proponga all'utente le richieste e le traduca in script diversi, secondo le risposte date. In questo caso è però necessario conoscere un linguaggio di programmazione, come ad esempio il C, il Pascal o il Basic.

Gli usi più comuni dei file script sono:
- visualizzazione di serie di viste o file-diapositiva;
- creazione di file-diapositive o di viste del modello;
- stampa su carta o su file di viste del modello;
- impostazione di valori a variabili di sistema;
- creazione di nuovi layer con assegnazione di nomi, colori e tipi di linea;
- creazione di entità (generalmente questi file script sono prodotti da programmi).

Per la corretta costruzione di file di script è necessario tenere presente che:
- gli 'a capo' nel file script corrispondono ad un INVIO dato in AutoCAD;
- è possibile aggiungere commenti nel file script purché la riga inizi con un punto e virgola (;);
- volendo sopprimere tutti i messaggi "Sei sicuro?" dati da alcuni comandi AutoCAD è necessario mettere nella prima riga del file script l'indicazione: expert 5 che assegna valore 5 alla variabile di sistema EXPERT;
- assegnando valore 0 alla variabile di sistema FILEDIA (filedia 0) vengono eliminati i dialog-box relativi alla scelta dei file;
- volendo selezionare alcune entità è possibile usare l'opzione F [W] o I [C] e far seguire due coppie di valori che indicano le coordinate dei due vertici della finestra;
- per annullare tutte le operazioni eseguite dal file script è sufficiente digitare il comando A [U], poiché tutto viene visto come un unico comando;
- per interrompere un file script è necessario digitare CTRL+C o il tasto di cancellazione backspace;
- volendo ripetere continuamente l'intera sequenza è sufficiente mettere alla fine del file script il comando RIPRENDE [RSCRIPT];
- volendo fermare l'esecuzione dello script è necessario immettere il comando PAUSA [DELAY] seguito da un numero intero che rappresenta, in millisecondi, il tempo di pausa: ad esempio pausa 5000 ferma l'esecuzione per 5 secondi (valori da 0 a 32767, vale a dire tra 0 e 32 secondi e 7.7 decimi).

Esempio:
_copy     (comando COPIA, con trattino basso e nome comando in inglese, per poterlo usare sia nella versione italiana sia inglese) 
p            (p sta per precedente o previous, nella versione inglese: è dunque necessario, prima di avviare lo script, creare un gruppo di selezione)
              (linea nulla, per chiudere la selezione)
0,0         (dal punto base 0,0...)
0,0         (allo stesso punto 0,0: dunque, si copia l'oggetto su sé stesso)
_rotate   (ruota l'oggetto ...)
p

0,0         (punto base 0,0)
30          (angolo di 30°: l'ampiezza angolare del gradino)
_move
p

0,0,0      (punto base 0,0)
0,0,20    (spostamento di 20 unità lungo l'asse Z: l'altezza del gradino)

Questi comandi si dovranno copiare, nel file di script, il numero desiderato di volte.
Si salverà il file con suffisso SCR: ad esempio, GRADINO.SCR

Dopo aver selezionato il gradino ed eseguito lo script GRADINO.SCR, il risultato sarà:

Nota importante: è necessario disattivare tutti gli SNAP (comando OSNAP). In caso contrario il programma potrà assumere altri punti di riferimento, non preventivabili né opportuni.
Questa precauzione è da adottare anche nell'uso di programmi in AutoLISP (vedi oltre). 
In ogni caso, se i risultati di uno script o di un programma AutoLISP non corrispondono alle attese, la mancata disattivazione di tutti gli SNAP è, di norma, il motivo dell'errore.

 

La rampa elicoidale

E' questo un caso più complesso del precedente. La complessità risiede anzitutto nella corretta costruzione di un segmento di rampa che possa poi essere trattato seguendo le indicazioni viste in precedenza.
Torna utile, per iniziare, definire l'ambito di percorrenza della rampa: l'elica che individua il bordo esterno e l'interno. 
Per costruire l'elica in modo semplice (mediante una polilinea 3D) è utile adottare un opportuno programma scritto in AutoLISP (per caricarlo in memoria, usare il comando APPLOAD):

Questa funzione ristabilisce le variabili CMDECHO e BLIPMODE in caso di errore
(defun myerror (s) 
(if (/= s "Function cancelled")
(princ (strcat "\nError: " s))
)
(setvar "cmdecho" ocmd) 
(setvar "blipmode" oblp)
(setvar "osmode" oosm)
(setq *error* olderr) 
(princ)
)

Questa funzione costruisce l'elica
(defun celica3d (ntimes bpoint raggio chih lppass / ang dist tp ainc dinc dhih distz circle) 
(setvar "blipmode" 0) pone a 0 la variabile BLIPMODE (per evitare di visualizzare le croci di riscontro poste in corrispondenza dei punti della polilinea 3D che si creerà)
(setvar "cmdecho" 0) pone a 0 la variabile CMDECHO (per evitare di visualizzare la richiesta di immissione dei punti da parte del comando _3dpoly)
(setvar "osmode" 0) pone a 0 la variabile OSMODE (disattiva, durante il funzionamento del programma, gli SNAP ad oggetto)
(setq circle (* 3.141596235 2)) la variabile circle è posta pari a 2*PI greco (un intero angolo giro)
(setq ainc (/ circle lppass)) la variabile ainc è posta pari a 2*Pi greco/numero di punti per passo: vale a dire l'angolo, in radianti, per ciascun segmento di elica
(setq dhih (/ chih lppass)) la variabile dhih è posta pari a: altezza passo/numero di punti per passo: vale a dire dhih = altezza di ciascun segmento di elica o differenza in altezza tra due punti contigui della polilinea 3d
(setq ang (- 0.0 ainc)) la variabile ang è inizializzata a -ainc (in modo che il primo valore sia 0.0 = inizio sull'asse X, di norma)
(setq distz (- 0.0 dhih)) la variabile distz è inizializzata a -dihi (in modo che il primo valore sia 0.0 = inizio con Z = 0.0)
(command "_3dpoly") esegue il comando AutoCAD _3dpoly, il quale richiede l'immissione di un numero non prestabilito di punti nella forma X,Y,Z
(repeat ntimes ripete le operazioni successive per ntimes (ntimes = numero di passi)
(repeat lppass ripete le operazioni successive per lpass (lpass = numero di punti per passo)
(setq distz (+ distz dhih)) assegna alla variabile distz (inizialmente posta a -dhih) il valore distz+dhih. La prima volta che il programma eseguirà questa linea di codice (che verrà ripetuta ntimes*lppass volte) la variabile distz varrà 0.0, la seconda dhih, la terza dhih*2 e così via. Questa variabile contiene pertanto l'altezza dell'ennesimo punto della polilinea
(setq tp (polar bpoint (setq ang (+ ang ainc)) raggio)) la funzione polar (funzione nativa di AutoLISP) restituisce le coordinate di un punto a partire da un punto base (bpoint, centro dell'elica), un angolo (ang) ed una distanza (raggio = costante). L'angolo, a sua volta, è incrementato via via di un valore costante (ainc, calcolato precedentemente)
(setq tp (list (car tp) (cadr tp) distz)) definisce una stringa di caratteri che contiene le coordinate X,Y,Z dell'ennesimo punto della polilinea 3D
(command tp) passa la stringa al comando _3dpoly: costruisce l'ennesimo segmento dell'elica
) chiude il ciclo repeat lppass
) chiude il ciclo repeat ntimes
(command "") chiude il comando _3dpoly con un input nullo (equivalente ad un RETURN o INVIO)
(princ) esce dalla funzione


Questa funzione gestisce l'inserimento dei parametri di costruzione dell'elica: il centro, il raggio, il numero di rotazioni, l'elevazione per ciascuna rotazione, il numero di punti per ciascuna rotazione
(defun C:ELICA3D (/ olderr ocmd oblp oosm nt bp bp1 ch lp) la funzione verrà richiamata dal comando ELICA3D
(setq olderr *error* *error* myerror) assegna alla variabile olderr il valore attuale di *error* (variabile nativa di AutoLISP che gestisce il comportamento del programma in caso di errore) ed assegna a quest'ultima la funzione descritta in testa
(setq ocmd (getvar "cmdecho")) ottiene da AutoCAD il valore della variabile CMDECHO e lo memorizza in ocmd
(setq oblp (getvar "blipmode")) ottiene da AutoCAD il valore della variabile BLIPMODE e lo memorizza in oblp
(setq oosm (getvar "osmode")) ottiene da AutoCAD il valore della variabile OSMODE e lo memorizza in oosm
(setvar "cmdecho" 0) imposta il valore di CMDECHO pari a 0
(initget 1) ; bp must not be null inizializza l'input del punto centrale dell'elica (1 = valore non nullo [non è ammessa, ad esempio, una stringa di caratteri o solo valore reale, ma viene richiesta l'immissione di un punto: ad esempio 0,0 o 1,2 o anche 3,1.3,4.650 e così via])
(setq bp (getpoint "\nPunto centrale: ")) richiede l'immissione del centro dell'elica (punto)
(initget 3) ; bp1 must not be zero or null inizializza l'input del raggio (3 = valore non nullo e diverso da zero)   
(setq bp1 (getdist "\nRaggio: ")) richiede l'immissione del raggio dell'elica (distanza)
(initget 7) ; nt must not be zero, neg, or null inizializza l'input del numero di passi (7 = valore non nullo, diverso da zero e non negativo) 
(setq nt (getint "\nNumero di passi: ")) richiede l'immissione del numero di passi (valore intero)
(initget 3) ; cf must not be zero, or null inizializza l'input dell'altezza del passo (3 = valore non nullo e diverso da zero)
(setq ch (getdist "\nAltezza per passo: ")) richiede l'immissione dell'altezza del passo (valore reale)
(initget 6) ; lp must not be zero or neg inizializza l'input del numero di punti per passo (6 = diverso da zero e positivo: se nullo viene assunto il valore di default, 30 punti)
(setq lp (getint "\nPunti per ogni rotazione <30>: ")) richiede l'immissione del numero di punti per passo (valore intero)
(cond ((null lp) (setq lp 30))) condizione di input nullo (usa il valore di default = 30)
(celica3d nt bp bp1 ch lp) richiama la funzione di costruzione dell'elica
(setvar "cmdecho" ocmd) ristabilisce il precedente valore della variabile CMDECHO
(setvar "blipmode" oblp) ristabilisce il precedente valore della variabile BLIPMODE
(setvar "osmode" oosm) ristabilisce il precedente valore della variabile OSMODE
(setq *error* olderr) ; Restore old *error* handler ristabilisce l'error handle precedente: ritorna nelle stesse condizioni originarie
(princ) esce dalla funzione
)

Per caricare il programma in AutoLISP, utile per AutoCAD 14 e 2000...

Esempio di costruzione di due eliche concentriche. Valori usati: coordinate centro 0,0; raggi 2 e 3 metri; 2 passi; altezza per passo 7.2 metri; 36 punti per passo.

Individuazione dei collegamenti tra i punti che definiscono le polilinee 3D.

 

Il primo tentativo di costruzione della rampa riguarda la definizione di una sezione verticale della rampa stessa e la sua estrusione lungo una delle due eliche.

Tuttavia, come si può notare, l'estrusione non risponde alle richieste, poiché la sezione, durante l'estrusione lungo la traiettoria elicoidale, ruota attorno alla traiettoria stessa.

Anche ponendo la sezione centrata sulla traiettoria non si ottengono risultati accettabili.

E' pertanto necessario operare per altre vie.
Poiché le varie superfici che definiscono i segmenti dell'elica non sono piane, non è possibile estrudere la pianta di ciascun segmento e tagliare il solido con un piano passante per i quattro vertici del segmento: il piano, infatti passerà solo per tre dei quattro punti.

 

E' utile dunque definire un ulteriore piano di taglio, passante per il quarto punto e per due punti ad esso adiacenti.

Tuttavia, naturalmente, in questo caso si forma uno spigolo diagonale.