16.07.2014 13:19    

brolin59
Benzer bir konu varsa ve tekrar açtıysam kusura bakmayın. Aradım fakat benzer birşey göremedim o yüzden yeni konu açıyorum. Yeni lisp öğrenmeye başladım. Bir kaç tane basit, işimi görecek dört işlem yapan lisp yazdım.:) Şöyle bir ihtiyacım var;

Çizim yapmadan önce gelen mimariyi temizlemem gerekiyor. Benim kendi layerlarımın hepsi tanımlı. Kısaca açıklayım. Mesela komutu giricem çizim üzerinden bir line ı seçicem ve o line ın layer ına sahip tüm objeleri benim layerım olan "mimari" layer a çevirecek.

Böyle bir lisp için yardımcı olursanız sevinirim.

16.07.2014 14:01    

ProhibiT


Linkleri görebilmek için ÜYE olmalısınız.

linkinde paylaşılan Lisp fonksyionları incelerseniz her türlü sorunuza cevap bulabilirsiniz.

17.07.2014 16:23    

brolin59
Linki inceledim. Ufak bir ekleme yapmam lazım ama bilgim yetersiz yardımcı olursanız sevinirim. Şöyle birşey yaptım verdiğiniz linkten faydalanarak;

(defun C:mml (/ e)
(setvar "cmdecho" 0)
(command "_.undo" "group")
(command "_.chprop" (ssget) "" "layer" "mimari_layer" "")
(command "_.undo" "e")
(setvar "cmdecho" 1)
(prin1)
)

Bir nesne seçiyoruz ve o nesnenin layerını "mimari_layer" a çeviriyor. sorunsuz çalışıyor fakat benim amaçladığım şey şu:

Bir nesne seçicem, o nesnenin layerına sahip tüm objelerin layerını "mimari_layer" a çevirecek. Bu mümkünmüdür? Yardımcı olursanız sevinirim.

Not : Belki verdiğiniz linkte sorduğum sorunun cevabıda vardır fakat ben anlayamadım sanırım.

18.07.2014 13:28    

Travaci
brolin59 napıcaksın ? busefer her layer için ayrı kodmu yazıcaksın ?
Linkte ki ChLyr isimli fonksiyon sana göre.

18.07.2014 15:51    

brolin59
Amatörce de olsa yaptım. En azından çalışıyor ve benim işimi görür :) İşine yarayacağını düşünen arkadaşlar için kodu yayınlıyorum. Bu konuda profesyonel olan arkadaşlarımız zaten kodu gereğince düzenleyeceklerdir.

ehya ve ProhibiT, yardımlarınız için teşekkür ederim.

Kod:

(defun ssv (/)
  (setvar "cmdecho" 0)
  (command "_.undo" "group")
)
(defun rsv (/)
  (command "_.undo" "e")
  (setvar "cmdecho" 1)
  (prin1)
)

(defun C:mml (/ e)
  (ssv)

  (setq robj (entsel "\nLayer'ı değiştirilecek objeyi seçiniz : "))
  (setq lrobj (cdr (assoc 8 (entget (car robj)))))

  (setq robj2 (entsel "\nLayer'ı Alınacak objeyi seçiniz : "))
  (setq lrobj2 (cdr (assoc 8 (entget (car robj2)))))

  (print "Tüm çizimi seçin : ")
  (setq ss (ssget))
  (setq say (sslength ss))

  (setq c 0)
  (while (< c say)
    (setq tek (ssname ss c))
    (setq ltek (cdr (assoc 8 (entget tek))))
    (if (= lrobj ltek)
      (command "_.chprop" tek "" "LA" lrobj2 "")
      (progn)
    )
    (setq c (+ c 1))
  )

  (rsv)
)

18.07.2014 15:54    

brolin59
Alıntı
Travaci :
brolin59 napıcaksın ? busefer her layer için ayrı kodmu yazıcaksın ?
Linkte ki ChLyr isimli fonksiyon sana göre.



