Uniform scale van block aanpassen (opgelost door HofCAD)

Gestart door AdenRob, wo 17 04 2013, 15:02:51

Vorige topic - Volgende topic

AdenRob

Hallo,

Wij zouden graag de eigenschap UNIFORM SCALE van een block willen veranderen d.m.v. een lisp.
Handmatig kunnen we dit doen door het block te openen met de blockeditor en dan bij properties de eigenschap SCALE UNIFORMLY op YES te zetten. Maar hoe krijgen we dit in een LISP ingebouwd?

We dachten dit te kunnen regelen met de code:
(vla-put-blockscaling blocknaam acUniform)

Helaas werkt dit niet, we krijgden de foutmelding: ActiveX Server returned the error: unknown name: BlockScaling

In de help-file kwamen we dit tegen: Note To access this property, use the IAcadBlock3 interface
Wellicht heeft dit er wat mee te maken, alleen ons zegt dit niet veel...
Dit is de code die we tot nu toe hebben samengesteld:

(defun c:vus ()
  (setq blok (entsel))
(vl-load-com)
  (setq blocknaam (vlax-Ename->Vla-Object (car blok)))
  (vla-put-blockscaling blocknaam acUniform)
(princ)
  )


Zou iemand ons kunnen vertellen wat we verkeerd doen?

Alvast bedankt voor het meedenken!

Groet, AdenRob

HofCAD

#1
Citaat van: AdenRob op wo 17 04 2013, 15:02:51
Hallo,

Dit is de code die we tot nu toe hebben samengesteld:

(defun c:vus ()
  (setq blok (entsel))
(vl-load-com)
  (setq blocknaam (vlax-Ename->Vla-Object (car blok)))
  (vla-put-blockscaling blocknaam acUniform)
(princ)
  )


Zou iemand ons kunnen vertellen wat we verkeerd doen?

Alvast bedankt voor het meedenken!

Groet, AdenRob
Beste AdenRob,

Met (setq blocknaam (vlax-Ename->Vla-Object (car blok))) krijg je
het object van de blockreferentie en niet het object van de block
definitie!
Probeer eens:
(defun c:BlkSetScalUni(/ BlockName Scalability e ed e330 e330d)
   (setq Scalability 1) ;;0=non-Uniform  1=Uniform
   (setq BlockName (cdr (assoc 2 (entget (car (entsel))))))
   (setq e (tblobjname "block" BlockName)
         ed (entget e)
         e330 (cdr (assoc 330 ed))
         e330d (entget e330)
         e330d (subst (cons 281 Scalability) (assoc 281 e330d) e330d)
   );setq
   (entmod e330d)
   (entmod ed)
   (prin1)
)

of
(defun c:BlkSetScalUni2(/ BlockName Scalability)
   (vl-load-com)
   (setq Scalability 1) ;;0=non-Uniform  1=Uniform
   (setq BlockName (cdr (assoc 2 (entget (car (entsel))))))
     (vla-put-blockscaling
       (vla-item (vla-get-blocks
   (vla-get-activedocument (vlax-get-acad-object))
)
BlockName
       )
      Scalability
     )
   (prin1)
)


Met vriendelijke groet, HofCAD CSI.

PS Als je kijkt in de dialoogbox van PROPERTIES, dan kan je zien dat na
het block op uniform schaling is gezet er toch verschillende waarden voor
X, Y en Z schalen kunnen bestaan, maar niet na verandering van de X schaal. :nigoe:
ACADcadabra

AdenRob

Beste HofCAD,

Allereerst onze hartelijke dank voor je snelle reactie, en de perfect werkende lisps! Dit is precies waar we naar op zoek waren.  :D :vreegoe:

Onze lisp kennis is nog vrij beperkt. We zijn dan ook meteen aan de gang gegaan om jouw lisp te ontleden. We kunnen de eerste lisp volgen, maar helaas (nog) niet zelf bedenken. Heb je misschien tips waar je bepaalde gegevens vandaan haalt, of is dit allemaal ervaring?
We hebben de cursus van Joop op deze site gevolgd en ook zijn we bezig met het doorlopen van alle cursussen op afralisp, maar helaas kregen we met de opgedane kennis dit probleem niet opgelost. Maar we blijven oefenen!  :wink:

