Newsgroup: it.comp.software.cad
Titolo: [LISP] calcolare il peso di un solido

Salve gente,
fino ad oggi per calcolare il peso di un solido ho utilizzato _massprop
ottenendone il volume e moltiplicandolo con la calcolatrice per il peso
specifico del materiale.
So che in Autocad esiste il comando CAL per richiamare uno strumento di
calcolo.
Che voi sappiate, è possibile programmare qualche linea di codice lisp al
fine di avere la possibilità di selezionare il solido, immettere il peso
specifico ed ottenerne il peso, magari approssimato alla prima decimale?
In caso affermativo, potreste indicarmi dove trovare un codice simile da
poter utilizzare (o modificare o quant'altro)?
Grazie in anticipo
ReddeV

Prova questo:
(defun C:ALE_GetWeight ( / EntObj VolVal WSpVal)
  (vl-load-com)
  (if (setq EntObj (ALE_EntSelFilter "Seleziona un solido" '((0 . 
"3DSOLID"))))
    (progn
      (setq
        EntObj (ALE_vlax-Ename>Vla-Object EntObj)
        VolVal (vla-get-Volume EntObj)
        WSpVal (getreal "\nPeso specifico: ")
      )
      (if WSpVal
        (princ
          (strcat
            "\nVolume: " (rtos VolVal 2 1)
            " - Peso: " (rtos (* VolVal WSpVal) 2 1)
          )
        )
      )
    )
  )
  (princ)
)
;
; Copyright ©2005 - Marc'Antonio Alessi, Italy - All rights reserved
; 
http://xoomer.virgilio.it/alessi
;
; Function: ALE_EntSelFilter
;
; Version 1.00 - 22/02/2005
;
; Description:
;   Ssget for one entity with filter list
;
; Arguments:
;   PrmStr = User prompt [STR]
;   FltLst = ssget filter list [LIST]
;
; Example:
;  (ALE_EntSelFilter "Select attibuted block" '((0 . "INSERT") (66 . 1)))
;
; Return Values:
;   [ENAME] Entity name
;   nil if user press 'Return' or 'Space'
;
(defun ALE_EntSelFilter (PrmStr FltLst / FlgSlt EntNam)
    (princ "\n_ ")
    (prompt (setq PrmStr (strcat "\n" PrmStr ": ")))
    (if
      (while (not FlgSlt)
        (if (setq EntNam (ssget "_:E:S" FltLst))
          (not (setq FlgSlt T))
          (if (= 52 (getvar "ERRNO"))
            (setq FlgSlt T)
            (prompt (strcat "\nNessun oggetto selezionato o valido, 
riprova!" PrmStr))
          )
        )
      )
      (not (princ "\nComando annullato.  "))
      (ssname EntNam 0)
    )
)
;
; Function: ALE_vlax-Ename>Vla-Object
;
; Version 1.00 - 22/02/2005
;
; Description:
;   Validate input object
;
; Arguments:
;   EntObj = [VLA-OBJECT] or [ENAME]
;
; Return Values:
;   [VLA-OBJECT] if valid input object
;   nil otherwise
;
(defun ALE_vlax-Ename>Vla-Object (EntObj)
    (cond
      ( (= (type EntObj) 'VLA-OBJECT) EntObj )
      ( (= (type EntObj) 'ENAME) (setq EntObj (vlax-Ename->Vla-Object 
EntObj)) )
      (T (prompt "\nTipo di oggetto non valido!  ") )
    )
)
;
(princ)

 Prova questo:
ti ringrazio, ma ho dei problemi!
dunque... copiando l'intero listato e lanciandolo con ALE_GetWeght il log di
risposta è questo che segue:
Command: ale_getweight
error: null function
(VL-LOAD-COM)
(C:ALE_GETWEIGHT)
*Cancel*
se provo a saltare VL-Load con punto e virgola ottengo questo log:
Command: ale_getweight
_
Seleziona un solido: error: bad ssget mode string
(SSGET "_:E:S" FLTLST)
(SETQ ENTNAM (SSGET "_:E:S" FLTLST))
(IF (SETQ ENTNAM (SSGET "_:E:S" FLTLST)) (NOT (SETQ FLGSLT T)) (IF (= 52
(GETVAR "ERRNO")) (SETQ FLGSLT T) (PROMPT (STRCAT "\nNessun oggetto
selezionato
o valido, \nriprova!" PRMSTR))))
(WHILE (NOT FLGSLT) (IF (SETQ ENTNAM (SSGET "_:E:S" FLTLST)) (NOT (SETQ
FLGSLT
T)) (IF (= 52 (GETVAR "ERRNO")) (SETQ FLGSLT T) (PROMPT (STRCAT "\nNessun
oggetto selezionato o valido, \nriprova!" PRMSTR)))))
(IF (WHILE (NOT FLGSLT) (IF (SETQ ENTNAM (SSGET "_:E:S" FLTLST)) (NOT (SETQ
FLGSLT T)) (IF (= 52 (GETVAR "ERRNO")) (SETQ FLGSLT T) (PROMPT (STRCAT
"\nNessun oggetto selezionato o valido, \nriprova!" PRMSTR))))) (NOT (PRINC
"\nComando annullato.  ")) (SSNAME ENTNAM 0))
(ALE_ENTSELFILTER "Seleziona un solido" (QUOTE ((0 . "3DSOLID"))))
(SETQ ENTOBJ (ALE_ENTSELFILTER "Seleziona un solido" (QUOTE ((0 .
"3DSOLID")))))
(IF (SETQ ENTOBJ (ALE_ENTSELFILTER "Seleziona un solido" (QUOTE ((0 .
"3DSOLID"))))) (PROGN (SETQ ENTOBJ (ALE_VLAX-ENAME>VLA-OBJECT ENTOBJ) VOLVAL
(VLA-GET-VOLUME ENTOBJ) WSPVAL (GETREAL "\nPeso specifico: ")) (IF WSPVAL
(PRINC (STRCAT "\nVolume: " (RTOS VOLVAL 2 1) " - Peso: " (RTOS (* VOLVAL
WSPVAL) 2 1))))))
(C:ALE_GETWEIGHT)
*Cancel*
ovviamente non conoscendo autolisp sono sicuro che l'annullare il VL-Load ha
provocato qualche conflitto nel resto del codice.
non riesco a venirne a capo!
mi sono accorto che ho tralasciato il fatto che lavoro con AutoCad 14, ma
per il lisp non credo ci siano differenze!
grazie ancora
ReddeV

 Prova questo:
ok... funge su autocad 2004!
mi rispondo anche per l'altro post scritto in reply... avevo ignorato il
vl-load ed ovviamente non funzionava.
In ogni caso da quello che ho potuto verificare, il listato su autocad14 non
può funzionare perchè è in VLisp anzichè Lisp.
Grazie ancora per l'aiuto!
ReddeV

 può funzionare perchè è in VLisp anzichè Lisp.
a meno che tu non abbia il Visual Lisp per R14 (che veniva venduto a 
parte)...
-- 
Marc'Antonio Alessi
http://xoomer.virgilio.it/alessi
(strcat "NOT a " (substr (ver) 8 4) " guru.")
--

E' un lisp veramente molto utile, si potrebbe fare in modo di
selezionare piu' solidi come quando si calcola con massprop?
grazie ancora
ciao Andrea da Modena

 quando si calcola con massprop?
; Marc'Antonio Alessi 
http://xoomer.virgilio.it/alessi
; Version 1.00 - 18/10/2005 - per Andrea da Modena
;
(defun C:ALE_GetTotalWeight ( / Countr SelSet EntNam EntObj VolVal WSpVal)
  (vl-load-com)
  (if
    (setq SelSet
      (ALE_SsGetFilter "Seleziona uno o più solidi" '((0 . "3DSOLID")))
    )
    (progn
      (setq
        WSpVal (getreal "\nPeso specifico: ")
        VolVal 0.0
        Countr 0
      )
      (while (setq EntNam (ssname SelSet 0))
        (setq
          EntObj (ALE_vlax-Ename>Vla-Object EntNam)
          VolVal (+ (vla-get-Volume EntObj) VolVal)
          Countr (1+ Countr)
        )
        (ssdel EntNam SelSet)
      )
      (if WSpVal
        (princ
          (strcat
            "\n" (itoa Countr) " Solidi > Volume totale: "
            (rtos VolVal 2 1)
            " - Peso totale: " (rtos (* VolVal WSpVal) 2 1)
          )
        )
      )
      (vlax-release-object EntObj)
    )
  )
  (princ)
)
;
; Copyright ©2005 - Marc'Antonio Alessi, Italy - All rights reserved
; 
http://xoomer.virgilio.it/alessi
;
; Function: ALE_SsGetFilter
;
; Version 1.00 - 22/02/2005
;
; Description:
;   Ssget with filter list
;
; Arguments:
;   PrmStr = User prompt [STR]
;   FltLst = ssget filter list [LIST]
;
; Example:
;  (ALE_SsGetFilter "Select attibuted block(s)" '((0 . "INSERT") (66 . 1)))
;
; Return Values:
;   [PICKSET] Selection set
;   nil if user press 'Return' or 'Space'
;
(defun ALE_SsGetFilter (PrmStr FltLst / FlgSlt SelSet)
    (princ "\n_ ")
    (prompt (setq PrmStr (strcat "\n" PrmStr ": ")))
    (if
      (while (not FlgSlt)
        (if (setq SelSet (ssget FltLst))
          (not (setq FlgSlt T))
          (if (= 52 (getvar "ERRNO"))
            (setq FlgSlt T)
            (prompt
              (strcat
                "\nNessun oggetto selezionato o valido, riprova!" PrmStr
              )
            )
          )
        )
      )
      (not (princ "\nComando annullato.  "))
      SelSet
    )
) 

Perfetto ho solo fatto due piccole modifiche che mi semplificano la
vita, una e' il comando da richiamare e l'altra e' per l'unita' di
misura ma e' FANTASTICO.
(defun C:peso ( / Countr SelSet EntNam EntObj VolVal WSpVal)
            " - Peso totale: " (rtos (* VolVal WSpVal 0.000001) 2 1)
Grazie mille
Ciao Andrea
P.S.
Dove hai imparato a programmare in visual lisp? Interesserebbe anche a
me.

 Ciao Andrea
ed hai anche il mio stesso nome!
'nnamo bene!
;]
ReddeV

Devi anche aggiungere un pezzo del primo listato che ha postato Marco
altrimenti ti va in errore.
;
; Function: ALE_vlax-Ename>Vla-Object
;
; Version 1.00 - 22/02/2005
;
; Description:
;   Validate input object
;
; Arguments:
;   EntObj = [VLA-OBJECT] or [ENAME]
;
; Return Values:
;   [VLA-OBJECT] if valid input object
;   nil otherwise
;
(defun ALE_vlax-Ename>Vla-Object (EntObj)
    (cond
      ( (= (type EntObj) 'VLA-OBJECT) EntObj )
      ( (= (type EntObj) 'ENAME) (setq EntObj (vlax-Ename->Vla-Object
EntObj)) )
      (T (prompt "\nTipo di oggetto non valido!  ") )
    )
)
;
(princ)
A proposito seguiamo anche gli stessi ng ad esempio ihm anche se io non
posto molto.
Ciao Andrea da Modena

 me.
E' una storia lunga che comincia nel 1988 con un 286,
poi il mio primo 386 IBM 16Mhz 2 Mb Ram (11 milioni - di lire)
AutoCAD 2.17 (se non ricordo male)
...
se vai sul mio sito puoi vedere qualcosa come il 2D Parametrico
per AutoCAD.
Se ti occupi di strutture C.A. ho fatto anche un programma per
disegnare automaticamente le travi, i ferri, staffe, ecc.
---
La funzione può essere migliorata usando una variabile globale
per il peso specifico:
; Marc'Antonio Alessi 
http://xoomer.virgilio.it/alessi
; Version 1.01 - 19/10/2005 - per Andrea da Modena e ReddeV
; #WSpVl = variabile globale
;
(defun C:ALE_GetTotalWeight ( / Countr SelSet EntNam EntObj VolVal)
  (vl-load-com)
  (if
    (setq SelSet
      (ALE_SsGetFilter "Seleziona uno o più solidi" '((0 . "3DSOLID")))
    )
    (progn
      (setq
        #WSpVl (uReal 7 "" "Peso specifico" #WSpVl)
        VolVal 0.0
        Countr 0
      )
      (while (setq EntNam (ssname SelSet 0))
        (setq
          EntObj (ALE_vlax-Ename>Vla-Object EntNam)
          VolVal (+ (vla-get-Volume EntObj) VolVal)
          Countr (1+ Countr)
        )
        (ssdel EntNam SelSet)
      )
      (princ
        (strcat
          "\n" (itoa Countr) " Solidi > Volume totale: "
          (rtos VolVal 2 1)
          " - Peso totale: " (rtos (* VolVal #WSpVl 0.000001) 2 1)
        )
      )
      (vlax-release-object EntObj)
    )
  )
  (princ)
)
;
(defun uReal (IGtBit KwdStr PrmStr DefRea / InpVal)
  (if DefRea
    (setq
      PrmStr (strcat "\n" PrmStr " <" (ALE_RTOS_DZ8 DefRea) ">: ")
      IGtBit (logand IGtBit 254)
    )
    (setq PrmStr (strcat "\n" PrmStr ": "))
  )
  (initget IGtBit KwdStr)
  (setq InpVal (getreal PrmStr))
  (if InpVal InpVal DefRea)
)
;
(defun ALE_RtoS_DZ8 (ReaVal / CurDZn OutVal)
  (if (= 8 (setq CurDZn (getvar "DIMZIN")))
    (setq CurDZn nil)
    (setvar "DIMZIN" 8)
  )
  (setq OutVal (rtos ReaVal 2))
  (and CurDZn (setvar "DIMZIN" CurDZn))
  OutVal
)

 ...
senti... ormai è più per curiosità visto che il listato già me l'hai passato
(e ancora ti ringrazio).
mi chiedevo se fosse possibile ottenere cmq il peso anche con il Lisp
normale e non visual.
In pratica si tratterebbe di estrapolare il dato del volume dalla funzione
di _massprop, aprire una query che ti chieda di inserire il peso specifico e
semplicemente moltiplicare i due.
Che tu sappia... esiste il modo di estrarre il valore del volume dal
_massprop?
ReddeV

 posto molto.
ehehehe... posta di piů allora... tanto hai visto pure te che gabbia di
bestie č quel gruppo!
ReddeV

 _massprop?
Si è possibile, ma non è un lavoretto di cinque minuti...
Marco 

 Si è possibile, ma non è un lavoretto di cinque minuti...
ok... vedo se riesco a documentarmi (non avevo intenzione di chiederti di
lavorare per me... ci mancherebbe)
grazie
ReddeV

La funzione e' perfetta grazie molte, io per lavoro mi occupo tra le
altre cose di progettazione meccanica e mi sarebbe piaciuto imparare a
farmi funzioncine come quella che ci hai gentilmente fatto tu.
Ciao e grazie mille ancora Andrea