Cambio colori layers, da RGB a ACI (ma Basic Colors!)

MauroTC

Esploratore...
Professione: Disegnatore/Progettista
Software: Inventor 2021 + Autocad Mech.2021
Regione: Umbria
Ciao a tutti,
ci sono una grossa quantità di disegni dwg ottenuti da esportazione con un qualche sw 3D che genera layer che hanno associati colori RGB un po’ troppo variegati, mentre il cliente finale esige che i colori assegnati siano solo gli 8 principali (da 1 a 8).
Per spiegarmi meglio, nell’immagine allegata a sinistra è il risultato della tabella layers che si ha dopo esportazione che il cliente non vuole, a destra come lo si vorrebbe avere, comunque secondo queste combinazioni:
RGB.png

255,0,0 = 1 (red)
255,255,0 = 2 (yellow)
0,255,0 = 3 (green)
0,255,255 = 4 (light blue)
128,255,255 = 4 (light blue)
0,0,255 = 5 (dark blue)
255,0,255 = 6 (magenta)
255,255,255 = 7 (white)
128,128,128 = 8 (gray)

Presumo che con un lisp la cosa dovrebbe essere abbastanza semplice e in giro su internet ci sono varie soluzioni a partire dal “classico” RGB2ACI, che però non fa esattamente quanto dovrebbe, perché probabilmente ragiona con i valori numerici della mappa e in qualche caso di combinazioni un po’ balorde si lascia ingannare (esempio sul 128,255,255).

Se qualcuno riuscisse ad impostare un lisp anche solo per un paio di combinazioni, sarei molto grato, poi lo completerei io autonomamente replicando le righe, con le poche reminiscenze rimaste di lisp…

Al momento sopperisco con un macro-command che mi sono fatto (“ragiona” in maniera diversa, assegnando ai vari colori base gli specifici layers) , che ha di buono che gira pure sotto autocad LT, però gli utilizzatori trovano ostico caricare un pulsante personalizzato, mentre preferiscono caricare e far girare un lisp.
(mia macro: ^C^C -LAYER C 2 AM_1 C 1 AM_0 C 3 AM_3 C 3 AM_3N C 4 AM_4 C 4 AM_5 ; ecc...)

Grazie anticipatamente!
 
Ultima modifica:

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
Vedi se funziona
Codice:
(defun c:pippo ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x (vla-get-color x))
    )
)
 

MauroTC

Esploratore...
Professione: Disegnatore/Progettista
Software: Inventor 2021 + Autocad Mech.2021
Regione: Umbria
Vedi se funziona
Codice:
(defun c:pippo ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x (vla-get-color x))
    )
)
? grazie per l'interessamento, domani lo provo. Dal basso della mia ignoranza mi chiedo come funzioni., con così poche righe. Non credo processi i colori richiesti e non ho capito semmai se c'è e cosa, da editare nel codice... ?
 

MauroTC

Esploratore...
Professione: Disegnatore/Progettista
Software: Inventor 2021 + Autocad Mech.2021
Regione: Umbria
Prova, poi te lo spiego
Provato.
Diciamo che fa quello che fa il classico e storico RGB2ACI, ma che è uno script molto più lungo!
Ma ha lo stesso "limite", ovvero si va ad "incartare" su quel rgb 128,255,255, che invece che trasformarlo in 4 (ciano) lo fa diventare 131 (non so perchè)... e magari potenzialmente lo può fare anche su altre sfumature...
128.PNG

A me andrebbero bene anche le 9 trasformazioni mirate se si potesse; anzi come detto me ne basterebbero un paio di esempio, poi lo script dovrei essere in gradi di completarlo io replicando le righe di codice...

Ti allego anche un dwg per test...

Grazie ancora per la disponibilità!
 

Allegati

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
La funzione vla-get-color restituisce il colore ACI, ovvero, nel caso di truecolor, il corrispondente ACI similare.
Ad esempio il colore 255,255,0 restituisce 2 (giallo), il colore 128,255,255 restituisce 131).
Il lisp quindi assegna ad ogni layer il suo stesso colore, ma indicato come ACI.
Nell'aggiornamento sotto, visto che devi rimanere nei primi 8 colori, nel caso di 131 viene trasformato in 4 (mi era sfuggito).
Tutto funziona quindi con i colori che hai indicato nella tua immagine, ci possono essere altre "sfumature"?
Codice:
(defun c:xx ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x (if (= 131 (vla-get-color x)) 4 (vla-get-color x)))
    )
)

Se invece vuoi completarlo a piacimento...
Codice:
(defun c:yy ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (if (= (vla-get-Name x) "AM_0") (vla-put-color x 1))
        (if (= (vla-get-Name x) "AM_1") (vla-put-color x 2))
        (if (= (vla-get-Name x) "AM_3") (vla-put-color x 3))
        (if (= (vla-get-Name x) "AM_4") (vla-put-color x 4))
    )
)
 

MauroTC

Esploratore...
Professione: Disegnatore/Progettista
Software: Inventor 2021 + Autocad Mech.2021
Regione: Umbria
La funzione vla-get-color restituisce il colore ACI, ovvero, nel caso di truecolor, il corrispondente ACI similare.
Ad esempio il colore 255,255,0 restituisce 2 (giallo), il colore 128,255,255 restituisce 131).
Il lisp quindi assegna ad ogni layer il suo stesso colore, ma indicato come ACI.
Nell'aggiornamento sotto, visto che devi rimanere nei primi 8 colori, nel caso di 131 viene trasformato in 4 (mi era sfuggito).
Tutto funziona quindi con i colori che hai indicato nella tua immagine, ci possono essere altre "sfumature"?
Codice:
(defun c:xx ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x (if (= 131 (vla-get-color x)) 4 (vla-get-color x)))
    )
)

