31 agosto 2019

Le funzioni LISP (nascoste) di ZWcad

Una serie di funzioni LISP non documentate per chi sviluppa programmi in ZWcad ...

I cloni di AutoCAD oltre che a fornire lo stesso set di comandi del CAD di Autodesk offrono anche lo stesso set di funzioni base del linguaggio LISP, per lo sviluppo di programmi interni.

La presenza di queste funzioni garantisce il funzionamento dei numerosi programmi scritti in linguaggio AutoLISP e disponibili in rete.

Con il succedersi delle versioni i CAD compatibili hanno cominciato a rendere disponibili anche funzioni aggiuntive LISP o per un loro uso interno o per metterle a disposizione dell’utente più avanzato che desidera sviluppare i propri programmi.

Cosa offre il LISP di ZWCAD

Esplorando la memoria del programma ho scoperto la presenza di numerose funzioni aggiuntive non documentate.

Per alcune è stato facile intuire la sintassi di utilizzo, per altre non ci sono riuscito. È probabile comunque che alcune, soprattutto quelle per trattare le stringhe, siano state implementate per supportare stringhe contenenti caratteri dell'alfabeto cinese con ideogrammi.

Ho contattato il supporto tecnico di ZWcad ed ho chiesto se fosse disponibile una documentazione e come mai queste funzioni non fossero state documentate nel file di help.
Mi hanno risposto che le funzioni sono per uso interno e consigliato di "... non usarle se non fosse strettamente necessario"... Niente di più stimolante allora che cercare di capire cosa fanno e come funzionano pur essendo consci che, probabilmente, alcune funzioni non sono ancora stabili.

Scopriamo dunque cosa cela il LISP di ZWcad 2020.

Funzioni DOSlib di McNeel

Presenti sin dai primi anni '90 una serie di funzioni per AutoLISP sono state create ed implementate nel corso degli anni dalla software house Robert McNeel and Associates (quelli che producono  Rhinoceros).
Le funzioni sono state sempre disponibili come freeware raccolte in un file di libreria chiamata DOSLIB (in formato ADS prima e ARX e BRX poi) da caricare in AutoCAD o BricsCAD.

Dal maggio 2018 la libreria di funzioni è diventata open-source ed è disponibile su GitHub .

ZWsoft ha quindi avuto la possibilità di inglobarle in ZWcad mettendo così a disposizione del programmatore numerosissime funzioni è garantendo la portabilità dei programmi LISP che fanno uso delle funzioni presenti in questa libreria.

Sono pertanto disponibili un centinaio di funzioni, riconoscibili dal prefisso "DOS_" .
Per ottenere l'elenco completo digitate:
(dos_help)
parte dell'output della funzione DOS_HELP che elenca le funzioni disponibili

Le funzioni operano sui dischi, sulle info del sistema operativo, sui files, sulle cartelle, sulla stampa, su funzioni trigonometriche. Solo per fare qualche esempio:
(dos_encrypt filename password) critta un file con una password.
(dos_move source destination) sposta un file in una nuova posizione.
(dos_show method) minimizza o massimizza la finestra di ZWcad.
(dos_capslock [T]) attiva o disattiva le maiuscole sulla tastiera.
(dos_sysdir) restituisce il nome della cartella di sistema di Windows.

Il file di help relativo alle funzioni è disponibile nel file zip che la contiene sul sito di MeNeel.

Funzioni Express Tools

Così come in AutoCAD, quando sono presenti gli Express Tools (una serie di comandi aggiuntivi) sono anche disponibili una serie di funzioni lisp che sono utilizzate dentro suddetti comandi.
Le funzioni sono a disposizione dell’utente per creare propri programmi personalizzati e sono molti i programmatori che ne fanno uso.

Le funzioni si riescono ad identificare grazie al prefisso "ACET_ " (per esempio ACET-STR-REPLACE, ACET-UI-PROGRESS, ACET-LAYERP-MODE ecc).

