CADsite forum

AutoCAD => Autolisp => Topic gestart door: Baco op di 25 09 2012, 23:00:51

Titel: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: Baco op di 25 09 2012, 23:00:51
Wie heeft er een suggestie?

Ik heb een isometrisch schema van een waterleidingstelsel met aan elk einde van een lijn een block met attributen. Deze kan ik exporteren en dan in vabi inlezen. Nu moet elke lijn eindigen met een zo'n block of doorgaan met een andere lijn. Als een lijn dus eindigt zonder block of niet begint met een andere lijn eindigt dus mijn waterleidingstelsel. Nu wil ik mbv een lisp routine controleren waar ik eindpunten van lijnen die niet aangesloten zijn met andere lijnen of blocken.

Wie heeft hier iets voor? Zelf dacht ik alle begin- en eindpunten van elke lijn te filteren en P1, P2, P3 etc te noemen. Dan van elk block het insertionpoint te benoemen en vervolgens de coordinaten te vergelijken  en alle coordinaten die 1x voor komen in de lijst te voorzien van een dikke dot.

Maar hoe kan ik een lijst van punten maken van alle lijnen uit een tekening. En idem dito voor alle blocks.

Bij voorbaat bedankt.
Titel: Re: Lijjncontrole uit hele tekening
Bericht door: roy_043 op wo 26 09 2012, 16:20:11
Zo bijvoorbeeld:

; (ActiveSet_To_ObjectList)
; Hulpfunctie.
(defun ActiveSet_To_ObjectList ( / activeSet count ret)
  (vlax-for object (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))
    (setq ret (cons object ret))
  )
  (reverse ret)
)

