28.05.2021 12:28    

ProhibiT
Merhaba,

Mümkün elbette.
İstenen işlem tam olarak nedir?
Tıklanarak seçilen Block ile aynı Layer ve (seçilen block ile aynı) isimdeki Block'lar mı işleme alınacak...
Yoksa, seçilen Block ile aynı Layer'da olan tüm Block'lar mı?

Aslına bakılırsa, sorunun doğru cevabını verirken (yani istenen işlemi tanımlarken) göreceksin ki, yazması o kadar zor değil.

28.05.2021 12:51    

k005
@ProhibiT



Hocam şöyle sadeleştireyim :

- objeyi seçtiğimde ( ki bu obje bloktur.) kolon layerına mensup olanlar seçilmelidir.
- akabinde colordialog ile rengi belirleyeceğiz.

k005 (01.06.2021 12:08 GMT)

31.05.2021 08:27    

ProhibiT
Merhaba,
2009 yılında paylaştığımız, arkadaşlardan gelen istekler üzerine kısa sürede 3 ayrı sürümünü yazdığımız... gene aynı yıl içinde "Yeter artık, bu konunun suyunu çıkardık" yorumunu yaptığım konuyla ilgili yeni bir paylaşım yapmak istiyorum.

Aradan geçen (yaklaşık) 12 yıldan sonra, suyunu çıkardığımız konusunda hala aynı fikirde sabit olmakla birlikte, Ertan arkadaşımızın işi görülsün (hoş, AutoCad içinde bunu kolaylıkla yapabilir, bu şekilde Lisp ile yapmak daha keyifli geliyor anlaşılan) ve diğer yandan da, özellikle yazar (ve yazar olmak isteyen) arkadaşlarımıza, kitabımda ve sitemizde bıkmadan usanmadan anlatmaya çalıştığım bazı temel kavramları bir kere daha hatırlatmak amacıyla paylaşıyorum.

Kod:

