lukaasz

Użytkownik forum
  • Postów

    2
  • Dołączył

  • Ostatnia wizyta

Odpowiedzi opublikowane przez lukaasz

  1. 9 godzin temu, kruszynski napisał:

    Ogólnie dobrze, ale trochę chaos zaczyna się wkradać.

    
    (setq nazwa (sslength zb1) i 0)

    Może przemawia przeze mnie obsesja ale bardzo ważne jest nadawanie zmiennym odpowiednich nazw . Nazwy mają być znaczące a nie mylące.
    Bardzo dobrze jest to wytłumaczone w książce "Czysty kod. Podręcznik dobrego programisty" Autor: Robert C. Martin . Cały niewielki rozdział jest temu poświęcony.
    sslength zwraca ilość i nazywanie tego "nazwa" to zły pomysł

    warto też stosować zmienne lokalne.  np

    
    (defun C:raport ( / nazwa_warstwy zb1 nazwa i )   

    W wielu miejscach w programie może pojawić się  zmienna "i", jeśli mamy funkcję wewnątrz funkcji, w obu wykorzystujemy i jako licznik pętli to funkcja wewnętrzna nadpisze stan zmiennej z funkcji zewnętrznej i takiego błędu można szukać godzinami.

     

    
    (setq wsk (ssname zb1 i) lista_dxf (entget wsk))

    Moim zdaniem bardziej czytelne byłoby

    
    (setq lista_dxf (entget (ssname zb1 i)))
    
    (princ "\n")
    (princ "Liczba elementow w zbiorze wyboru: ")
    (princ (sslength zb1))
    (princ "\n")

    można uprościć do:

    
    (princ (strcat "\nLiczba elementow w zbiorze wyboru: " (itoa (sslength zb1) ) "\n" )

    Teraz najważniejsze :

    
    (setq lista_dxf (entget (ssname zb1 i)))

    tutaj mamy zapisany cały element.

    
    (setq EntName (cdr (assoc 0 lista_dxf ) ) )

    daje nam nazwę elementu np INSERT
    Trzeba wykorzystać cond i rozdzielić działanie programu na odpowiednie dla każdego typu obiektów.

    
    (cond
    ((= EntName "INSERT")    (progn
        (print "blok")
        (print (cdr (assoc 2 lista_dxf ) ) )    ; nazwa bloku
    ))
    ((or(= EntName "LIGHTWEIGHTPOLYLINE")(= EntName "POLYLINE")) (progn
    (print "polilinia ")
    ))
    ((= EntName "CIRCLE")(progn
    (print "okrąg")
    ) )
    ((= EntName "ARC") (progn
    (print "łuk")
    ))
    ((= EntName "LINE") (progn
    (print "linia")
    ))
    
    (t
    (print "Wybrałeś coś innego")
    )
    )
    

    odczytanie poszczególnych parametrów typu punkty początku, końca, środek itp to tylko kwestia odczytania odpowiedniej pozycji z list_dxf.
    (punkty to najczęściej kod: 10) pełną listę kodów można bez problemu znaleźć w Internecie.
    Można też zamienić element jako ENAME na VLA-OBJECT

    
    (setq element (vlax-ename->vla-object (ssname zb1 i) ))

    Wtedy to już pełna kultura obiektowości.
    Nazwę bloku możemy pobrać tak:

    
    (vlax-get-property element 'Name )

    środek okręgu:

    
    (vlax-get-property element 'Center )

    albo nawet tak:

    
    (vla-get-Center element )

    tylko trzeba pamiętać, że punkty są typu variant, czyli trzeba je zamienić na czytelną postać zanim się je wyświetli:

    
    (vlax-safearray->list (vlax-variant-value (vlax-get-property element 'Center )  ) )

    Powodzenia. W razie dalszych trudności proszę pisać

     

    Super, bardzo dziękuję za wskazówki. Problem ma tylko taki, że coś mi wyświetla cały czas tą samą nazwę bloku przy każdym INSERT, a nie wiem za bardzo czemu. 

    (defun C:raport ()   ;tworzy raport obiektow znajdujacych sie na danej warstwie 
    
        (setq dlugosc_warstwy (getstring "Podaj nazwe warstwy: ")) 
    
        (setq zb1 (ssget "X" (list (cons 8 dlugosc_warstwy))))
      
        (if(= zb1 nil)
            (progn
                (princ "\nZbior wyboru nie zawiera elementow.\n")
            )
        )
    
        (if (> (sslength zb1) 0) 
            (progn
                (textscr) 
                (princ "\n") 
                (princ "Liczba elementow w zbiorze wyboru: ") 
                (princ (sslength zb1)) 
                (princ "\n")
                (setq dlugosc (sslength zb1) i 0) 
          
                (repeat dlugosc      
                    (progn
              
                        (setq lista_dxf (entget (ssname zb1 i)))
                        (setq EntName (cdr (assoc 0 lista_dxf )))    
                        (setq num (cdr(car lista_dxf)))      
                        (setq wpocz2 (cdr (assoc 0 (entget num))))                             
                        (setq wpoczl (cons wpocz2 wpoczl))
                        (setq i (1+ i))
                    )
                )
                
              (setq i 0)
                (repeat dlugosc
                    (cond
    ((= EntName "INSERT")    (progn
        (princ i)
        (princ (nth i wpoczl))
        (princ (cdr (assoc 2 lista_dxf ) ) )    ; nazwa bloku
        (princ "\n")
    ))
    ((or(= EntName "LIGHTWEIGHTPOLYLINE")(= EntName "POLYLINE")) (progn
    (princ "Polilinia ")
    ))
    ((= EntName "CIRCLE")(progn
    (princ "okrąg")
    ) )
    ((= EntName "ARC") (progn
    (princ "łuk")
    ))
    ((= EntName "LINE") (progn
    (princ "linia")
    ))
    
    (t
    (princ "Wybrales cos innego")
    )
    )
                        
                        (setq i (1+ i))
                    
                )
                (graphscr) 
            )
        )
               (princ)
    )

     

  2. Witam,

    Czy jest ktoś w stanie pomóc przy dokończeniu programu, który wypisuje nazwy elementów rysunkowych (linii, polilinii, okręgów) pod podaną warstwą? Na tą chwilę mam tak, że po podaniu nazwy warstwy wypisuje mi:

    1 LWPOLYLINE
    2 LWPOLYLINE
    3 CIRCLE
    4 INSERT
    itd.

    Potrzebuję, aby za "INSERT" wypisać jeszcze nazwę bloku, a dla pozostałych obiektów współrzędne punktów, np. dla polilinii współrzędne pkt początkowego i końcowego, dla okręgu współrzędne środka itp.

    Dodam, że jestem całkowicie początkujący. Oto co mam do tej pory:

    (defun C:raport ()    
    
       (setq nazwa_warstwy (getstring "Podaj nazwe warstwy: ")) 
    
       (setq zb1 (ssget "X" (list (cons 8 nazwa_warstwy))))
      
       (if(= zb1 nil)
          (progn
             (princ "\nZbior wyboru nie zawiera elementow.\n")
          )
        )
    
       (if (> (sslength zb1) 0) 
          (progn
             (textscr) 
             (princ "\n") 
             (princ "Liczba elementow w zbiorze wyboru: ") 
             (princ (sslength zb1)) 
             (princ "\n")
             (setq nazwa (sslength zb1) i 0) 
         
             (repeat nazwa      
                (progn
            
                   (setq wsk (ssname zb1 i) lista_dxf (entget wsk))
                   (setq num (cdr(car lista_dxf)))      
                
                            (setq w2 (cdr (assoc 0 (entget num))))                      
                            (setq wl (cons w2 wl))                            
    
                   (setq i (1+ i))
                )
             )
             
            (setq i 0)
             (repeat nazwa
                (progn
                   (princ i)
                   (princ (nth i wl))
                   (princ "\n")
                   (setq i (1+ i))
                )
             )
             (graphscr) 
          )
       )
               (princ)
    )