Ben yeni öğrenmeye başladığım için ihtiyacım kadarını soruyorum ve gerisini çözmeye çalışıyorum. Benim öğrenme şeklim böyle. O yüzden sorum saçma gelmiş olabilir sana fakat gittiğim sonuca bakarsan dediğin gibi birşey yapmayı amaçlamadığımı göreceksin. İyi günler.

18.07.2014 18:44    

Travaci
Yok hayır saçma gelmedi, sen yanlış anladın sanırım beni. İstediğin lisple yukarıdaki birbirini tutmuyor. İsteğinde referans olarak bir layer göstermekten bahsetmedin. Böyle oluncada her layer için ayrı yod yazıcağını düşündüm. Relax ; ) yada öyle demeyi kastettiysende ben kodlardan çıkaramadım.

19.07.2014 03:02    

ProhibiT
Kod:

(defun ssv (/)
   (setvar "cmdecho" 0)
   (command "_.undo" "group")
)
(defun rsv (/)
   (command "_.undo" "e")
   (setvar "cmdecho" 1)
   (prin1)
)
;;; Tek bir kere kullanılacak hiç bir bölümü altyordam işlevi
;;; (subroutine function) olarak tanımlamayınız.
;;; Kodları aldığınız kaynakta çok sayıda işlev tanımında kullanıldığı için
;;; Öyle yazılmıştır.