;|===========================================================================|
| Seçilen örnek block'tan algılanan Layer'da bulunan tüm Block'lar (Insert) |
| sırasıyla ele alınarak Block Tanımında (Definition) yer alan nesnelerin   |
| rengi belirlenen Renk ile değiştirilir.                                   |
|                                   Hazırlayan: M. Şahin Güvercin           |
|                                   31/05/2021 www.cizimokulu.com           |
|___________________________________________________________________________|;
(defun c:BLCLr (/ LyR BLock BLockLar n Renk BlockName BLockDef BLockEnt SubObj)
;_____________________________________________________________________________;
  (defun *error* (ocmd / er)
    (if (and (member er '("Function cancelled" "quit / exit abort"))
             (= (logand (getvar "undoctl") 8) 8))
      (progn (command-s "_.undo" "e")  (setvar "cmdecho" ocmd)))
    (princ (strcat "\n" er)) (setq *error* oeRr) (prin1))
;_____________________________________________________________________________;
  (setq oeRr *error*) (setq ocmd (getvar "cmdecho"))
  (setvar "cmdecho" 0) (command "_.undo" "group")
  (if (= "INSERT" (cdr (assoc 0 (entget (setq BLock (car (entsel
            "\Rengi değişecek Block'ların Layer'ında bir Block seçiniz")))))))
    (setq LyR (cdr (assoc 8 (entget BLock))))
    (princ "\nSeçtiginiz obje bir BLock değildir, yeniden deneyiniz..."))
  (setq BLockLar (ssget "x" (list (cons 0 "INSERT") (cons 8 LyR)))
        n (sslength Blocklar))
  (while (> (setq n (1- n)) -1)
    (if (not Renk) (setq  Renk (acad_colordlg 0)))
    (setq Block (ssname BlockLar n)
          BlockName (cdr (assoc 2 (entget BLock)))
          BLockDef (tblsearch "BLock" BLockName)
          BLockEnt (cdr (assoc -2 BLockDef)))
    (while BLockEnt
      (setq SubObj (entget BLockEnt))
      (if (assoc 62 SubObj)
        (setq SubObj (subst (cons 62 Renk) (assoc 62 SubObj) SubObj))
        (setq SubObj (append SubObj (list (cons 62 Renk)))))
      (entmod SubObj) (entupd (cdr (assoc -1 SubObj)))
      (setq BLockEnt (entnext BLockEnt))) (entupd BLock))
  (setq *error* oeRr) (command "_.undo" "e") (setvar "cmdecho" ocmd) (prin1))


Yazdığınız kod içinde bir nokta bile fazlalık olmamalı (elbette bir noktası bile de eksik olmamalı). Hocam, "Ne zararı var, ben böyle alıştım" diyenlere ben de bir soru soruyorum; "Ne gereği var?"

Fonksiyon tanımında (başka fonksiyonlarda ihtiyacınız olsa bile) değişkenlerinizi Local Variable (Yerel Değişken) olarak tanımlayınız. Buradaki örnekte Renk değişkenini Local olarak tanımladığımız için, (if (not Renk) ... ifadesinden önce (setq Renk nil) gibi anlamsız bir değer atama (ya da boşaltma) işlemine gerek kalmayacaktır.

Gene aynı örnek ifadeden yola çıkarsak; (if (not (= Renk nil) ...) veya (if (/= Renk nil)...) gibi bir ifadeye ne gerek var! Daha da ileri derecede gereksiz işlemler gözüme ilişiyor çok sayıda; (if (= Renk nil) ... (progn ) ...) biçiminde yazıldığını da görüyorum. Bu kadar uzatmaya, programa bu kadar zulmedip yormaya ne gerek var.

Yazdığınız kodlarda, kendi yazdıklarınız bile olsa, sorgusuz sualsiz kalıplara mahkum etmeyin kendinizi. Bunu söylerken zaman zaman ben de düşüyorum bu hataya. Gene buradaki örnekte (büyük ihtimalle dikkat çekmeyen bir durumdan bahsetmekte yarar var. Yazdığımız hemen tüm kodlarda, sanki Lisp Fonksiyonun besmelesi gibi her şeyden önce yazıverdiğimiz (vl-load-com) ifadesini yazmadım burada. Çünkü bu fonksiyonda, vl-, vla-, vlax- veya vlr- ile başlayan Visual Lisp Eklentisi olan hiç bir komut kullanılmıyor. "Ne zararı var" diyenlerin kulağını çınlatmak için, Uç noktada bir örnek olması bakımından kasıtlı olarak böyle yazdım.

Hata yakalama (Error Trap) işlevine gelince; yukarıda yazdıklarım burada da geçerli. Genelde yazar arkadaşlarımız, bir tek Undo kapatılmadığı durumlarda hatayla karşılaştıklarından; hata yakalama işlevini yalnızca 'undo end' yapmaya indirgiyor zihinlerinde. Gene hiç düşünmeden, cmdecho'yu kapattığınızda... belki sizin fonksiyonunuz daha bir profesyonelce (bu arada amatör profesyonelden daha az yetkin değildir, sadece o işten para kazanmayana amatör diyoruz) görünüyor. Kullanıcı da karşılaştığı aksaklığın farkında/veya değil, bunun sizden kaynaklandığını bilmiyor diye, göz ardı etmemelisiniz. Gene bu hata yakalama işlevleri için internet ortamında yaygın olan kalıpları da sorgulamanızı tavsiye ederim. Bazı örneklerde olduğu gibi push-error ve pop-erro ile errror status durumunu saklayıp, oradan almasını da bildiğim halde neden yapmadım acaba?

Hem kullanıcı hem de yazar arkadaşlarımızı ilgilendiren bir konu var. Fonksiyonun açıklama kısmında da (kısaca) belirttiğim (pek çok yerde inat ve sabırla anlattığım) gibi, Block diye genelleyip geçtiğimiz AutoCAD nesneleri; Block Definition ve Block Reference (ki veritabanında INSERT nesnesi olarak yer alırlar) olmak üzere iki türlüdür. Adları üstünde, bunları kavram olarak birbirine karıştırmamak, yerli yerinde kullanmakta büyük fayda var.

Selam ve saygılarımla herkese kolaylıklar dilerim.

Not: Ele alınan konuyu daha açık ifade etmesi bakımından konu başlığı tarafımdan değiştirildi.
Alumina arkadaşımızın uyarısı üzerine açıklama gereği duydum. vl- komutları Visual Lisp Eklentisi olmakla birlikte bunlar vl-load-com yüklenmeden de kullanılabilir.

ProhibiT (31.05.2021 11:27 GMT)

01.06.2021 11:58    

k005
@ProhibiT

Hocam evet lispler ile çalışmak keyifli + bazen başka işlemlerle combin de yapmak gerekebiliyor, lisp isteği birazda bu yüzden.

* yine güzel bir çalışma . Çok Teşekkür ediyorum.

* suyunu çıkarma konusunda sizinle aynı fikirdeyim . . iyice yani.. :)

04.03.2022 11:12    

baha07
merhaba ,
lisp kusursuz calisiyor . ve buyuk kolaylik sagliyor . emeginize saglik .
kullananlar icin dikkat edilmesi gereken konu -
blok icindeki nesnelerin renkleri index color (ACI) ile verilmisse lisp sorunsuz calisiyor .
fakat nesne renkleri True color (RGB color ) renkleri ile verilmisse (orn 255,0,0) , nesnelerin rengini yeni sectigimiz renge degistiremiyor - yeni renk secme kisminda sadece index color (ACI) renk duzeninden secilebiliyor , sanirim renkleri RGB den ACI renk koduna ceviremiyor

04.03.2022 19:15    

alumina
Alıntı
baha07 :

Yormayin Sahin Hocamizi..

2. while icerisinde;

bunun yerine;
Kod:

(setq SubObj (entget BLockEnt))

bunu yazin;
Kod:

(setq SubObj (vl-remove-if '(lambda(a)
  (or (= (car a) 420) (= (car a) 430)))
    (entget BLockEnt)))

istediginizi yapacaktir..

06.03.2022 08:50    

ProhibiT
Merhaba Adem Ercan (alumina),

Beni düşünüp "yormayın..." dediğin için teşekkür ederim.
Yalnız, "yorulmak" diye bir kavramın sözlüğümüzde olmadığını bilenlerden olduğunu sanıyordum. Başkaları bir bardak suda fırtına koparamazken, çay kaşığında transatlantik yüzdürülen bu yerde, K005 arkadaşımızla "iyice suyunu çıkardık..." derken, cehennemin kapağını sen açtın! Ben de odun atmaz mıyım o cehenneme. Ne yapalım sen istedin, ateşi harlamak şart oldu. :)

İlk paylaşımda açıkladığım temel ilkelerden vaz geçmeden, öncelikle *error* fonksiyonunu daha net ve kararlı hale getirdim. baha07 arkadaşımız haklı aslında. Bu haklı mesajıyla cehennemin kapağının açılmasına neden olduğu ve beni onca odunu taşımak zoruda bırakıp yorduğu için şiddetle kınıyorum. :)

