Blocken aanpassen

Gestart door KristofDC, za 17 10 2020, 13:18:31

Vorige topic - Volgende topic

KristofDC

Hoi,

Ik heb een aantal (dynamische) blokken zelf gemaakt in een BIBLIOTHEEK.DWG . Nu als ik die invoeg (rechtstreeks of via de toolpalettes) in mijn WERKTEKENING.DWG werken ze zoals het hoort. Mijn vraag is nu, waar moet ik nu mijn blocken editen wanneer ik daar nog wijzigingen in wil aanbrengen. Is dat in de bibliotheek.dwg, in de werktekening.dwg of op de palette? En hoe update ik ze dan in (al) mijn werktekening(en)?

Bedankt alvast!

julien

Zo werkt het niet.
Elk dwg bestand bewaart een ‘staat’ van je block .
Je kan die aanpassen in je dwg’ maar de andere bestanden gaan niet mee aanpassen.
Een block is geen xref.

KristofDC

Ok, tot zover ben ik mee. Als ik een aanpassing doe in de oorspronkelijke block en ik kies in mijn werktekening  op de toolpalette Redefine, doet AutoCad bij block A maar halfslachtig iets en bij block B doet hij exact wat er zou moeten gebeuren. Beide blocken hebben een gelijkaardige dynamische opbouw alleen de "lijntjes" en de tekst verschillen van plaats.

gery

#3
De blocks in je werktekeningen zijn statische kopies van de blocks uit je bibliotheek, dus geen dynamische verwijzing naar de blocks in je bibliotheek. Als je blocks in je bibliotheek wijzigt, dien je indien gewenst ook de "kopies" in je werktekeningen te updaten. Dat kan mbv het commando "redefine", eventueel in combinatie met "attsync" indien je block attributen bevat.
Ikzelf gebruik wblocks en een LISP-routine die beide bovenstaande commando's combineert. Laad de LISP-routine, type (Blockredef+Attsync) op de commandoregel, incl. de haakjes (!), en selecteer het block op het scherm. Het pad waar de wblocks staan, dient wel toegevoegd te zijn aan de standaard zoekpaden van AutoCAD.