(defun C:mml (/ e)
;;; başka işlevlerde kullanılmayacak tüm değişkenler,
;;; yerel değişken (local variable) olarak tanımlanmalıdır.
;;; burada hiç kullanılmamış e isimli değişkenin
;;; yerel değişken olarak tanımlanması yanlıştır.
;;; farketmiyor, yazmasamda çalışıyor yaklaşımı yanlıştır.
;;; eninde sonunda hata olarak size dönecektir.
   (ssv)

   (setq robj (entsel "\nLayer'ı değiştirilecek objeyi seçiniz : "))
;;; Nesne seçerken tıklanan nokta koordinatlarına ihtiyacımız olmadığı için,
;;; daha seçerken (car (entsel kullanılmalı
   (setq lrobj (cdr (assoc 8 (entget (car robj)))))

   (setq robj2 (entsel "\nLayer'ı Alınacak objeyi seçiniz : "))
   (setq lrobj2 (cdr (assoc 8 (entget (car robj2)))))
;;; birbirini izleyen (setq direktiflerini ayrı ayrı yazmak kodlamayı uzatır,
;;; karışık bir görüntüye sebep olur. Tek bir setq direktifiyle yazılmalıdır.

   (print "Tüm çizimi seçin : ")
   (setq ss (ssget))
;;; "tüm çizimi seçin" mesajından sonra (ssget) kullanmak yerine
;;; doğrudan (ssget "x") kullanılması daha doğrudur.
;;; Ki; buna gerek var mı?

   (setq say (sslength ss))
   (setq c 0)
;;; Hiç ihtiyacımız olmayan 2 değişken tutulması
;;; 2 ayrı setq kullanılarak yazılması yanlış olmuş.

   (while (< c say)
     (setq tek (ssname ss c))
     (setq ltek (cdr (assoc 8 (entget tek))))
     (if (= lrobj ltek)
       (command "_.chprop" tek "" "LA" lrobj2 "")
       (progn)
     )
     (setq c (+ c 1))
;;; Konuyla ilgisiz not: Döngü sayaçlarını (loop counter)
;;; Döngünün sonunda artırmak, hem fazladan bir satır yazmak demektir,
;;; hem de kolaylıkla hataya sebep olabilecek acemice bir biçimdir.
   )
;;; Önce tüm çizim nesnelerinin seçilmesi,
;;; sonra while döngüsü içinde layer'larının kontrol edilerek
;;; işleme alınmalarına gerek yok.

   (rsv)
)

Eleştirdiğimiz noktaları göz önüne alarak yeniden yazarsak;
Kod:

(defun C:mmL (/ LRObj LRObj2 ChObj)
   (setvar "cmdecho" 0) (command "_.undo" "group")
;;; yazdığımız açıklamalar ışığında
;;;  (setq robj (car (entsel "\nLayer'ı değiştirilecek objeyi seçiniz : "))
;;;        lrobj (cdr (assoc 8 (entget robj)))
;;;        robj2 (car (entsel "\nLayer'ı Alınacak objeyi seçiniz : "))
;;;        lrobj2 (cdr (assoc 8 (entget robj2))))
;;; şeklinde yazılabilecek bu bölümün doğru yazılışı;
  (setq LRObj (assoc 8 (entget (car (entsel ....))))
        LRObj2 (cdr (assoc 8 (entget (car (entsel ....)))))
;;; şeklinde olur böylece kullanmayacağımız 2 değişken tutmamış oluruz.
        ChObj (ssget "x" (list LRObj)))
  (command "_.ChProp" ChObj "" "La" LRObj2 "")
  (command "_.undo" "e") (setvar "cmdecho" 1) (princ))

İşlemden temiz bir çıkış için (princ) ile bitirmekte fayda var.
Öğrenirken böyle yazabilirsiniz elbette. Ama böyle bir işlem için bu kadar uzun kod yazmaya, bunca değişken tutmaya hiç gerek yok.
Kod:

(defun C:mmL  (/)
  (command "._ChProp"
    (ssget "x" (list (assoc 8 (entget (car (entsel
                          "\nLayer'ı değiştirilecek objeyi seçiniz : ")))))) ""
    (cdr (assoc 8 (entget (car (entsel
                          "\nLayer'ı Alınacak objeyi seçiniz : "))))) ""))

Şeklinde yazmak her bakımdan daha doğrudur. Sözün özü, Travacı arkadaşımızın söylediği doğrudur. ChLyr fonksiyonundan tek farkı, belirlenen Kaynak Layer'daki Nesnelerin tümünün seçiliyor olmasıdır.

Bir başka detaydan daha söz etmekte fayda var.
Kodları yazarken, değişken isimlerinde Büyük harf ve Küçük harfleri birlikte kullandığımız dikkatinizi çekmiştir. Bunu şekil olsun diye yapmıyoruz. Örneğin; değişken adlarındaki L harflerini küçük yazarsanız, büyük "ı" harfleriyle karışırlar. göz yanılması sonucu hatalara yol açabilirler.

Burada bahsettiğimiz ipuçlarının çok daha fazlasını kitabımızda bulabilirsiniz. Biz yazmaya üşenmedik, lütfen okumaya üşenmeyiniz.

Kitabımızdan bir alıntı yaparsak;
"Bu şekilde gereksiz değişkenler oluşturmak, yazana, bilgisayarın işlemci ve belleğine, bunların yanında AutoLISP Çevirici ve Değerlendiricisine işkence etmekten başka hiç bir işe yaramaz. Üstelik program kodu gereksiz yere çok uzadığından takip edilebilirliği ve anlaşılabilirliği son derecede azalır. “Canım böyle istedi, nasılsa aynı sonucu elde ediyorum” şeklinde yanlış düşünceye kapılmamak gerekir. Bu tür yanlış alışkanlıkların eninde sonunda hata olarak size döneceğinden emin olabilirsiniz. AutoLISP yazarken, daha başlangıçta düzgün, mantıklı bir üslup edinmek en doğru yaklaşımdır.

Birbirini takip eden setq işlemlerini ayrı ayrı yazmaktansa bir tek setq işlevi altında topluca yazmak her durumda daha doğrudur."

19.07.2014 13:21    

brolin59
Alıntı
Travaci :
Yok hayır saçma gelmedi, sen yanlış anladın sanırım beni. İstediğin lisple yukarıdaki birbirini tutmuyor. İsteğinde referans olarak bir layer göstermekten bahsetmedin. Böyle oluncada her layer için ayrı yod yazıcağını düşündüm. Relax ; ) yada öyle demeyi kastettiysende ben kodlardan çıkaramadım.



:) Çok relax yazmıştım zaten. Kendimi doğru anlatabilmek için yazdım :) İstediğimde referans olarak bir layer göstermekten bahsetmemiştim çünkü o kısmını yapabileceğimi düşündüm :-) Yani kısa lafın özü gerektiği kadar soru sordum diyelim :)

