Scrivere una stringa di testo con dimensione caratteri variabile

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#1
Salve a tutti,
cerco la soluzione con la quale scrivere, mediante autolisp, una stringa di testo ad altezza variabile.
Più precisamente il testo dovrebbe essere così strutturato :
- primi n caratteri con altezza 20
- i seguenti con altezza 5
il tutto in una stringa.
Qualcuno ha un'idea?
Grazie.
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
#2
Entriamo nel mondo degli MTEXT, dove le formattazioni possono spingere al suicidio.
Un esempio terra-terra potrebbe essere questo:

Codice:
(entmake
    (list
        (cons 0 "MTEXT")
        (cons 8 "PIPPO")
        (cons 100 "AcDbEntity")
        (cons 100 "AcDbMText")
        (cons 10 '(5.0 10.0))
        (cons 40 20.0)
        (cons 7 "ARIAL")
        (cons 1 "TESTO ALTO 20 {\\H0.25x;TESTO ALTO CINQUE}")	
    )
)
che crea un MTEXT
nel punto (5,10)
sul layer "PIPPO"
con font = "ARIAL"
con altezza iniziale = 20
con altezza finale = 20x0.25 = 5
 

rpor66

Utente Standard
Professione: Programmatore
Software: AutoCad, GstarCAD, CadWorx, Excel, Lisp, VBA
Regione: Sicilia
#3
Oppure alla fimminina.....

comando T2H, per ora è settato che dal 4° carattere imposta altezza diversa, edita il file e adattalo alle tue esigenze.
 

Allegati

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#5
Grazie per la risposta, sto cercando di capire come intervenire nel programma che cerco faticosamente di scrivere (come avrai capito sono un neofita e cerco di attingere dall'esperienza di chi ne sa più di me!).
Questo è lo stralcio del file dxf che il mio programma genera :
CIRCLE
8
cerchietti ' layer
62
1
10
1498789.579000 ' coordinata est cerchio
20
5042431.954000 ' coordinata nord cerchio
40
0.50
0
TEXT
5
0
8
testo ' testo
62
1
10
1498790.079000 ' coordinata est testo
20
5042432.454000 ' coordinata nord testo
40
40
0.40
50
0
1
p1 (165.03) - 4420571.480,698896.546,4529362.926 ' stringa de testo scritta
0
Chiaramente la stringa dovrà essere formattata in modo che la stessa risulti poi con altezza variabile (prima del trattino grande (0.40) dal trattino in poi piccolo (0.05).
Grazie
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#6
Salve a tutti,
in base alle indicazioni degli amici che mi hanno risposto, ho scritto questo codice :
Codice:
    (defun C:CambiaAltezza (/)

    (setq string nil)
    (while
        (= string nil)
        (setq string (entsel "\nSeleziona il nome del Punto: "))
    )

    (setq string (entget (car string)))
    (setq txt1 (cdr (assoc 1 string)))
    (princ txt1)

    (setq testo1 (substr txt1 1 3)) ; i primi 3 caratteri
    (setq testo2 (substr txt1 4))   ; dal 4 in poi
    ;(command "_mtext" pause "_j" "_bl" "_w" 50 (strcat testo1 "{\\H0.2x;" testo2 "}") "")
    )
il risultato è una stringa con due altezze del testo posizionata in un punto individuato dal comando _mtetxt

Io vorrei però che anziché chiedere il punto di inserimento del nuovo testo, il programmino aggiornasse direttamente la stringa selezionata in partenza (string).
Grazie.
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#7
come posso applicare le tue istruzioni a :
Codice:
(setq string "aaaaabbbbb")
...... istruzioni
(setq risultato "aaaaa" con altezza 20 e "bbbbb" con altezza 5)
Grazie.
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
#8
....Io vorrei però che anziché chiedere il punto di inserimento del nuovo testo, il programmino aggiornasse direttamente la stringa selezionata in partenza (string).
Grazie.
Solo gli mtext possono visualizzare altezze di testo diverse, se la stringa che vuoi modificare appartiene ad un mtext è possibile aggiornarlo, altrimenti no.
Dacci qualche informazione, non ho ancora capito da cosa parti.
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#9
Ho scritto questo codice che funziona benissino :
Codice:
    (defun C:CambiaAltezza (/)

    (setq string nil)
    (while
        (= string nil)
        (setq string (entsel "\nSeleziona il nome del Punto: "))
        (setq elemento (car string))
    )

    (setq string (entget (car string)))
    (setq txt1 (cdr (assoc 1 string))) 

    (setq cxy (assoc 10 string))
    (setq cox (cadr cxy))
    (setq coy (caddr cxy))
    (princ " - ")
    (princ cox)
    (princ ",")
    (princ coy)
    (princ " - ")
    (command "_erase" elemento "")
    (setq coox (rtos cox))
    (setq cooy (rtos coy))
    (setq indirizzo (strcat coox "," cooy))

    (setq testo1 (substr txt1 1 3)) ; i primi 3 caratteri
    (setq testo2 (substr txt1 4))   ; dal 4 in poi
    ;(command "_mtext" "50,50" "_j" "_bl" "_w" 50 (strcat testo1 "{\\H0.2x;" testo2 "}") "")
    (command "_mtext" indirizzo "_j" "_bl" "_w" 50 (strcat testo1 "{\\H0.2x;" testo2 "}") "")
    )
Come puoi vedere, il programmino cambia il testo selezionato in uno modificato con altezza variabile (secondo i parametri impostati).
Se è possibile ottimizzarlo, sono graditi consigli.
Ora vorrei, con implementazione del codice, scrivere la routine che, esaminando tutte le stringhe contenute nel > .dwg < ed intercettate tramite un codice (ad esempio > "**" + numero dell'elemento < contenuto nella singola stringa, cambiare ogni stringa intercettata.
Due problemi :
1 - il numero delle stringhe presenti (nel > .dwg < esistono solo stringhe e cerchietti scritti leggendo il file > .dxf < generato da basic).
2 - ricerca di ogni stringa in modo ciclico con un opportuno comando.
Grazie.
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
#10
Codice:
[B](setq TTT (ssget "_X" '((0 . "TEXT,MTEXT")(1 . "A*,B*"))))[/B] [COLOR="#FF0000"]cattura tutti i TEXT ed MTEXT che iniziano con "A" o "B"[/COLOR]

[B](repeat (setq n (sslength TTT))[/B] [COLOR="#FF0000"][/COLOR][COLOR="#FF0000"];ripete per il numero di oggetti trovati[/COLOR]
    [B](setq TT (ssname TTT (setq n (1- n))))[/B] [COLOR="#FF0000"];ad ogni ciclo fornisce il [B]nome[/B] dell'oggetto[/COLOR]
    [B]<[COLOR="#0000FF"]fai qualcosa all'oggetto[/COLOR]>[/B]
)
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#11
Grazie GP, funziona perfettamente.
Ho implementato il tuo codice col mio :
Codice:
(defun C:CSTR (/)

    (setq TTT (ssget "_X" '((0 . "TEXT,MTEXT")(1 . "p*"))))

    (repeat (setq n (sslength TTT))
    (setq TT (ssname TTT (setq n (1- n))))

    (setq string (entget TT))
    (setq txt1 (assoc 1 string))
    (setq txt1 (cdr txt1))
    (setq lungh (- (strlen txt1) 63)) 

    (setq cxy (assoc 10 string))
    (setq cox (cadr cxy))
    (setq coy (caddr cxy))
    (command "_erase" TT "")
    (setq coox (rtos cox))
    (setq cooy (rtos coy))
    (setq indirizzo (strcat coox "," cooy))

    (setq testo1 (substr txt1 1 lungh)) ; nome del punto
    (setq testo2 (substr txt1 (+ lungh 1)))   ; dal nome del punto in poi
    (command "_mtext" indirizzo "_j" "_bl" "_w" 50 (strcat testo1 "{\\H0.1x;" testo2 "}") "")

)
)
ed ottengo il risultato che volevo, grazie ancora.
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#12
Grazie GP,
ho messo in pratica jl tuo suggerimento e, apparentemente tutto funziona, questo è il codice :
Codice:
    (defun CSTR (/)

    (setq TTT (ssget "_X" '((0 . "TEXT,MTEXT")(1 . "P*"))))

    (repeat (setq n (sslength TTT))
        (setq TT (ssname TTT (setq n (1- n))))

        (setq string (entget TT))
        (setq txt1 (assoc 1 string))
        (setq txt1 (cdr txt1))
        (setq lungh (- (strlen txt1) 60)) 

        (setq cxy (assoc 10 string))
        (setq cox (cadr cxy))
        (setq coy (caddr cxy))
        (command "_erase" TT "")
        (setq coox (rtos cox))
        (setq cooy (rtos coy))
        (setq indirizzo (strcat coox "," cooy))

        (setq testo1 (substr txt1 2 lungh))       ; nome del punto
        (setq testo2 (substr txt1 (+ lungh 2)))   ; dal nome del punto in poi
        (command "_mtext" indirizzo "_j" "_bl" "_w" 50 (strcat testo1 "{\\H0.1x;" testo2 "}") "")

    )
Le stringhe vengono modificate ed appaiono nel modo voluto ovvero, la prima parte con caratteri grandi e la seconda con caratteri piccoli.
Al successivo passo, quando seleziono la stringa, la stessa mi viene restituita non così come appare ma bensì contenente i caratteri di controllo usati per ottenere l'effetto > grande - piccolo <.
Questo è il codice del comando comprensivo dei risultati :
Codice:
    (defun RIFERIMENTO (/)

    (if (= help 1)
	(progn
	    (startapp "C:\\Trasformer\\HelpInLinea\\Rif.exe " "C:\\Trasformer\\HelpInLinea\\Rif.tkn")
	    (exit)
	)
    )

    (if (= Primariga 1)
        (alert "La Riga di riferimento è già stata inserita")
    )

    (setq ed1 nil)
    (while
        (= ed1 nil)
        (setq ed1 (entsel "\nSeleziona la Linea di riferimento : "))
    )

    (setq ed1 (entget (car ed1)))
    (setq txt1 (cdr (assoc 1 ed1)))
    (setq txt2 (cdr (assoc 10 ed1)))
    (princ "\n")
    (princ txt1)
    ;p2 (164.93){\H0.1x;-4420568.319,698901.058,4529365.156-1498794.527,5042435.240}
    (princ "\n")
    (princ txt2)
    ;(1.4988e+06 5.04244e+06 0.0)
    (princ "\n")

    (setq Lung (strlen txt1))
    (setq LungNomeBase (- Lung 77))
    (setq NomePuntoBase (substr txt1 1 LungNomeBase))    
    (princ "\n")
    (princ NomePuntoBase)
    ;p2
    (princ "\n")
    (princ Lung)
    ;79
    (princ "\n")

    (setq NotaX "")
  
    (setq Stazione (getstring "\nNome della Stazione : "))
    (setq NotaX (getstring T "\nNota della Stazione > cm sf sr re st pi to ct < : "))

    (cond
        ((= NotaX "cm" ) (setq NotaX "Chiodo miniato"))
        ((= NotaX "sf" ) (setq NotaX "Spigolo fabbricato"))
        ((= NotaX "sr" ) (setq NotaX "Spigolo recinzione"))
        ((= NotaX "re" ) (setq NotaX "Recinzione"))
        ((= NotaX "st" ) (setq NotaX "Segno a terra"))
        ((= NotaX "pi" ) (setq NotaX "Picchetto"))
        ((= NotaX "to" ) (setq NotaX "Tombino"))
        ((= NotaX "ct" ) (setq NotaX "Centro tombino"))
    )

    (setq pos1 (- (strlen txt1) 58))
    (setq xyz (substr txt1 pos1 34))
    (princ "\n")
    (princ xyz)
    ;4420568.319,698901.058,4529365.156
    (princ "\n")

    (setq CxB (substr xyz 1 11))
    (princ CxB)
    ;4420568.319
    (princ "\n")
    (setq CyB (substr xyz 13 10))
    (princ Cyb)
    ;698901.058
    (princ "\n")
    (setq CzB (substr xyz 24 11))
    (princ CzB)
    ;4529365.156
    (princ "\n")     

    (setq CxBB (atof CxB))
    (princ CxBB)
    ;4.42057e+06
    (princ "\n")
    (setq CyBB (atof CyB))
    (princ CyBB)
    ;698901.0
    (princ "\n")
    (setq CzBB (atof CzB))
    (princ CzBB)
    ;4.52937e+06
    (princ "\n")

    (setq Nota2 (strcat NomePuntoBase " - " NotaX " - " Stazione))
    (setq Riferimento (strcat "1|" Stazione "|" xyz "|0.000 WGS84-RTF2000]|" Nota2 "|"))
    (setq SecondaLinea "6|L1|14122017-20:12|14122017-20:12|RTK|PDOP=1|")
    (setq Stringa1 (strcat Riferimento "                                " SecondaLinea))
    (princ Stringa1)
    ;1|80000|4420568.319,698901.058,4529365.156|0.000 WGS84-RTF2000]|p2 - Recinzione - 80000|                                6|L1|14122017-20:12|14122017-20:12|RTK|PDOP=1|
    (princ "\n")

    (setq risp nil)

    (while
	(and (/= risp "S") (/= risp "N"))
	(prompt "\nDevo salvare i dati ? (S/N) : ")
	(setq risp (getstring))
	(setq risp (strcase risp))
    ) 
 
    (if
        (= risp "S")
	(progn
             (setq fp1 (open "C:\\Trasformer\\Libretto\\LibrettoPregeo.dat" "a"))
             (write-line Riferimento fp1)
             (write-line SecondaLinea fp1)     
             (close fp1)
        )
    )

    (setq Ind "")
    (setq Indice(strcat Ind NomePuntoBase))
  
    (setq Primariga 1)
    (alert Stringa1)    
	       
    )
Come si nota, per ottenere la stringa così come mi serve, la devo depurare.
Il codice qui allegato è compreso in un > .lsp < molto più lungo di nome > PRE.LSP <, dopo il primo impiego del comando > Riferimento <, ad un nuovo richiamo dello stesso, ottengo questo errore :
Codice:
Impossibile richiamare (command) da*errore* senza prima chiamare (*push-error-using-command*).
Si consiglia la conversione (command) delle chiamate in (command-s).
e per proseguire devo ricaricare di nuovo > PRE.LSP <, così ad ogni impiego di > Riferimento <!
Non riesco trovare ciò che provoca questo comportamento.
Grazie.
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
#13
Ora non ho tempo di esaminare il tuo listato, ma la prima cosa che mi viene in mente è che devi resettare le variabili dopo l'uso della routine, ovvero "localizzarle".
Per fare questo devi posizionarle dopo la barra nella riga del defun, ad es.:
(defun c:pippofranco ( / ed1 txt1 txt2)
così ad ogni lancio partono vergini.
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#14
grazie GP,
ho reso private le variabili ma il problema prima citato rimane ovvero non riesco a ricaricare il comando.
Ho notato anche un'altro problemino :
applicando il comando che modifica le stringhe, se vi sono due stringhe sovrapposte anche parzialmente, i relativi testi modificati non appaiono nella posizione nella quale dovrebbero essere ma risultano con lo stesso allineamento orizzontale, uno sopra l'altro.
Difficile!
Grazie.
(P.S. Mi sembra che il problemino si manifesti con lo zoom originale, se vado sul particolare, mi sembra, tutto va bene.)
 

rpor66

Utente Standard
Professione: Programmatore
Software: AutoCad, GstarCAD, CadWorx, Excel, Lisp, VBA
Regione: Sicilia
#15
Quando inserisci entità nel disegno devi tener conto degli osnap attivi che interferiscono modificando il punto di inserimento.
Questa funzione serve a attivare / disattivare gli osnap:
; accende o spegne gli osnap, equivalente al tasto F3
(defun SetOsnapOnOFF(mode / osmode)
(setq osmode (getvar "osmode"))
(if (= mode "ON")
(if (> osmode 16384)
(setvar "osmode" (- osmode 16384))
)
(if (< osmode 16384)
(setvar "osmode" (+ osmode 16384))
)
)
)
 

Angelo2449

Utente Junior
Professione: Pensionato
Software: Autocad
Regione: Lombardia
#16
Grazie rpor66, eseguito con successo con osmode settata a 0.
Ora occorre trovare la soluzione all'altro problema segnalato.