Eskiden AutoCAD'de renkler ACI (AutoCAD Color Index) sisteminde, 0 ile 256 arasında (0= ByBlock, 256=ByLayer, 1'den 255'e kadar olanlarda değişik renkleri gösteren) tamsayılarla ifade ediliyordu. Sonraları "True Color", "PANTONE®", "RAL™ Classic", "RAL Design color books" ve "DIC® Color Guide" renk sistemleri o kadar ustalıklı bir şekilde AutoCAD'e eklendi ki, her ne kadar biraz karışık gibi görünse de, hem kullanıcının hem de yazarların istekleri tam olarak karşılandı.

AutoCAD Nesne Renklerini 3 grupta ele alıyor. 1- ACI (AutoCAD Color Index), 2- True Color ve 3- Color Books. True Color renk sistemi RGB (Red-Green-Blue) veya HSL (Hue-Saturation-Luminance) renk bileşenlerinin oranlarını ayarlayarak istenen rengi elde etme yöntemidir. Color Books sisteminde ise üretimde kullanılan Pantone, RAL ve DIC katalog renkleri kullanılabilir. Hatta istenirse uygun yöntemle özel renk kartelaları bile yüklenerek kullanılabilir.

ACI döneminde Acad_ColorDlg ile ulaşıyorduk.



Yukarıda paylaştığımız Lisp kodlarındaki gibi, (acad_colordlg RenkNo) şeklinde çağırıyorduk. Girişte verdiğimiz RenkNo tamsayısı mevcut (yada ön seçili) rengin numarasını ifade ediyor, geri dönen 0 ile 256 arasında tamsayı bir değer oluyordu. Bunu da Entity List'te 62 koduyla işliyorduk.

True Color ve Color Books döneminde ise Acad_TrueColorDlg ile ulaşılabiliyor.



Aşağıda paylaşılan Lisp kodunda olduğu gibi, (Acad_TrueColorDlg ScLiRenk) şeklinde çağırıyoruz. Girişte verdiğimiz ScLiRenk değeri; ön seçili renk ACI ise, (62 . RenkNo), renk karışımı (RGB veya HSL) ise (420 . 3068369) biçiminde noktalı çift, Color Books kullanırken de (430 . "DIC COLOR GUIDE(R)$DIC 27") şeklinde 430 anahtarlı noktalı çift oluyor.