Se invece vuoi completarlo a piacimento...
Codice:
(defun c:yy ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (if (= (vla-get-Name x) "AM_0") (vla-put-color x 1))
        (if (= (vla-get-Name x) "AM_1") (vla-put-color x 2))
        (if (= (vla-get-Name x) "AM_3") (vla-put-color x 3))
        (if (= (vla-get-Name x) "AM_4") (vla-put-color x 4))
    )
)
Grazie, due soluzioni, testate entrambe, entrambe perfette!

Per essere autonomo in caso di eccezioni o novità:
Sul primo presumo che debba aggiungere righe così?
(defun c:xx ()
(vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
(vla-put-color x (if (= 131 (vla-get-color x)) 4 (vla-get-color x)))
(vla-put-color x (if (= 151 (vla-get-color x)) 6 (vla-get-color x)))
)
)

Sul secondo, ho già implementato qualcosa...:

(defun c:yy ()
(vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
(if (= (vla-get-Name x) "AM_0") (vla-put-color x 1))
(if (= (vla-get-Name x) "AM_1") (vla-put-color x 2))
(if (= (vla-get-Name x) "AM_2") (vla-put-color x 7))
(if (= (vla-get-Name x) "AM_3") (vla-put-color x 3))
(if (= (vla-get-Name x) "AM_3N") (vla-put-color x 3))
(if (= (vla-get-Name x) "AM_4") (vla-put-color x 4))
(if (= (vla-get-Name x) "AM_BOR") (vla-put-color x 3))
)
)

Ineccepibile! (y)
 

MauroTC

Esploratore...
Professione: Disegnatore/Progettista
Software: Inventor 2021 + Autocad Mech.2021
Regione: Umbria
Per completezza di chi può essere interessato metto anche il macro-comando assegnato ad un pulsante, che permette di ottenere stesso risultato (gestibile in questo caso trattandosi di pochi layers...), con breve spiegazione:

^C^C-LAYER C 1 AM_0 C 2 AM_1 C 7 AM_2 C 3 AM_3 C 3 AM_3N C 4 AM_4 C 4 AM_5 C 2 AM_6 C 3 AM_7 C 7 AM_8 C 1 AM_10 C 6 AM_11 C 9 AM_12 C 3 AM_BOR C 5 AM_VIEWS ^C

-LAYER lancia il comando layer
C chiama l'opzione colore
1 seleziona il colore da assegnare
AM_0 è il layer a cui si vuole assegnare quel colore

Poi di nuovo C per opzione colore
2 il colore da assegnare
AM_1 il layer a cui assegnarlo

e così via...
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
Il primo non va bene, appena riesco posto qualcosa
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
In sostituzione del primo lisp puoi usare questo, aggiungendo una riga per ogni colore particolare che vuoi processare
Codice:
(defun c:zz ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x
            (cond
                ( (= 131 (vla-get-color x)) 4)
                ( (= 151 (vla-get-color x)) 6)
                (t (vla-get-color x)) ;--> se il colore non è tra quelli indicati assegna il proprio colore ACI
            )
        )
    )
)

Per il secondo puoi usare anche questa versione con COND, la particolarità è che puoi assegnare lo stesso colore ai layer che non ti interessano
Codice:
(defun c:hh ()
    (vlax-for x (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (vla-put-color x
            (cond
                ( (= (vla-get-Name x) "AM_0") 1)
                ( (= (vla-get-Name x) "AM_1") 2)
                ( (= (vla-get-Name x) "AM_3") 3)
                ( (= (vla-get-Name x) "AM_4") 4) 
                (t 7)   ; --> se il layer non è tra quelli indicati assegna il colore 7
            )
        )
    )
)
 

rpor66

Utente Standard
Professione: Programmatore
Software: AutoCad, CadWorx, Lisp, VBA. YouTube: roberto portuese
Regione: Sicilia
Codice:
(defun fnRidColor (r g b / rosso verde blu Indice lColor)
    (setq lColor (list 8 1 3 2 5 6 4 7))
    (if (= r 128) (setq r 127))
    (if (= g 128) (setq g 127))
    (if (= b 128) (setq b 127))
    (setq rosso (lsh r -7))
    (setq verde (lsh g -7))
    (setq blu (lsh b -7))
    (setq Indice (+ rosso (* verde 2) (* blu 4)))
    (nth indice lColor)
)
Questa funzione trasforma i valori rgb 0÷255 in 0÷1 tramite la funzione lsh, praticamente è come ridurre i colori di una foto da 16 milioni a 8.
La condizione (= r 128) è per ovviare ad un errore interpretativo, considera 128 1 e non 0, quindi valori rgb 128 255 255 diventavano 7 e non 4, come nel tuo specifico caso.

Buon divertimento
 

GP.

Utente Senior
Professione: Nientologo
Software: uozapp
Regione: Vercelli
lsh è una di quelle funzioni che non ho mai usato e di cui non riuscivo ad ipotizzarne un utilizzo, ora almeno so che non è stata inventata invano... :)
 

rpor66

Utente Standard
Professione: Programmatore
Software: AutoCad, CadWorx, Lisp, VBA. YouTube: roberto portuese
Regione: Sicilia
lo shift dei numeri l'ho imparato studiando "linguaggio macchina per msx", libro trovato per caso in una libreria a Ragusa mentre ero in libera uscita, facevo il militare a Comiso, anno 1989.
Credo sia la prima volta che uso la funzione, e come disse Cetto La Qualunque, "roba da matti".