È possibile scaricare il file di help dal questo link: acetutil.zip , risale al 2000 ma offre descrizioni complete su tante funzioni.


Funzioni per operare sui File

FNSPLIT questa funzione è presente anche in AutoCAD a anche lì non è documentata.
Dato un nome di file restituisce una lista con all’interno gli oggetti logici : drive, cartella, nome file estensione.
(FNSPLITL "c:\\disegno.dwg") ->("c:\\" "disegno" ".dwg")

La funzione GETZWCADSUPPORTPATH restituisce il percorso nel quale si trova ala cartella dei file di supporto
(getzwcadsupportpath) -> "C:\\Users\\Utente\\AppData\\Roaming\\ZWSOFT\\ZWCAD\\2020\\it-IT\\"

Funzioni per le Liste

ACONS restituisce una lista che combina i primi 2 argomenti in una coppia puntata inserita nella lista fornita come del terzo argomento
(ACONS 1 4 '(22)) --> ((1 . 4) 22)

CONSP restituisce T se l'argomento è una coppia puntata o una lista.
(consp '(1 2) )  -> T
(consp '(1 . 2) ) -> T
lo stesso fa LISTP

FIRST restituisce il primo elemento di una lista, equivale a un CAR ma è molto più intuitivo
(FIRST '(R A Y)) -> R

SECOND restituisce il secondo elemento della lista e, in maniera analoga, funzionano le funzioni  THIRD FOURTH
(SECOND '(R A Y)) -> A

RPLACA sostituisce il primo valore di una coppia puntata con il secondo argomento fornito.
(RPLACA  '(10 . 2) 54) -> (54 . 2)

RPLACD   sostituisce il secondo valore di una coppia puntata con il secondo argomento fornito.
(RPLACD  '(10 . 2) 54) -> (10 . 54)

REST esclude il primo elemento della lista o coppia puntata fornito come argomento
(rest '(1 . 2)) -> 2
(rest '(1 2 3)) -> (2 3)

Funzioni matematiche

MOD restituisce 1 se la divisione tra i suoi argomenti restituisce un numero intero altrimenti restituisce 0.
(MOD 105 2) -> 1
(MOD 104 2) -> 0

EVENP restituisce T se il suo argomento numerico è pari altrimenti restituisce nil
(EVENP 4) -> T
(EVENP 5) -> nil

ODDP è la funzione inversa, verifica se il numero è dispari
(ODDP 4) -> nil
(ODDP 3) -> T

PLUSP restituisce T se il numero è positivo, altrimenti restituisce nil
(plusp 5)  -> T
(plusp -5) -> nil

INTEGERP verifica che l'argomentio sia un numero intero
(integerp 8) -> T
(integerp 8.55) -> nil


Funzioni trigonometriche

ACOS  restituisce la funzione inversa del coseno di un angolo
(acos 0) -> 1.5708

TAN restituisce il valore dela tangente di un angolo
(TAN 0) -> 0.0

Funzioni per la gestione delle Stringhe

NSTRING-DOWNCASE restituisce la stringa con caratteri minuscoli
(NSTRING-DOWNCASE "E") -> "e"
mentre NSTRING-UPCASE fa il contrario.

STRING-NOT-GREATERP confronta 2 stringhe , restituisce 1 se iniziano con lo stesso carattere,
(STRING-NOT-GREATERP "4" "44") -> 1
nil se la prima inizia con un carattere successivo al primo carattere della seconda stringa
(STRING-NOT-GREATERP "5" "44") -> nil
0 se il primo carattere della prima stringa è precedente al primo carattere della seconda stringa
(STRING-NOT-GREATERP "3" "44") -> 0 

STRING/= confronta due stringhe per verificarne l'uguaglianza
(STRING/= "a" "b") -> 0
(STRING/= "a" "a") -> nil

STRING<= confronta due stringhe, restituisce 0 se la prima stringa e precedente alla seconda, nil in caso contrario
(STRING<= "a" "b") -> 0
(STRING<= "c" "b") -> nil

STRINGP restituisce T se l'argomento è una stringa
(stringp 2) -> nil
(stringp "3ee") -> T

SUBSEQ assomiglia alla funzione Substr ma il primo argomento indica la posizione precedente da cui partire per estrarre la sotto stringa,
(subseq "qwerty" 2 4) -> "er" con Substr (substr "qwerty" 2 4) ->
"wert"
(subseq "qwerty" 4) -> "ty" con Substr (substr "qwerty" 4) -> "rty"

Varie

ZRX in maniera analoga ad ARX elenca i moduli ZRX caricati nel programma
(zrx) -> ("zwmanaged.dll" "zwlisp.zrx" "lspapputils.zrx" "zrxopm.zrx" "zrxupdate.zrx" "zwextend.zrx" "zwmousegesturecmd.zrx" "zrxtoolpalette.zrx")

VLA-GET-ENTITYTYPE dato un objname restituisce un numero in base a tipo di oggetto
19 per la linea, 4 per l'arco, 24 per la polilinea ecc..

VLA-GET-ENTITYNAME dato un objname restituisce la classe dell'oggetto nella catalogazione degli oggetti CAD.
 (VLA-GET-ENTITYNAME  (vlax-ename->vla-object (entlast))) -> "AcDbArc"

GET-LICENSE-SERIAL restituisce una lista con 3 valori.
Il primo valore , da 0 a 3, indica 
- 1 = ha una licenza sw
- 2 = ha una chiave hardware
- 3 = è in versione Trial 30 giorni
- 0 = versione Trial scaduta.
Il secondo valore è il numero di licenza crittato. 
Il terzo valore indica in che maniera è stato attivato:
1 licenza di rete
2 licenza stand-alone.
(GET-LICENSE-SERIAL) -> (0 "" 0) in questo caso l'ho provato su una versione trial altrimenti avremmo ottenuto un qualcosa del genere: (1 "1C43536A32" 1)

SELECTSIMILAR-DCL indica il percorso del file .dcl temporaneo che viene utilizzato dal comando Selctsimilar.
(SELECTSIMILAR-DCL) -> "C:\\Users\\Utente\\AppData\\Local\\Temp\\DclTemp001.dcl"

COMPILE-ZELX compila un file in formato .lsp in formato .zelx
(compile-zelx "C:\\LSP\\PLACA.lsp" "C:\\LSP\\PLACA.zelx")

COMPILE-LISP compila un file in formato .lsp in formato .zel
(compile-lisp "C:\\LSP\\PLACA.lsp" "C:\\LSP\\PLACA.zel")

Sconosciute

Molte sono le funzioni sconosciute. I nomi fanno immaginare a cosa possano servire ma non sono riuscito a trovare la giusta sintassi (per ora...) .
Ne elenco alcune:

FOR-EACH funziona come foreach ma probabilmente ha qualche feature in più
ZLSP-PUT-PROPERTY esiste anche il GET
VLA-NEWDRAWING crea unnuovo disegno ?
VLA-PUT-HORIZONTALALIGNMENT  sarebbe molto interessante se forzasse il tracking per un punto.
-1+
ARRAYP
FLOAP

Le successive sembrano essere legate ad un oggetto CHAR
CHAR-GREATERP
ALPHANUMERICP
CHAR-CODE
CHAR<=
BOTH-CASE-P
e molte molte altre.

Se qualcuno conoscesse la sintassi di qualche funzione non esiti a scrivere nei commenti in calce a questo articolo o a contattarmi per aggiornare l'articolo.

4 commenti:

  1. compile.lisp... non funziona un tubo

    RispondiElimina
    Risposte
    1. probabilmente ci vuole "\\" al posto di "\" per sepecificare le cartelle

      Elimina
  2. in compenso funziona il semplice "compile"

    RispondiElimina
    Risposte
    1. Si, il comando COMPILA da linea di comando è più comodo

      Elimina