Geri dönen Liste ise yaptığımız seçimin türüne göre değişiyor. ACI seçilince ((62 . RenkNo)) 62 anahtarlı tek elemanlı bir liste; RGB/HSL (Renk Karışımı) seçilince ((62 . RenkNo) (420 . 3068369)) şeklinde 2 elemanlı bir liste; Color Books'tan seçim yapılınca ((62 . RenkNo) (420 . 3068369) (430 . "DIC COLOR GUIDE(R)$DIC 27")) şeklinde 3 elamanlı bir liste elde ediliyor. acad_truecolordlg işleminden dönen listenin eleman sayısından (uzunluğundan, length) seçilen rengin hangi sistemde olduğu doğrudan sorgulanabilir. Listedeki eleman sayısı (listenin uzunluğu) 3 ise Color Books, 2 ise True Color, 1 ise ACI sisteminde renk seçimi yapılmıştır. 430'lu dönüşte yer alan 420'li değer seçilen renge en yakın (neredeyse aynı) RGB karışımını, 62'li değer ise ACI'te olabilecek en yakın rengi ifade ediyor. Benzer şekilde 420'li dönüşte yer alan 62'li değer seçilen renk karışımına en yakın ACI rengini ifade ediyor. Bir nesnenin rengi değiştirilirken, diyalog kutusundan dönen listenin tamamı kullanılıyor, Entity listesine işleniyor. Bununla birlikte Entity List'te nesnenin rengini belirleyen, listede yer alan anahtar numarası en büyük değer (62 < 420 < 430) oluyor.

Bu açıklananlar ışığında, Varlık Listesi'nin 420 ve 430 anahtarlı elemanlarını yok ederek, her şeyi ACI renk sistemine indirgemek, "Benden ırak, cehenneme direk!" demek gibi geldi. Bunun yerine hem mevcut renkte hem de hedef renkte AutoCAD'de mevcut tüm sistemlerin kullanılabileceği şekilde yazmayı tercih ettim.
Kod:

;|===========================================================================|
| Seçilen örnek block'tan algılanan Layer'da bulunan tüm Block'lar (Insert) |
| sırasıyla ele alınarak Block Tanımında (Definition) yer alan nesnelerin   |
| rengi belirlenen Renk ile değiştirilir.                                   |
|                                   Hazırlayan: M. Şahin Güvercin           |
|                                   31/05/2021 www.cizimokulu.com           |
| Düzenleme: Truecolor'dan ve TrueColor'a renk değiştirme eklendi.          |
|                                                      05/03/2022           |
|___________________________________________________________________________|;
(defun c:BLCLr (/ *error* LyR BLock BLockLar n Renk BLockDef BLockEnt SubObj)
;_____________________________________________________________________________;
  (defun *error* (er /)
    (if (and (member er '("Function cancelled" "quit / exit abort"))
             (= (logand (getvar "undoctl") 8) 8))
      (progn (command-s "_.undo" "e")  (setvar "cmdecho" ocmd)))
    (princ (strcat "\n" er)) (prin1))
;_____________________________________________________________________________;
  (setq ocmd (getvar "cmdecho")) (setvar "cmdecho" 0)
  (command "_.undo" "group")
  (if (= "INSERT" (cdr (assoc 0 (entget (setq BLock (car (entsel
            "\rRengi değişecek Block'ların Layer'ında bir Block seçiniz")))))))
    (setq LyR (cdr (assoc 8 (entget BLock))))
    (princ "\nSeçtiginiz obje bir BLock değildir, yeniden deneyiniz..."))
  (setq BLockLar (ssget "x" (list (cons 0 "INSERT") (cons 8 LyR)))
        n (sslength Blocklar))
  (while (setq Block (ssname Blocklar (setq n (1- n))))
    (setq BLockDef (tblsearch "BLock" (cdr (assoc 2 (entget BLock))))
          BLockEnt (cdr (assoc -2 BLockDef))
          SubObj (entget (entnext BlockEnt))
          ScLiRenk (cond ((assoc 430 SubObj) (assoc 430 SubObj))
                         ((and (not (assoc 430 SubObj)) (assoc 420 SubObj))
                          (assoc 420 SubObj))
                         ((and (not (assoc 420 SubObj)) (assoc 62 SubObj))
                          (assoc 62 SubObj))
                         ((not (assoc 62 SubObj)) 0)))
    (if (not Renk) (setq  Renk (Acad_TrueColorDlg ScLiRenk)))
    (while BLockEnt
      (setq SubObj (entget BLockEnt)
            SubObj (vl-remove-if '(lambda(Rn)
             (or (= (car Rn) 62) (= (car Rn) 420) (= (car Rn) 430))) SubObj)
            SubObj (append SubObj Renk)
            SubObj (entmod SubObj)
            SubObj (entupd (cdr (assoc -1 SubObj)))
            BLockEnt (entnext BLockEnt)))
    (entupd BLock))
  (if (= (logand (getvar "undoctl") 8) 8) (command "_.undo" "e"))
  (if ocmd (setvar "cmdecho" ocmd)) (prin1))