We hebben achter elke regel van jouw eerste code onze opmerking geplaatst bij het ontleden. Waarschijnlijk is het taalgebruik niet helemaal correct, maar de boodschap is hopelijk duidelijk.
(defun c:BlkSetScalUni(/ BlockName Scalability e ed e330 e330d)
   (setq Scalability 1) ;;0=non-Uniform  1=Uniform
   (setq BlockName (cdr (assoc 2 (entget (car (entsel)))))) ;;blocknaam uitlezen van het geslecteerde block
   (setq e (tblobjname "block" BlockName) ;;retourneert entiteit naam
ed (entget e) ;;haalt entiteit data van entiteit naam
         e330 (cdr (assoc 330 ed)) ;;retourneert entiteit naam 330 uit lijst
         e330d (entget e330) ;;haalt entiteit data van entiteit naam
         e330d (subst (cons 281 Scalability) (assoc 281 e330d) e330d) ;;maakt copy van hele lijst en veranderd code 281 van "0" naar "1"
   );einde van setq e
   (entmod e330d) ;;wijzigt data
   (entmod ed) ;;wijzigt data
   (prin1) ;;is dit hetzelfde als (princ)???
)


Wat ons op viel is dat er 2x entget wordt gebruikt om uiteindelijk bij de variabele 281 (uniform scale) te komen. Moet dit standaard om eigenschappen van blocks uit te lezen? Waar kunnen we dit ergens opzoeken/leren?
Dit zelfde geldt voor de code 281. Wij wisten niet dat dit voor uniform scale stond. Is er ergens een uitgebreide lijst met DXF-codes te vinden? Wij gebruiken deze http://www.afralisp.net/reference/dxf-group-codes.php, maar hier staat bijvoorbeeld de code 281 niet duidelijk tussen...

Wat betreft je 2e code, hier hebben we dus het verkeerde commando gebruikt? Ook hiervoor geldt dat we de code begrijpen, maar helaas niet zelf konden samenstellen. We gaan binnenkort ons (nog) verder verdiepen in visual lisp.

Nogmaals onze hartelijke dank HofCAD!

Met vriendelijke groet,
AdenRob

EddyBeerke

Als je dan toch iets nieuws moet leren, waarom dan niet gelijk in VB/C#.NET?
Civil3d 2022, Blender 3.4 gebruiker
Gebruiker sinds AutoCAD R12

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

HofCAD

#4
Beste AdenRob,

Het belangrijkste is dat een block reference iet anders is
dan een block definitie! :twisted:
In de help van AutoCAD kun je bij de DXF help onder
de 'TABLES Section' de categorie 'BLOCK_RECORD' vinden!
En daar vind je de code 281 voor de 'Block scalability'!
The DXF Reference is available through the product Help or in the formats listed below.
http://usa.autodesk.com/adsk/servlet/item?linkID=10809853&id=12272454&siteID=123112
Zie bijv. blz. 39 in:  http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf
Dit lijkt mij beter dan: http://www.afralisp.net/reference/dxf-group-codes.php