(defun BlockRedef+AttSync ( / )
  (command "_.undo" "_begin")
    (Sub:Error) ; defines a custom error handler
    (setq   #snapmode (getvar "snapmode")) ; remembers the initial setting
    (setvar "snapmode" 0) ; set temporary setting
    (Sub:SelectBlock) ; lets the user select the block
    (Sub:BlockRedef) ; redefines the block
    (Sub:BlockAttSync) ; synchronizes the block attributes
    (*error* nil) ; executes nested error handler
  (command "_.undo" "_end")
  (Sub:clStatus "BlockRedef+AttSync1")
)


(defun Sub:Error ( / ) ; defines a custom error handler
  (setq #error *error*) ; secures users error handler
  (defun *error* ( #errmsg ) ; defines nested error handler
    (if #errmsg (princ #errmsg)) ; displays the initial error message on the command line (can be ommitted)
    (if #snapmode (setvar "snapmode" #snapmode)) ; restores the initial setting
    (if #error (setq *error* #error))) ; restores users error handler
)


(defun Sub:DblockCount ( %BlockName %tab / #Ent #ssx #x ) ; counts the amount of the specified (dynamic) block in the specified tab
  (if (setq #ssx (ssget "_X" (list (cons 2 (strcat %BlockName ",`*U*")) (cons 410 %tab))))
    (mapcar
      (function
        (lambda (#Ent)
          (if (and (/= (strcase %BlockName) (strcase (vla-get-effectivename (vlax-ename->vla-object #Ent)))) (ssmemb #Ent #ssx))
    (ssdel #Ent #ssx))))
      (vl-remove-if-not '(lambda (#x) (= (type #x) 'ename)) (mapcar 'cadr (ssnamex #ssx)))))
  (if (and #ssx (> (sslength #ssx) 0))
    (cons %BlockName (sslength #ssx)))
)


(defun Sub:SelectBlock ( / )
  (setq #BlockName   (vla-get-Effectivename (vlax-ename->vla-object (car (entsel "\nSelect block to update: "))))) ; determines the (dynamic) block name of the user selected block
  (setq #BlockCount  (cdr (Sub:DblockCount #BlockName (getvar "ctab")))) ; counts the amount of (normal or dynamic) blocks affected
)


(defun Sub:BlockRedef ( / ) ; redefines the block definition of all the referenced blocks
  (repeat 2 ;
    (command "_.insert" (strcat #BlockName "=")) ; redefines a block
    (command)) ; interrupts the insert command prior to the prompt for an insertion point
)


(defun Sub:BlockAttSync ( / ) ; synchronizes the attributes of a block definition to all the referenced blocks in the drawing
  (repeat 2 (command "_.attsync" "_Name" #BlockName))
)


(defun Sub:clStatus ( %Status / )
  (if (/= %Status "BlockRedef+AttSync2")
    (progn (princ "\n")
      (cond ((= %Status "BlockRedef") (princ "Block \"")))
      (cond ((= %Status "BlockAttSync") (princ "\nAttributes of block \"")))
      (cond ((= %Status "BlockRedef+AttSync1") (princ "Block \"")))
                                                (princ #BlockName)
      (cond ((= %Status "BlockRedef") (princ "\" is redefined (EXCL. attributes!), ")))
      (cond ((= %Status "BlockAttSync") (princ "\" are synced, ")))
      (cond ((= %Status "BlockRedef+AttSync1") (princ "\" is completely redefined, ")))
                                                (princ #BlockCount)
      (cond ((= #BlockCount 1) (princ " block is")))
      (cond ((> #BlockCount 1) (princ " blocks are")))
                                                (princ " affected.")
                                                (princ)))
)
AutoCAD 2020 - Windows 10

bart

Dat het lijkt of er iets niet op de zelfde manier gaat is een enkele bug daargelaten het gevolg van bewuste  keuzen. van de ontwikkelaar.
In hoe er met bepaalde data in je tekening word omgegaan.

Als een Block intelligentie bevat bijvoorbeeld attributen of als het dynamische is moet je meer handelingen verrichten om het aan te passen in de hele dwg
Dit moet je zien als een beveiliging tegen het onbewust aanpassen van dergelijke gegevens in je tekening.



Domme vragen bestaan niet.
Domme antwoorden wel.

m.vr. groet Bart

delangstevandestraat

Er zijn verschillende manieren die ik gebruik afhankelijk van welke soort block ik wens up te daten,

Zowiezo beheer ik al mijn blocks in een aparte folder telkens als dwg op zich. (dit ter info)

1e - als het een 'simpele' block is (enkel getekende elementen en attributes) dan volstaat een redefine, dit kan via een lispje waar je een lusje schrijft rond onderstaande code om alle blocks die je wilt laten aanpassen te behandelen
          (command "-INSERT" (strcat bloknaam "=" fullfile) nil)
          (command-s "ATTSYNC" "N" bloknaam)

LET OP: als je attributen wijzigt of toevoegt dan zal dit ongewenste resultaten leveren en kan deze manier niet meer voldoende zijn.

2e - als het een 'complexere' block is (met dynamic en attrib en wat nog niet allemaal ;-) ) dan maak ik daar een
een ander soort lispje rond waarin ik alle parameters van de block uit de dwg haal :
* alle attrib's,
* alle dynamic properties
* alle block properties (positie,hoek, ...)

deze oude block verwijderen en een nieuwe block vanuit de lisp laten intekenen waarbij ik dan alle bijgehouden variabelen gebruik om deze geupdate block exact terug te plaatsen.

Hier heb je alle vrijheid om binnen het ontwerp van je block echt alles te veranderen. als je bvb een extra attribute toegevoegd hebt kan je bij het vervangen in je lisp de 'te verwijderen block' tonen aan de gebruiker en daar de vraag stellen wat de nieuwe attribute moet zijn.

Je moet hierbij wel code maken voor elke block specifiek.
Een extra optie is om de oude block te moven naar ergens ver weg, en eventueel te veranderen van laag, dan ben je deze niet onmiddellijk kwijt voor als het toch fout loopt.
Ook plaats ik de nieuwe blocks meestal in een layer nieuw met een opvallend kleurtje, zodat je makkelijk kan zien wat er overal vervangen is geweest.

Eens alles klaar kan je dit dan aanpassen naar de juiste layer en de gemovede blocks in een actie verwijderen.

Deze manier werkt goed, maar is natuurlijk een beetje codeerwerk, en je moet dus zelf uitmaken of het rendabel genoeg (hoeveel keer heb je dit nodig en voor hoeveel blocks) is om daar je tijd in te steken of niet.

3e - Een andere mogelijkheid is dat je
* uw slechte blocks verplaatst naar een lege locatie,
* daar met een vaste offset uw nieuwe blocks naast plaatst,
* via een copypastecopypaste lispje de attrib value's overbrengt
* deze nieuwe blocks terugplaatst

deze manier vereist geen codeerwerk en levert je vlugger resultaat, maar duurt langer bij grotere aantallen

Hier het copy - paste - cpoy - paste stukje code (een van mijn meest gebruikte stukjes code)
; this program let's u copy txt sequentially
; read txt write txt read write, read write....
;

(defun c:xFT (/ cntr ent atortxt modtxt txtormtxt dimortxt seldimt strdimedit el mt selatt )
(setvar "cmdecho" 0)
(setq cntr 0)
  (while (< cntr 10)
      (setq ent (nentselp "Select source Text: " ))
      (if ent
        (progn ;1
         (setq atortxt (cdr(assoc 1 (entget (car ent ))))) 
            (setq modtxt (nentselp "\n Select Text to modify: "))
            (if modtxt
              (progn ;2
                (setq txtormtxt (cdr(assoc 0 (entget (car modtxt ))))) 
                (cond
                  ((or (= txtormtxt "TEXT")(= txtormtxt "MTEXT"))
                    (progn ;3
                      (setq dimormtxt (cdr(assoc 42 (entget (car modtxt ))))) 
                      (if (/= dimormtxt nil)
                        (progn ;4
                          (setq seldimt (cdr (assoc -1 (entget (car modtxt )))))
                          (setq strdimedit (substr atortxt 5 (strlen atortxt)))
                          (command "dimedit" "n" strdimedit seldimt "")
                        ) ;progn4
                        (progn ;5
                          (setq el (entget (car modtxt )))         
                          (setq mt (subst (cons 1 atortxt) (assoc 1 EL) EL))
                          (entmod mt)
                        ) ;progn5
                      ) ;if
                    ) ;progn3
                  ) ;cond or
                  ((= txtormtxt "ATTRIB")
                    (progn ;6
                      (setq selatt (cdr (assoc -1 (entget (car modtxt )))))
                      (command "-attedit" "" "" "" "" selatt "v" "r" atortxt "")
                    ) ;progn6
                  ) ;cond or
                  (T (princ "\n Invalid Selection... "))
                ) ;cond
              ) ;progn2
            ) ;if
        ) ;progn1
      ) ;if
  );while
(princ)
) ;defun



Ik hou van werken,
ik kan er uuuren naar kijken...
daarom zorg ik ook dat er altijd genoeg overblijft voor morgen :-)