Ik ben aan mijn eerste lisp-programma begonnen.
Het zal wel lang duren, maar dat is denkik de enige manier om het te leren.
Nu zoek ik het volgende commando.
Via een lisp selecteer ik eerst een window en in dit window staan karakters.
Nu moeten deze karakters de "naam" worden van blocks die ik aan wil maken.
Hoe kan ik via lisp iets selecteren en dit gebruiken
als "blockname"?
groet, martin
nieuw de inhoud van 1 tekststring als blocknaam gebruiken is goed te doen
maar een aantal strings tot 1 naam omvormen dat lijkt me nog al een klus (tenzij de naam volstrekt willekeurig mag zijn)
Bart schreef:
Citeermaar een aantal strings tot 1 naam omvormen dat lijkt me nog al een klus (tenzij de naam volstrekt willekeurig mag zijn)
Als je de tekst regels in de goede volgorde selecteerd heb je een lijst van die inhoud van die regels die je met de LISP opdracht "strcat" tot een (1) zin (lees naam) kunt omvormen.
Selecteer je de tekst met een window dan heb je een "willekeurige" lijst.
Deze kun je sorteren op bijvoorbeeld de x-coordinaat.
Citaat van: bartnieuw de inhoud van 1 tekststring als blocknaam gebruiken is goed te doen
maar een aantal strings tot 1 naam omvormen dat lijkt me nog al een klus (tenzij de naam volstrekt willekeurig mag zijn)
Het is één tekststring van max. 4 karakters; dit is dus goed te doen, maar hoe?
Aangezien je wilt leren programmeren met LISP het volgende:
Maak vanuit de Visual Lisp Console een selectie van een block.
(setq MijnBlok (ssget))
Dubbelkik daarna op de variabelenaam MijnBlok.
De naam wordt oranje. Klik nu met je rechter muisknop hierop en kies Inspect.
Er verschijnt een inspectievenster. Dubbelklik op entity naam en er verschijnt weer een inspectie venster metr meer gegevens.
Klik weer op entity naam en kies inspect raw data.
Nu krijg je (een deel van) de dxf data van het gekozen blok, waaronder ook de naam.
Met behulp van assoc en entmod, entupd e.d. kun je nu de naam veranderen.
DUS: je maakt een blok aan met een standaard naam en vervangt dan de naam door jouw, uit tekst geconstrueerde, naam.
OF je werkt met de command instructie van lisp. Hiertoe moet je eerst goed opschrijven wat het commando "-wblock" precies doet, net als in een script.
Dit lijkt misschien eenvoudiger maar de kans op bugs is veel groter.
bedankt, maar ik wacht wel totdat er wat meer lessen op deze catsite staan.
groetjes, Martin
just be patient
kan niet wachten.
ik zoek zoiets als
(setq a (getstring (278,315 236,303)))
(command "-block" "a" "337.5,300" "w" "0,553.5" "337.5,300" "")
waarbij a de naam block is, deze haalt hij uit het window van de opgegeve coordinaten.
maar hoe selecteer ik eigenlijk een string? dat kon ik nog niet
in de lessen vinden.
(setq a (ssget "_W" '(0 553.5) '(337.5,300) '(( 0 . "TEXT"))))
(setq a (cdr (assoc 1 (entget (ssname a 0)))))
Let erop dat je het juiste aantal haakjes openen en sluiten hebt.
hij loopt vast bij insertion point. wat is fout?
(defun c:tttt ( / a pt0 pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pt9 pt10 pt11 pt12)
(setq a (ssget "_W" '(279 323) '(337.5 300) '(( 0 . "TEXT"))))
(setq a (cdr (assoc 1 (entget (ssname a 0)))))
(setq pt0 278)
(setq pt1 315)
(setq pt2 615)
(setq pt3 62)
(setq pt4 236)
(setq pt5 303)
(setq pt6 573)
(setq pt7 337.5)
(setq pt8 300)
(setq pt9 279)
(setq pt10 323)
(setq pt11 (list pt7 pt8))
(setq pt12 (list pt9 pt10))
(command "-block" a (pt11) w (pt12) (pt11) "")
)
(defun c:tttt (/ ;a pt0 pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pt9 pt10 pt11 pt12
)
(setq a (ssget "_W" '(279 323) '(337.5 300) '((0 . "TEXT"))))
(setq a (cdr (assoc 1 (entget (ssname a 0)))))
(setq pt0 278)
(setq pt1 315)
(setq pt2 615)
(setq pt3 62)
(setq pt4 236)
(setq pt5 303)
(setq pt6 573)
(setq pt7 337.5)
(setq pt8 300)
(setq pt9 279)
(setq pt10 323)
(setq pt11 (list pt7 pt8))
(setq pt12 (list pt9 pt10))
(command "-block" a pt11 "w" pt12 pt11 "")
) ;_ end of defun
;|«Visual LISP© Format Options»
(100 2 40 2 T "end of " 80 9 0 0 nil T T nil T)
;*** DO NOT add text below the comment! ***|;
In de "command" regel moet je alle aanwijzingen voor het commando (zoals selecteren m.b.v. een window) tussen aanhalingstekens zetten, dus: niet w maar "w".
Als je een variabele gebruikt op de command line dan moet je deze (meestal) tussen haakjes zetten.
:!: Maar niet in AutoLisp! :!:
PS
:wink:
Je moet de punt-komma voor de variabelen weer even weghalen.
Dit heb ik gedaan om de code te kunnen debuggen.
YES !!!!!!! THANKS !!!
Nu moet ik dit tig keer herhalen op verschillende coordinaten.
Dus een loop met een teller.
Waar kan ik basis/principe instrukties vinden over loops?
groetjes,Martin
Zoals altijd in de help functie van Visual LISP
Ik raad je aan om de coordinaten in een lijst te stoppen en dan met de while en de nth functie de zaken af te handelen.
Denk er wel aan dat de index van het eerste element in een lijst 0 is.
:?: Vraagje:
Liggen deze coordinaten vast of moet je die elke keer bepalen?
In het laatste geval kun je beter de coordinaten kiezen met de muis, want dan ben je vlugger klaar en kun je de functie herhalend opbouwen rondom de getpoint functie. :roll:
Geen idee hoe je dan nth moet toepassen.
herhaalt de while functie zich automatisch of moet je op het eind terugverwijzen naar begin while functie.
ergens zag ik :
) ;_ end of while
maar als hij niks meer vindt, stopt hij toch vanzelf?
vraag 2.
(setq txtlst2 (acad_strlsort txtlst))
dit commande vond ik ergens in een lisp. Als ik dit gebruik sorteer hij
op tekst / eerste karakter niet op nummervolgorde. Kan dit wel?
bijv. 1, 2, 3, 15, 16, 22 sorteert hij op 1, 15, 16, 2, 22, 3
als je cijfers als tekst wilt sorteren moet je voorloop nullen gebruiken
dus 001 i.p.v. 1 dan kan je sorteren tot 999
als je de getallen als getallen behandeld is er volgens mij geen standaard sorteerfuntie voor (weet iemand er een dan hoor ik het ook graag)
en moet je aan de slag met sublijsten en de > (groter dan funtie)
werkwijze:
neem het eerste getal van de lijst en vergelijk die met de tweede
is deze groter ga dan verder met het tweede getal zo niet neem dan het eerste getal
plaats het kleinste getal in sublijst 1
herhaal dit tot je door de hele lijst heen bent (en dus het grooste getal hebt) en plaats het grootste getal in sublijst 2
vervang de hoofdlijst door sublijst 1
en herhaal alles
uiteindelijk is sublijst 2 op volgorde en kan je de hoofdlijst door sublijst 2 vervangen.
ps bij grote hoeveelheden kan dit afhankelijk van je systeem even tijd in beslag nemen
neem een regel op in de lus die bijvoorbeeld sublijst 2 afdrukt tijdens het debuggen van de lisp
en haal deze er uit als alles goed werkt omdat het constand uitvoeren naar het scherm de lisp behoorlijk vertraagt
Bart schreef:
Citeerals je de getallen als getallen behandeld is er volgens mij geen standaard sorteerfuntie voor (weet iemand er een dan hoor ik het ook graag)
De oplossing is simpel (nou ja :duivel1: ).
1) verander de lijst van getallen in een lijst van tekst.
itoa2) controleer of elk element uit minder dan (bijvoorbeeld) 5 tekens bestaat.
lambda of
nth3) zo ja voeg aan het begin genoeg nullen toe om er 5 tekens van te maken.
strcat4) sorteer de tekst lijst.
acad_strlsort5) converteer de tekest lijst naar een lijst van getallen.
atoiQED
ja dat is inderdaad een goede oplossing (met voorloop nullen :mrgreen: )
maar wel zo dat ze er alleen tijdelijk voor worden geplaatst.
Ik denk dat ik hem maar eens ga proberen
Normaal verdwijnen bij getallen de voorloopnullenvanzelf, doen ze dit niet dan maakt het nog niets uit want 00001 = 1 :lol:. Is toch zo?
Citaat van: JoopNormaal verdwijnen bij getallen de voorloopnullenvanzelf, doen ze dit niet dan maakt het nog niets uit want 00001 = 1 :lol:. Is toch zo?
Dat is waar maar er is binnen autocad geen funtie beschikbaar waarmee je cijfers als cijfers op je tekening zet
alles wat je ziet is tekst. (zelfs bij de maatvoering als je newtext gebruikt)
het onderscheid is alleen aanwezig tijdens het uitvoeren van een programma als je dus 00001 als waarde van een attribute opgeeft zal dit ook gewoon als 00001 op het scherm komen en niet vanzelf verdwijnen.
Ik kom hier morgen op terug.
Nu eerst naar de vrouw.
:D Het is wat later geworden dan beloofd, maar hier ben ik dan.
Om de nullen aan het begin van een "getal als tekst" weg te halen doe je het volgende.
Aan het begin van je LISP routine moet je (vl-load-com)
plaatsen. Hiermee maak je de Visual Lisp actief.
Vervolgens:
(vl-string-left-trim "0" "000125")
Dit geeft als resultaat "125".
Met de foreach of lambda functie kun je dit op elk element van de lijst toepassen. :lol:
ok bedankt.
Citaat van: Anonymous
vraag 2.
(setq txtlst2 (acad_strlsort txtlst))
dit commande vond ik ergens in een lisp. Als ik dit gebruik sorteer hij
op tekst / eerste karakter niet op nummervolgorde. Kan dit wel?
bijv. 1, 2, 3, 15, 16, 22 sorteert hij op 1, 15, 16, 2, 22, 3
Beste Gast,
In Visual LISP is er een functie VL-SORT die we goed sorteert.
Eerst moet U natuurlijk wel Visual LISP laden met de functie (vl-load-com), als u daarna bijvoorbeeld:
(VL-SORT '(2 1 5 7 6 16 3 3 22 3 3 25 4 8 11 9 14) '<) ingeeft
dan krijgt men:
(1 2 3 4 5 6 7 8 9 11 14 16 22 25)
Dubbelingen worden hierbij weg gelaten!
Groetjes HofCAD.
PS
(defun C:sorteer1()
(vl-load-com)
(setq txtlst2 '(2 1 5 7 6 16 3 3 22 3 3 25 4 8 11 9 14))
(VL-SORT txtlst2 '<)
;;dit geeft: (1 2 3 4 5 6 7 8 9 11 14 16 22 25)
)
(defun C:sorteer2()
(vl-load-com)
(setq txtlst2 '(2 1 5 7 6 16 3 3 22 3 3 25 4 8 11 9 14))
(VL-SORT txtlst2 '>)
;;dit geeft: (25 22 16 14 11 9 8 7 6 5 4 3 2 1)
)
HofCAD schreef:
Citeerdefun C:sorteer1()
(vl-load-com)
(setq txtlst2 '(2 1 5 7 6 16 3 3 22 3 3 25 4 8 11 9 14))
(VL-SORT txtlst2 '<)
;;dit geeft: (1 2 3 4 5 6 7 8 9 11 14 16 22 25)
)
(defun C:sorteer2()
(vl-load-com)
(setq txtlst2 '(2 1 5 7 6 16 3 3 22 3 3 25 4 8 11 9 14))
(VL-SORT txtlst2 '>)
;;dit geeft: (25 22 16 14 11 9 8 7 6 5 4 3 2 1)
)
Zoals je ziet verdwijnt hier wel alle dubbele getallen. 3 komt vier keer voor in de oorspronkelijke lijst en slechts 1 keer in de gesorteerde lijst.
Als je vl-sort-i gebruikt blijven wel alle dubbel voorkomende getallen aanwezig. Je krijgt echter een lijst met de positie van de getallen in de oorspronkele lijst retour. Dit betekent alleen maar dat jemet de nth functie de eigen lijst moet maken.