19.07.2014 13:28    

brolin59
ProhibiT çok teşekkür ederim. Şu anda

https://cizimokulu.com/indir/Lispler/lsp/autolisp.swf

Bu linkteki bilgileri okuyorum. zaten başka türlü öğrenmek pek mümkün değil seninde belirttiğin gibi. Tavsiyelerini de hemen not ettim. Nickimin altında yazan "Acemi" yazısından da belli olacağı gibi daha acemiyim :) Kodlardan alıntı yaparak onları çözmeye ve kendime göre uyarlamaya çalışıyorum. Sonra oturup tekrar kendim yazmaya çalışıyorum. Bunu kaç kere yazmaya çalıştım bilsen :) Sonunda o kadarı çıkabildi şimdilik :) Anlamadığım yerleri belki işe yarıyodur diye koydum işin gerçeği :) Ama öğrenicem inş. :) Böyle böyle olcak. Tüm yorum yazan arkadaşlara teşekkür ederim.

21.07.2014 14:58    

brolin59
Yukarıda yazmış olduğunuz uyarıları anlamak için tekrar ve tekrar okudum. Birkaç sorum olacak. Cevaplarsanız sevinirim.

1 - While döngüsü için yazdığınız uyarıyı anlayamadım. Heryerde bu şekilde uygulama gördüğüm için öyle yapmıştım. Doğrusunu öğrenmek isterim. Aklıma repeat kullanmak geldi. Açıklarsanız sevinirim.

2 - Değişkenleri tanımlıyorum artık.(kopya kod alsamda kullanıp kullanmadığımı kontrol ediyorum. ezbere gitmiyorum) Sanırım değişkeni defundan sonra tanımladığımda lispten çıktığımızda değişkenler hafızada kalmıyor. Birkaç yerde şöyle birşey gördüm. Örneğin;

(Defun c: zzz (a b c / d e f)
.....

gibi. Burada değişkenin "/" işaretinin solunda yada sağında kalması neyi ifade ediyor?

3 - command komutunu kullanarak autocad komutları ile birçok şey çizebiliyoruz lisp yardımı ile. command kullanmak doğrumudur yada hataya sebebiyet verebilir mi? Farklı bir yolun daha iyi olduğunu düşünüyorsanız pt1 noktasından pt2 noktasına line çizmek için kullanabileceğimiz daha sağlıklı bir komutun örneğini verebilirmisiniz? Ben şöyle yaptım mesela;

(command "._line" pt1 pt2 "")

21.07.2014 18:33    

ProhibiT
1-
Kod:

.
(setq SecimSeti (ssget)
      n (sslength SecimSeti))
(while (> (setq n (1- n)) -1)
  (redraw (ssname SecimSeti n) 3))
.

Döngü sayacını başlangıçta artırıp/eksiltip kontrol etmek hem daha kısa hem de daha verimlidir.

2- "/"'ın solunda kalanlar fonksiyonun parametreleri (beklediği değerler) dir. Sağında kalanlar ise yerel değişkenler (local variables)

3-
Kod:

(entmake (list (cons 0 "LINE") (cons 10 p1) (cons 11 p2))

> 1 <
Copyright © 2004-2022 SQL: 1.619 saniye - Sorgu: 77 - Ortalama: 0.02102 saniye