Ik gebruik geen 2x maar 3x entget!
De eerste keer gebruik ik entget om uit de geselecteerde
block reference de naam van het block te krijgen.
(setq BlockName (cdr (assoc 2 (entget (car (entsel))))))
De tweede keer gebruik ik entget om uit de
block tabel de gegevens te krijgen.
ed (entget e))
Waarbij men krijgt:
((-1 . <Entity name: 7eda9180>) (0 . "BLOCK") (330 . <Entity name: 7eda7d88>)
(5 . "A8") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 2) (10 0.0 0.0 0.0) (-2 . <Entity name: 7eda7d90>) (2 . "ISO A4 title block
(portrait)") (1 . "") (4 . "ISO A4 title block (portrait) and attributes"))

Men ziet dat in deze lijst een sub entiteit zit, namelijk het BLOCK_RECORD!
De derde keer gebruik ik entget om de gegevens van
deze sub entiteit te krijgen
e330d (entget e330)
Waarbij men krijgt:
((-1 . <Entity name: 7eda7d88>) (0 . "BLOCK_RECORD") (330 . <Entity name:
7eda7c08>) (5 . "31") (100 . "AcDbSymbolTableRecord") (100 .
"AcDbBlockTableRecord") (2 . "ISO A4 title block (portrait)") (360 . <Entity
name: 7eda9180>) (340 . <Entity name: 0>)
(310 . "") (310 . "") (310 . "")(310 . "") (310 . "") (310 . "")
(102 . "{BLKREFS") (331 . <Entity name:
7eda9198>) (102 . "}") (70 . 4) (280 . 1)
(281 . 0))

Met vriendelijke groet, HofCAD CSI.

PS Een ander alternatief is:

(defun c:BlkSetScalUni3 (/ BlockName Scalability)
  (vl-load-com)
  (setq Scalability 1)
  ;;0=non-Uniform  1=Uniform
  (setq BlockName (cdr (assoc 2 (entget (car (entsel))))))
  (vla-put-blockscaling
    (vlax-ename->vla-object
      (cdr (assoc 330 (entget (tblobjname "block" BlockName))))
    )
    Scalability
  )
  (prin1)
)
ACADcadabra

AdenRob

Beste HofCAD,

Bedankt voor je tip van de DXF help!

Wat betreft het entget... hier hebben we inderdaad een tel fout gemaakt.  :auw:

We zijn de lisp regel voor regel aan het invoeren in de visual lisp console en zo de uitkomsten aan het ontleden. Hierdoor is ons al een hoop duidelijk geworden, maar helaas blijven we met een aantal vragen zitten…

In jouw voorbeeld geef je aan dat je lijst na de tweede keer "entget” een sub-entiteit bevat  (330 . <Entity name: 7eda7d88>).  Waarom wordt deze sub-entiteit daarna met "entget" verder ontleed, en niet de andere sub-entiteit (-2 . <Entity name: 7eda7d90>) of (-1 . <Entity name: 7eda9180>)?
We begrijpen dat we met de 330 code de block record krijgen, maar waar staan de andere codes voor?

Codes die we voortdurend tegen komen, maar die we helaas niet terug gevonden krijgen of niet begrijpen zijn:
-2 ; hier krijgen we helaas niks over gevonden in de help.
330 ; Soft-pointer ID/handle to owner dictionary (optional), wat wordt hiermee bedoeld?
360 ; Soft-pointer ID/handle to owner object, wat wordt hiermee bedoeld?

Zou je zo vriendelijk willen zijn om ons hier wat meer over te vertellen. We denken dan de hele lisp te snappen, en voortaan ook toe te kunnen passen!  :D

Alvast bedankt voor alle hulp!

Met vriendelijke groet,
AdenRob

HofCAD

#6
Beste AdenRob,

Ik ga natuurlijk alleen iets opsporen, waar iets in zit wat ik wil bekijken
of wil veranderen!
Alleen in het BLOCK_RECORD code 330 zit de code 281 voor de 'Block scalability'!
De code -2 (Zie blz. 5 in:  http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf )
gaat over de tekenelementen die in het block zitten, en hebben dus niks te maken
met de 'Block scalability'!
Omdat je oorspronkelijke vraag ging over 'Block scalability', waarom zou ik die
dan gaan onderzoeken?

Bij (-1 . <Entity name: 7eda9180>) krijgt men een verwijzing
naar de entiteit die bij
(setq e (tblobjname "block" BlockName))
is verkregen, want in de variabele e zit <Entity name: 7eda9180>.
Met (setq eD (entget e)) krijgt men:
Zie blz. 58 in:  http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

Bij (-2 . <Entity name: 7eda7d90>) krijgt men een verwijzing
naar het eerste tekenelement (bijv. een LINE of CIRCLE) wat in het block zit.
Met  (setq e-2 (cdr (assoc -2 ed)))
       (setq e-2D (entget e-2)) krijgt men bijv.:
Zie blz. 70 en blz. 102 in:  http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf
Met Autolisp kan men via (entnext .....) het volgende tekenelement
krijgen enz.
  (setq e-2Next (entnext e-2))
  (setq e-2NextD (entget e-2Next))

Bij (330 . <Entity name: 7eda7c08>) krijgt men een verwijzing
naar het BLOCK_RECORD.
Met   (setq e330 (cdr (assoc 330 ed)))
        (setq e330D (entget e330))
Zie blz. 39 in:  http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

In hoofdstuk 12 in de ObjectARX Developer's Guide die wordt geleverd met de
ObjectARX SDK wordt uitgelegd wat Soft/Hard Owner/Poin​t zijn.

Met vriendelijke groet, HofCAD CSI.

PS Laat het bijgevoegde programma ZieBLK.lsp eens los op een Block met daarin twee of
meerdere tekenelementen(bijv. een lijn en een cirkel) en scroll eens door de uitvoer.
ACADcadabra

AdenRob

Beste HofCAD,

WAUW wat een informatie!   :ole:
Dit geeft ons héél wat meer duidelijkheid over het werken met Lisp!

We hebben je bijgevoegde lisp getest op een aantal blocks en de uitvoer bekeken. Dit in combinatie met je link naar de DXF-help file maakt het allemaal een stuk logischer.
We gaan ons de komende weken dan ook zeker verder verdieping in lisp én visual lisp. Met deze info en de help-files hopen we een heel eind te komen!   :D

Onze dank is zeer groot!!!

Met vriendelijk groet,
AdenRob