FastFiber

Dynamic blocks kopiëren

Gestart door Jacob, di 22 04 2025, 15:55:47

Vorige topic - Volgende topic

Jacob

Als wij wat aanpassingen in een blok doen in de huidige tekening en we laden datzelfde blok weer uit onze bibliotheek dan voegt hij hetzelfde blok in zoals die al in de huidige tekening zit.

We maken dan in de bibliotheek even een kopie met een andere naam en die voegen we in.
Dat willen we eigenlijk in een lisp zetten met de naam "KopieBlock"

Via Chat GTP ben ik druk bezig geweest om een Dynamic block te kopiëren en met een andere naam te plakken.
Dat loopt op verschillende manier steeds vast bijv:
- Het block is daarna niet dynamisch meer
- Je krijg allemaal losse lijnstukken
- Diverse errors in de commandline

Is hetgeen ik wil wel mogelijk?

Onderstaand 1 van de codes die heen en weer zijn gegaan.
(defun c:KopieerBlokSel ( / ent entname oldName newName ss)
  (prompt "\nSelecteer een blok om te kopiëren: ")
  (setq ent (car (entsel)))

  (if (and ent (= (cdr (assoc 0 (entget ent))) "INSERT"))
    (progn
      (setq entname (cdr (assoc 2 (entget ent))))
      (setq oldName entname)
      (setq newName (strcat oldName "_01"))

      ;; Controleer of de nieuwe bloknaam al bestaat
      (if (tblsearch "block" newName)
        (princ (strcat "\nBlok '" newName "' bestaat al."))
        (progn
          ;; Verzamel alle entiteiten in originele blok
          (setq ss (ssadd))
          (vlax-for obj (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) oldName)
            (ssadd (vlax-vla-object->ename obj) ss)
          )

          ;; Maak nieuwe blokdefinitie met nieuwe naam
          (command "_-BLOCK" newName '(0 0 0) ss "")

          (princ (strcat "\nBlok '" oldName "' gekopieerd als '" newName "'."))
        )
      )
    )
    (princ "\nSelectie is geen blok.")
  )
  (princ)
)
Een expert is iemand die steeds meer weet over steeds minder.

EddyBeerke

Jacob,

Zou het kunnen dat het bock geëxplodeerd wordt bij invoegen?

Wat je zou kunnen doen is (in AutoCAD):
In een bv Blocks.dwg de bocks maken, eventueel aanpassen -> deze opslaan en geopend laten.
Open de tekening waar de (aangepaste) blocks in moeten komen -> [Ctrl+2] indrukken
  Nu opend de "Designcenter", hier kun je van de ene (blocks.dwg) naar de andere het block 'in slepen'
  Met [rechts klikken] op zo'n block uit de blocks.dwg kun je ook 'Redefine only' kiezen.

Laat maar weten of dat voor jou werkt.

P.S.
Dit werkt ook voor layers, stylen enz. enz.
Civil3d 2026, Blender 4.x gebruiker
Gebruiker sinds AutoCAD R12

http://eddylucas.c1.biz/
https://www.google.com/maps/contrib/109381066561676463628/photos/

Reimer

Lee-Mac heeft een waanzinnige verzameling lisp-routines. Hij heeft ook LM:CopyBlockDefinition gemaakt. Zie: https://www.lee-mac.com/copyblockdefinition.html. Volgens mij doet deze precies wat je beschrijft en moet hij ook werken voor dynamic blocks. Zeker het proberen waard lijkt me. Ik heb hem zelf nog niet gebruikt maar wel vele andere hanige lisps van Lee Mac.

Groeten,
Reimer.

Jacob

Ik zie nu jullie reacties pas, had geen seintje gehad, ga er mee aan de gang.
Bedankt iig

Een expert is iemand die steeds meer weet over steeds minder.

Jacob

Reimer,
De Lisp van LM geeft de foutmelding dat hij het commando niet kent.
Ook na aanpassen van de namen

Eddie,
Dat is erg omslachtig.
We doen het nu zo:
We hebben een DB in de bibliotheek, bijv. wand01.
Deze laden we in een werktekening.
Vervolgens zien we in het project dat het wand01-block nog een extra onderdeel moet hebben, die voegen we toe in wand01.
We tekenen verder en moeten nog een wand maken zonder dat extra onderdeel.
Laden we nu wand01 weer in uit de bibliotheek, dan zit dat extra onderdeel er ook in.
Nu openen we in de bibliotheek wand01 met Block Editor en kiezen dan via het menu Safe Block As
Geven een andere naam bijv. wand02 en laden die in de werktekening.

De laatste 2 regels wilde ik in een lisp zetten
Dus een kopie met andere naam (bijv. A toevoegen) in de bibliotheek van een geselecteerd block, deze dan weer in de werktekening laden.
Een expert is iemand die steeds meer weet over steeds minder.

julien

Qua lisp ken ik niets, maar ik kom hetzelfde probleem ook soms tegen en ik los dat op door er een "visibility state" aan toe te voegen.

Jacob

Julien,

Waar en hoe kan ik een "visibility state" toevoegen?
Eerlijk gezegd is dat bij mij onbekend.
Een expert is iemand die steeds meer weet over steeds minder.