; (PointsFromLinesAndInserts)
; Vraagt de gebruiker om een selectie en retourneert een lijst van alle
; insertionpoints (insert) en alle startpoints en endpoints (line).
(defun PointsFromLinesAndInserts ()
  (ssget '((-4 . "<OR") (0 . "INSERT") (0 . "LINE") (-4 . "OR>")))
  (apply
    'append
    (mapcar
      '(lambda (object)
        (cond
          ((= (vla-get-objectname object) "AcDbBlockReference")
            (list (vlax-get object 'insertionpoint))
          )
          ((= (vla-get-objectname object) "AcDbLine")
            (list (vlax-get object 'startpoint) (vlax-get object 'endpoint))
          )
        )
      )
      (ActiveSet_To_ObjectList)
    )
  )
)
Titel: Re: Lijjncontrole uit hele tekening
Bericht door: Baco op wo 26 09 2012, 19:52:54
Hoi Roy,

Bedankt voor jouw reactie. Ik ga even regel voor uitzoeken wat er gebeurd. Helaas heb ik thuis geen autocad om te testen. Zelf heb ik diverse lisp-routines geschreven maar dat is alweer een tijd geleden. Nu zie ik dat je het startpunt - eindpunt weer combineert naar een coordinatie. En het insertionpunt van het block ook.

Ik ga even nazoeken op internet en in mijn boek (programmeren in autocad13), ja ik weet het een oud boek.

Jij gebruikt bijv. ook vla en vlax, deze ken ik (nog) niet. Ik zie ook niet zo snel aan welke variabele de lijncoordinaten worden toegekend en aan welke variabele de insertionpoint word toegekend).  Verder zie ook nog niet of het 3D coordinaten zijn of uitsluitend 2D, bovendien kan ik pas maandag even testen......

Alvast bedankt voor jouw inzet!!

Als ik meer weet koppel ik hem hier weer terug.

gr Bas
Titel: Re: Lijjncontrole uit hele tekening
Bericht door: Baco op wo 26 09 2012, 21:25:28
Als ik even kijk dan is er 1 lijst met zowel de insertionpoints en begin- en eindpunten van de lijnen. Ik kan nu helaas niet controleren met een tekening en proefdraaien....... mijn vertaling heb ik even achter de lijnen gezet (in kladblok wel goed te lezen). En dan de lijst controleren of de coordinaten 2x voorkomen, dan kan ik ze wegstrepen en de overgebleven een dikke donut geven.

; (ActiveSet_To_ObjectList)
; Hulpfunctie.
(defun ActiveSet_To_ObjectList ( / activeSet count ret) ;maak commando ActiveSet_To_ObjectList
  (vlax-for object (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) ;set object "de selectie"
    (setq ret (cons object ret)) ;geef waarde "object" aan ret
  ) ;einde set object
  (reverse ret) ;reverse ret
)

; (PointsFromLinesAndInserts)
; Vraagt de gebruiker om een selectie en retourneert een lijst van alle
; insertionpoints (insert) en alle startpoints en endpoints (line).
(defun PointsFromLinesAndInserts () ;maak commando PointsFromLinesAndInserts
  (ssget '((-4 . "<OR") (0 . "INSERT") (0 . "LINE") (-4 . "OR>"))) ;verkrijg entiteittype
  (apply
    'append ;toevoegen aan de lijst
    (mapcar
      '(lambda (object) ;maak lijst "object"
        (cond ;loop start
          ((= (vla-get-objectname object) "AcDbBlockReference") ;is object een block
            (list (vlax-get object 'insertionpoint)) ;insertionpoint van object
          )
          ((= (vla-get-objectname object) "AcDbLine") ;is object een lijn
            (list (vlax-get object 'startpoint) (vlax-get object 'endpoint)) ;startpoint - endpoint van object
          )
        ) ;loop end
      ) ;eind lijst "object"
      (ActiveSet_To_ObjectList) ;commando
    )
  )
)



groeten Bas
Titel: Re: Lijncontrole uit hele tekening
Bericht door: roy_043 op do 27 09 2012, 15:34:37
Beste Bas,

Jouw analyse van de code is op veel plaatsen niet correct.
Hoog tijd dus om jouw kennis wat op te frissen:
http://www.autolisp-tutorial.mapcar.net/ (Duits)
http://www.afralisp.net/
http://www.cadsite.be/lisp/lisp.php

Als je code in een bijdrage op wilt nemen dan kun je het beste de "#" knop boven het invoerveld gebruiken.

Succes, Roy.
Titel: Re: Lijncontrole uit hele tekening
Bericht door: bart op vr 28 09 2012, 07:17:21
baco,

ter informatie
Als je baas het goed vind is het door autodesk toegestaan om autocad thuis te installeren met de zelfde sleutel als op het werk.

Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op vr 28 09 2012, 22:00:52
Hoi Roy,
Het is inderdaad een tijd geleden dat ik iets met lisp geprogrammeerd heb.... en ik denk ook op een niveau dat minder diep gaat. Ik zal de sites gaan bekijken en de pdf's uitdraaien om het weer op te pakken.

En Bart,
Als dat zo is kan ik er meer aan doen in mij eigen tijd...... zeer nuttige info. Thanks


Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op ma 01 10 2012, 12:44:13
Net even de lisp geprobeerd en hij geeft een mooie lijst nadat ik (vl-load-com) had toegevoegd na (defun ActiveSet_To_ObjectList ( / activeSet count ret).

Nu wil ik de lijst gaan controleren op dubbele coordinaten en dan bij de enekel voorkomende een cirkel of donut plaatsen.

Top voor de ondersteuning / start van de code en de "pdf - files" zijn ongeveer wat ik had staan in mijn boek (ik denk het basis van lisp) de overige links ben ik nog niet aan toegekomen......

Tot snel, Bas
Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op di 02 10 2012, 19:50:19
Hoi Roy,

Ik ben erachter dat er ook visual-lisp in de code is toegepast. Hier weet ik niks van :oops:, weet je een duidelijk nederlands boek hierover? Want volgens mij heb ik dat wel nodig om te weten wat ik aan het invoeren ben...... en als je een nederlandse site weet dan is dat ook van harte welkom. Anders moet ik maar zoeken naar een degelijke cursus. :roll:

groeten Bas
Titel: Re: Lijncontrole uit hele tekening
Bericht door: roy_043 op wo 03 10 2012, 01:17:38
Er zijn bij mijn weten geen Nederlandse boeken die zich uitsluitend met Lisp bezighouden. Een aantal boeken over Autocad bevat wel een hoofdstuk of twee over het onderwerp, maar van veel diepgang is meestal geen sprake.

Zie hier voor wat voorbeelden:
http://www.cadsite.be/smf/index.php?topic=3807.0

De hierboven reeds genoemde link is een echte aanrader:
http://www.autolisp-tutorial.mapcar.net/

Voor de vl-functies kun je natuurlijk ook gewoon de Help raadplegen:
http://docs.autodesk.com/ACD/2011/ENU/landing.html

Mede n.a.v. jouw PM nog wat tips:

Om punten (= lijsten) te vergelijken kun je alleen (equal) gebruiken. (eq) heeft een hele specifieke betekenis. Ik gebruik deze functie eigenlijk nooit. Ik gebruik of (=) of (equal). Bij (equal) kun je ook een tolerantie opgeven.
(equal '(0 0 0) '(0.01 0.01 0.01) 0.01)
Ik raad je aan om gebruik te maken van een zekere tolerantie. Niet omdat jij onnauwkeurig tekent, maar omdat Autocad niet oneindig nauwkeurig is.

Het idee dat je hebt om elk fout punt op te slaan in een aparte variabele is niet handig. Je kunt Lisp beter gebruiken waar het voor bedoeld is namelijk "LISt Processing".

Ik zou het vervolg van het probleem zo aanpakken:

(setq lst (PointsFromLinesAndInserts))
(while lst
  (setq pointToCheck (car lst))  ; Eerste punt uit de lijst.
  (setq len (length lst))        ; Lengte huidige lijst
  (setq lst                      ; Verwijder alle punten die gelijk zijn aan pointToCheck
    (vl-remove-if
      '(lambda (pointFromList)
        (equal pointFromList pointToCheck 0.001)
      )
      lst
    )
  )
  (if (> (length lst) (- len 2)) ; Vergelijk de lengtes. Er moeten min. 2 punten (w.o. het pointToCheck) uit de lijst zijn verwijderd.
    (CreateDotFunction pointToCheck)
  )
)




Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op wo 03 10 2012, 22:51:06
Hoi Roy,

Ik heb hem nu samen gevoegd en het resultaat staat hieronder:
; (ActiveSet_To_ObjectList)
; Hulpfunctie.
(defun ActiveSet_To_ObjectList ( / activeSet count ret) ;maak commando ActiveSet_To_ObjectList
(vl-load-com)
  (vlax-for object (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) ;set object "de selectie"
    (setq ret (cons object ret)) ;maak nieuwe lijst
  ) ;einde set object
  (reverse ret) ;keer ret om
)

; (PointsFromLinesAndInserts)
; Vraagt de gebruiker om een selectie en retourneert een lijst van alle
; insertionpoints (insert) en alle startpoints en endpoints (line).
(defun PointsFromLinesAndInserts () ;maak commando PointsFromLinesAndInserts
  (ssget '((-4 . "<OR") (0 . "INSERT") (0 . "LINE") (-4 . "OR>")))        ;selecteer alle lijnen en blocken
  (apply ;laat zien op commandoregel
    'append ;toevoegen aan de lijst
    (mapcar ;maak lijst "object"
      '(lambda (object) ;van elk element uit de lijst "object"
        (cond ;loop start
          ((= (vla-get-objectname object) "AcDbBlockReference") ;is object een block
            (list (vlax-get object 'insertionpoint)) ;insertionpoint van object
          )
          ((= (vla-get-objectname object) "AcDbLine") ;is object een lijn
            (list (vlax-get object 'startpoint) (vlax-get object 'endpoint)) ;startpoint - endpoint van object
          )
        ) ;loop end
      ) ;eind lijst "object"
      (ActiveSet_To_ObjectList) ;commando
    )
  )
  (setq lst (PointsFromLinesAndInserts)) ;lst = PointsFromLinesAndInserts
  (while lst ;als lst is niet gelijk aan nil
  (setq pointToCheck (car lst))  ; Eerste punt uit de lijst.
  (setq len (length lst))        ; Lengte huidige lijst
  (setq lst                      ; Verwijder alle punten die gelijk zijn aan pointToCheck
    (vl-remove-if
      '(lambda (pointFromList)
        (equal pointFromList pointToCheck 0.001)
      )
      lst
    )
  )
  (if (> (length lst) (- len 2)) ;vergelijk de lengtes. Er moeten min. 2 punten (w.o. het pointToCheck) uit de lijst zijn verwijderd.
    (CreateDotFunction pointToCheck) ;zet dot?
  )
  )
)

;


Dit geeft als resultaat een oneindige loop. (hij begint telkens weer bij selecteer) en volgens mij komt het doordat lst=nil

Verder zal het mij nog wel een aantal avondjes kosten.... bedankt voor jouw ondersteuning! ps ik ga ff pitten... de kids staan 6:00h weer naast mijn bed :shock:.


mvg Bas
Titel: Re: Lijncontrole uit hele tekening
Bericht door: roy_043 op do 04 10 2012, 10:26:32
Jouw oplossing komt inderdaad in een oneindige lus terecht. De reden hiervoor is recursie. De functie (PointsFromLinesAndInserts) roept zichzelf aan. Mits goed gebruikt kan recursie zeer nuttig zijn. Maar hier gaat het dus mis.

Hieronder mijn bedoeling. De functie (MarkPoint) moet nog uitgewerkt worden.

; 20121004: Toegevoegd. Nodig voor Autocad (maar niet voor Bricscad).
(vl-load-com)

; 20121004: Overbodige variabelen verwijderd.
; 20120926
; (ActiveSet_To_ObjectList)
; Hulpfunctie om de actieve selectie om te zetten in een lijst met objecten.
(defun ActiveSet_To_ObjectList ( / ret)
  (vlax-for object (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)))
    (setq ret (cons object ret))
  )
  (reverse ret)
)

; 20121004
; (MarkPoint)
; Hulpfunctie om een punt te markeren.
; Deze functie moet nog gemaakt worden.
; Nu worden alleen de coördinaten van het punt weergegeven.
(defun MarkPoint (point)
  (print point)
)

; 20121004: De functie (PointsFromLinesAndInserts) is geïntegreerd in deze nieuwe functie.
; (c:CheckWaterLines)
; Hoofdfunctie.
(defun c:CheckWaterLines ( / len lst pointToCheck)
  (if (ssget '((-4 . "<OR") (0 . "INSERT") (0 . "LINE") (-4 . "OR>")))
    (setq lst
      (apply
        'append
        (mapcar
          '(lambda (object)
            (cond
              ((= (vla-get-objectname object) "AcDbBlockReference")
                (list (vlax-get object 'insertionpoint))
              )
              ((= (vla-get-objectname object) "AcDbLine")
                (list (vlax-get object 'startpoint) (vlax-get object 'endpoint))
              )
            )
          )
          (ActiveSet_To_ObjectList)
        )
      )
    )
  )
  (while lst
    (setq pointToCheck (car lst))  ; Eerste punt uit de lijst.
    (setq len (length lst))        ; Lengte huidige lijst
    (setq lst                      ; Verwijder alle punten die gelijk zijn aan pointToCheck
      (vl-remove-if
        '(lambda (pointFromList)
          (equal pointFromList pointToCheck 0.001)
        )
        lst
      )
    )
    (if (> (length lst) (- len 2)) ; Vergelijk de lengtes. Er moeten min. 2 punten (w.o. het pointToCheck) uit de lijst zijn verwijderd.
      (MarkPoint pointToCheck)
    )
  )
  (princ)
)
Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op do 04 10 2012, 19:34:37
Roy,

Je bent een toppertje. Ik ben blij dat je een forum-verslaafde bent...... Ik heb zelf nog wel veel werk om het goed uit te zoeken water per regel gebeurt. De code zal ik hier en daar wat aanpassen zoals een apparte laag voor de circels. Het meeste snap ik wel nu ik er weer ff mee bezig ben maar volgens mij is hetgene wat ik niet begrijp visual-lisp. Hier zal ik toch gaan zoeken naar een begeleidend boek in de nederlandse taal. Wat ik ook niet wist is dat het commando circle op meerdere punten tegelijk een circel zet.

Mijn grote dank,
Bas :mrgreen:
Titel: Re: Lijncontrole uit hele tekening
Bericht door: roy_043 op vr 05 10 2012, 09:07:00
Citaat van: Baco op do 04 10 2012, 19:34:37Wat ik ook niet wist is dat het commando circle op meerdere punten tegelijk een cirkel zet.
Dat wist ik ook niet... M.a.w. volgens mij klopt dit niet.
Titel: Re: Lijncontrole uit hele tekening
Bericht door: EddyBeerke op vr 05 10 2012, 09:57:34
Citaat van: Baco op do 04 10 2012, 19:34:37
...
volgens mij is hetgene wat ik niet begrijp visual-lisp...
Als ik het goed heb is Lisp een engelstalige programmeertaal.
Het zou dus  niet verkeerd zijn om je engels wat bij te schaven.
Als je dus wat meer van Visual-Lisp wilt weten:
http://ubuntuone.com/p/uUb/
Kijk het eens na want er wordt soms ook vergeleken met Auto-Lisp
Titel: Re: Lijncontrole uit hele tekening
Bericht door: Baco op vr 05 10 2012, 20:37:03
Hoi Roy,

Als ik een paar lijnen los in een tekening zet en de lisp laad en draai geeft hij netjes cirkels aan de lijnpunten behalve als deze dus op elkaar aansluiten. Dit is wat ik in markpoint heb neergezet :P:

(defun MarkPoint (point la)
  (setq la (getvar "clayer"))
  (command "-LAYER" "m" "chechpoint" "c" "6" "" "")
  (command "CIRCLE" point "50")
  (setvar "clayer" la)
)


Eddybeerke,

Het volgende boek: "programmeren in autocad13" is hartstikke duidelijk en in het nederlands. Het leren schrijven deed ik in mijn stageperiode dus daar had ik een hele dag de tijd voor. Nu is het meer zoeken wat het betekend wat er geschreven is, en straks dus ook bedenken hoe je iets schrijft zodat autocad doet wat je wilt. Een naslag om codes na te lezen is dan erg practisch . Want nu vraag ik mij bijv. welke codes er bestaan en wat ze dan doen...... :shock:


mvg Bas
Ik zal in het weekend wel kijken waar jouw link mij brengt.
Titel: Re: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: Baco op zo 07 10 2012, 19:01:11
Citaat van: Baco op di 25 09 2012, 23:00:51
Wie heeft er een suggestie?

Ik heb een isometrisch schema van een waterleidingstelsel met aan elk einde van een lijn een block met attributen. Deze kan ik exporteren en dan in vabi inlezen. Nu moet elke lijn eindigen met een zo'n block of doorgaan met een andere lijn. Als een lijn dus eindigt zonder block of niet begint met een andere lijn eindigt dus mijn waterleidingstelsel. Nu wil ik mbv een lisp routine controleren waar ik eindpunten van lijnen die niet aangesloten zijn met andere lijnen of blocken.

Wie heeft hier iets voor? Zelf dacht ik alle begin- en eindpunten van elke lijn te filteren en P1, P2, P3 etc te noemen. Dan van elk block het insertionpoint te benoemen en vervolgens de coordinaten te vergelijken  en alle coordinaten die 1x voor komen in de lijst te voorzien van een dikke dot.

Maar hoe kan ik een lijst van punten maken van alle lijnen uit een tekening. En idem dito voor alle blocks.

Bij voorbaat bedankt.
Titel: Re: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: roy_043 op ma 08 10 2012, 09:03:33
@ Baco:
Een typisch probleem bij het gebruik van (command) is dat de huidige instelling van OSMODE het resultaat zal beïnvloeden. Als de OSMODE ingesteld staat op uitsluitend midpoint dan zijn de resultaten van jouw (MarkPoint) functie anders dan gewenst. Het is dus verstandig om de OSMODE in de functie tijdelijk op 0 te zetten.
Titel: Re: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: EddyBeerke op ma 08 10 2012, 10:08:48
Citaat van: Baco op vr 05 10 2012, 20:37:03
Het volgende boek: "programmeren in autocad13" is hartstikke duidelijk en in het nederlands. Het leren schrijven deed ik in mijn stageperiode dus daar had ik een hele dag de tijd voor. Nu is het meer zoeken wat het betekend wat er geschreven is, en straks dus ook bedenken hoe je iets schrijft zodat autocad doet wat je wilt. Een naslag om codes na te lezen is dan erg practisch . Want nu vraag ik mij bijv. welke codes er bestaan en wat ze dan doen...... :shock:

Oke, ik begrijp dat je nu iets weet van AutoLISP, maar je begrijpt weinig van VisualLISP.
Ik het naslagwerk waar ik het over had (http://ubuntuone.com/p/uUb/) gaat juist over VisualLISP!
Het boek waar jij het over hebt stamt uit 1995, toen was er nog GEEN VisualLISP!
Titel: Re: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: Baco op ma 08 10 2012, 19:27:00
Hoi Roy,

De eerder geplaatste reactie van gisteren 19:00h had ik niet willen plaatsen maar eigenlijk alleen opgelost in het onderwerp willen plaatsten..... :?. De lisp doet precies wat ik wil en met de osmode op 0 zetten is waar zelf teken ik altijd met osmode op 0 dus dat geeft geen problemen...... Het rare vind ik alleen dat het commando circle op alle plaatsen tegelijk de cirkel plaatst, dit komt nu eigenlijk alleen maar beter uit!

Hoi Eddy,

Ik heb de link (pdf) ook gedownload en moet beginnen met hem te gaan lezen. En inderdaad het is een oud maar makkelijk en overzichtelijk boek. In elk geval bedankt voor de bijdrage!!!! :vreegoe:

gr Bas
Titel: Re: Lijncontrole uit hele tekening (OPGELOST)
Bericht door: roy_043 op ma 08 10 2012, 23:43:51
Citaat van: Baco op ma 08 10 2012, 19:27:00
Het rare vind ik alleen dat het commando circle op alle plaatsen tegelijk de cirkel plaatst, dit komt nu eigenlijk alleen maar beter uit!
Dit lijkt alleen maar zo. De functie (c:CheckWaterLines) bevat een while-lus waarin een lijst met punten wordt gecontroleerd. Voor elk punt dat slechts één keer in de lijst voorkomt wordt de functie (Markpoint) aangeroepen. Deze functie tekent slechts één cirkel op dat punt. Er worden meerdere cirkels getekend omdat (Markpoint) meerdere keren wordt aangeroepen (als meer dan één "fout" punt is).