Önceki paylaşımımızdaki temel prensipleri bir kere daha hatırlatıp, buradaki bazı ayrıntılara dikkat çekmek isterim.
Block tanımı altındaki nesnelerin önce mevcut renk bilgileri kaldırıldı, sonra yapılan seçime göre yeni renk değerleri Varlık Listesi'ne eklenerek Nesne (veritabanında ve ekranda) güncellendi.

İlk while döngüsünde, işleme alınacak block sayısı (n) hesaplanmakla birlikte bunun bir döngü sayacı olarak kullanılmadığına dikkat ediniz. while döngüsünün şartı, "bir şey varsa vardır, yoksa yoktur!" Varsa işlemi yap, yoksa işine bak sonraki bölüme doğru ikile... Böyle olağan üstü bir yöntem, bilinen yüksek seviyeli (ilkel) programlama dillerinin hiç birinde yoktur. Benzer şekilde burada kullandığımız cond, vl-remove-if, ayaküstü anonim fonksiyon tanımlamaya yarayan lambda ve bunun gibi pek çok fonksiyon başka dillerde yoktur. Bu nedenledir ki, Lisp yazarken, başka dillerden edindiğiniz alışkanlıklarla ufkunuzu karartmayınız, Lisp'i Lisp gibi yazmakta her zaman fayda var.

Bir diğer örnek cond bölümünde karşımıza çıkıyor. cond işlevi if'e benzemekle birlikte, şart'ı doğrulayan ilk ifadenin değeri ile geri döner. Örneğimizde Varlık Listesi'nde 430 varsa onu alır geçer. Yukarıda açıkladığımız gibi, 430 olunca bunun yanında 420 ve 62 de olacaktır, ama onlar bizi ilgilendirmez. Benzer şekilde 420 varsa bunun yanında var olan 62 bizi hiç ilgilendirmez, biz en büyük anahtar değerli ifadeyi arıyoruz.

Kahin olmaya gerek yok, bu soru (veya istek) mutlaka gelecektir; "İlgili Layer'daki bütün Block'ları (Insert) aynı renge çeviriyor... her block için başka bir renk seçilemez mi?" diye. Çok kolay bir işlem olmasına rağmen bunu yazmayacağımı şimdiden ifade edeyim. Ev Ödevi kabul edenlere, (if (not (Renk)) ... ifadesindeki şartı kaldırdıklarında neler olacağını deneyip görmelerini tavsiye ederim.

Selam ve saygılarımla herkese kolaylıklar dilerim.

Düzenleme: Lisp kodlarında
SubObj (append Renk SubObj) satırı
SubObj (append SubObj Renk) olarak değiştirildi

ProhibiT (08.03.2022 11:36 GMT)

07.03.2022 09:05    

baha07
merhaba ProhibiT abi ,
tum emeginiz , zamaninizi ayirdiginiz ve en onemlisi yorulmayip uzun uzun yazdiginiz aciklama yaziniz icin ayri ayri tesekkur ederim .
------
blok icerisindeki taramalarin rengini degistirmiyordu . bu kadar emege mizmizlanmak istemememistim
bu yaptiginiz duzenlemeyle sorun cozulmus

bir kez daha tesekkur ederim . neden bu lisp ile bu kadar ilgileniyorum . calistigim sistemde projeler revitten dwg ye donusturulmekte ve revitte her cizilen aile katmanlarini blok olarak dwg icerisine geciriyorlar . bende dwgleri duzenlerken ihtiyac duyuyorum .

Düzenleme: Lisp kodlarında
SubObj (append Renk SubObj) satırı
SubObj (append SubObj Renk) olarak değiştirildi

baha07 (17.03.2022 07:26 GMT)

Copyright © 2004-2022 SQL: 0.954 saniye - Sorgu: 70 - Ortalama: 0.01363 saniye