julien

Een dynamisch block kan verschillende vormen hebben.
Je kan er "zichtbaarheid" aan toevoegen. Dan kan je kiezen wat wel en wat niet zichtbaar is per instantie van hetzelfde block.

Ik heb er een handleiding voor geschreven in:
https://cadsite.be/cursus/les_4/
Onderaan bespreek ik kort een stukje over visibility state.

Jacob

Ha ha, ik schaam me.  :oops:
Visibility gebruik ik al jaren, maar wist niet dat het Visibility State heet.

Maar hij geeft een foutmelding op het commando die in de lisp staat, niet op het block.
Een expert is iemand die steeds meer weet over steeds minder.

julien

 :mrgreen:
Ik stelde dit voor om misschien de lisp overbodig te maken.

Reimer

Ik moest ook even puzzelen maar ben er denk ik uit. Lee Mac schrijft bij de uitleg dat zijn functie werkt wanneer je het volgende ingeeft: (LM:CopyBlockDefinition "OldBlock" "NewBlock")
Ik wil liever een bestaand block selecteren dan een naar intypen. Het opvragen van de naam van een dynamic block is net wat lastiger dan van een gewoon block. Gelukkig heeft Lee Mac daar al een functie voor geschreven.
Ik heb zijn functies bij elkaar gezet en zelf een stukje code bijgeschreven. Als het goed is werkt het onderstaande wanneer je Copyb start. Bij mij werkt het!

;; Copy Block Definition  -  Lee Mac
;; Duplicates a block definition, with the copied definition assigned the name provided.
;; blk - [str] name of block definition to be duplicated
;; new - [str] name to be assigned to copied block definition
;; Returns the copied VLA Block Definition Object, else nil
(defun LM:CopyBlockDefinition ( blk new / abc app dbc dbx def doc rtn vrs )
    (setq dbx
        (vl-catch-all-apply 'vla-getinterfaceobject
            (list (setq app (vlax-get-acad-object))
                (if (< (setq vrs (atoi (getvar 'acadver))) 16)
                    "objectdbx.axdbdocument" (strcat "objectdbx.axdbdocument." (itoa vrs))
                )
            )
        )
    )
    (cond
        (  (or (null dbx) (vl-catch-all-error-p dbx))
            (prompt "\nUnable to interface with ObjectDBX.")
        )
        (  (and
                (setq doc (vla-get-activedocument app)
                      abc (vla-get-blocks doc)
                      dbc (vla-get-blocks dbx)
                      def (LM:getitem abc blk)
                )
                (not (LM:getitem abc new))
            )
            (vlax-invoke doc 'copyobjects (list def) dbc)
            (vla-put-name (setq def (LM:getitem dbc  blk)) new)
            (vlax-invoke dbx 'copyobjects (list def) abc)
            (setq rtn (LM:getitem abc new))
        )
    )
    (if (= 'vla-object (type dbx))
        (vlax-release-object dbx)
    )
    rtn
)

;; VLA-Collection: Get Item  -  Lee Mac
;; Retrieves the item with index 'idx' if present in the supplied collection
;; col - [vla]    VLA Collection Object
;; idx - [str/int] Index of the item to be retrieved
(defun LM:getitem ( col idx / obj )
    (if (not (vl-catch-all-error-p (setq obj (vl-catch-all-apply 'vla-item (list col idx)))))
        obj
    )
)

;; Effective Block Name  -  Lee Mac
;; ent - [ent] Block Reference entity
(defun LM:al-effectivename ( ent / blk rep )
    (if (wcmatch (setq blk (cdr (assoc 2 (entget ent)))) "`**")
        (if
            (and
                (setq rep
                    (cdadr
                        (assoc -3
                            (entget
                                (cdr
                                    (assoc 330
                                        (entget
                                            (tblobjname "block" blk)
                                        )
                                    )
                                )
                              '("AcDbBlockRepBTag")
                            )
                        )
                    )
                )
                (setq rep (handent (cdr (assoc 1005 rep))))
            )
            (setq blk (cdr (assoc 2 (entget rep))))
        )
    )
    blk
)

;; Functie door Reimer om de routine van Lee Mac te laten werken.
;;
(defun c:CopyB ( / OLDBLOCK OLDNAME NEWNAME)
  (prompt "\nSelecteer een blok om te kopiëren: ")
  (setq OLDBLOCK (car (entsel)))
  (if (and OLDBLOCK (= (cdr (assoc 0 (entget OLDBLOCK))) "INSERT"))
    (progn
      (setq OLDNAME (LM:al-effectivename OLDBLOCK))
      (setq NEWNAME (strcat OLDNAME "_1"))
      (while (tblsearch "BLOCK" NEWNAME)
        (setq NEWNAME (strcat NEWNAME "_1"))
      )
      (LM:CopyBlockDefinition OLDNAME NEWNAME)
      (princ (strcat "\nBlock '" OLDNAME "' gekopieerd als '" NEWNAME "'."))
    )
    (if (not OLDBLOCK)
      (prompt " Geen object geselecteerd.")
      (prompt " Selectie is geen block.")
    )
  );_if
  (print)
)

FastFiber