vla-InsertBlock method applies unit scaling twice?

vla-InsertBlock method applies unit scaling twice?

Michiel.Valcke
Advisor Advisor
1,479 Views
13 Replies
Message 1 of 14

vla-InsertBlock method applies unit scaling twice?

Michiel.Valcke
Advisor
Advisor

Hello everyone, 

I have a routine where I'm inserting blocks based on text content. The blocks come from external .dwg files as well as possible block definitions already inside the drawing. 

While the main drawing is in meters (doesn't matter really) the block definitions can be defined in meters, millimeters, centimeters, ... the works.

 

I'm using the vla-InsertBlock method to insert the blocks on the position of the text, with the text's rotation. But if a block definition has different units than the active drawing, then the block gets inserted with an added scale factor to compensate for the different units. 

For example, 

rec= block 1000x1000 mm (1x1 meter) - defined in mm

target dwg= units=meter

 

(vla-InsertBlock ModelSpace (vlax-3d-point '(0 0 0) ) "rec" 1 1 1 0)

 

The block "rec" will be placed with both the Unit factor 0.001 and the scale xyz 1000. The latter should be 1. This results in a block that is a square km instead of a square m.

Anybody knows how to prevent this, taking into account that I don't know beforehand whether the block or dwg I'm inserting has matching units to the target dwg?

MichielValcke_0-1761555419092.png

 

0 Likes
Accepted solutions (3)
1,480 Views
13 Replies
Replies (13)
Message 2 of 14

paullimapa
Mentor
Mentor

Perhaps try prior to insert set these to 0 first

INSUNITSDEFSOURCE, INSUNITSDEFTARGET and INSUNITS

https://www.autodesk.com/support/technical/article/caas/sfdcarticles/sfdcarticles/Blocks-xrefs-or-ra...

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 14

Michiel.Valcke
Advisor
Advisor

I looked into that, but the issue is that I don't know beforehand if the .dwg I'm inserting needs to be scaled or not. If I set it all to 0. Then the actual scale will be set to 1 (which is good) but in the case my source .dwg is in mm and my target in meter, then the block unit factor will also be 1 instead of 0.001 (which is bad).

 

So I thought that relying on the correct application of the unit scale factor by AutoCAD I would get the correct block unit factor and by setting the scale to 1 1 1 with vla-insertblock the actual scale would be set to one. But somehow the actual scale gets set to 1000? 

 

0 Likes
Message 4 of 14

paullimapa
Mentor
Mentor

Any difference if you use the actual Insert command to bring in the mm block into your Meter dwg?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 14

Michiel.Valcke
Advisor
Advisor

yes, when using (command "-insert" "rec" '(0 0 0) 1 1 0) - a regular block will insert correctly, but using that code a block with attributes will throw up the 'fill in attributes' dialog box and halt the routine. If I try to insert the block with (entmake ...) I need to be able to determine beforehand if there are attributes or not, which I don't know how to do from external .dwg's. If I presume there are no attributes, the blockdefinitions will enter 'broken' and need attsync's before they are fully functional again. 😞

so the vla-insertblock looked like the most promising method. In theory I could try and check the scale and rescale the block after insertion, but that is something I would like to avoid if possible. Preferably by knowing if there is a part of the method I'm not correctly using. My second preferred option would be to know if there is a system variable that I could set before and after the routine. Scaling block inserts after insertion, would be my last fix 😕 

So far I haven't found anything by myself to help me for the first two options. So I'm putting it here before trying the last option.

 

0 Likes
Message 6 of 14

Michiel.Valcke
Advisor
Advisor
Accepted solution

This is an example excerpt from vlax-dump-object on the block in the above demo .dwg

Application (RO) = #<VLA-OBJECT IAcadApplication 00007ff6663b2cc0>
; Document (RO) = #<VLA-OBJECT IAcadDocument 000001d3e1e67a78>
; EffectiveName (RO) = "rec"
; EntityTransparency = "ByLayer"
; Handle (RO) = "2FD"
; HasAttributes (RO) = 0
; HasExtensionDictionary (RO) = 0
; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 000001d3de4ec6e8>
; InsertionPoint = (0.0 0.0 0.0)
; InsUnits (RO) = "Millimeters"
; InsUnitsFactor (RO) = 0.001
; IsDynamicBlock (RO) = 0
; Layer = "0"
; Linetype = "ByLayer"
; LinetypeScale = 1.0
; Lineweight = -1
; Material = "ByLayer"
; Name = "rec"
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 42
; ObjectName (RO) = "AcDbBlockReference"
; OwnerID (RO) = 43
; PlotStyleName = "ByLayer"
; Rotation = 0.0
; TrueColor = #<VLA-OBJECT IAcadAcCmColor 000001d3de71fd80>
; Visible = -1
; XEffectiveScaleFactor = 1000.0
; XScaleFactor = 1.0
; YEffectiveScaleFactor = 1000.0
; YScaleFactor = 1.0
; ZEffectiveScaleFactor = 1000.0
; ZScaleFactor = 1.0

 

Now that I look at the difference between the EffectiveScaleFactor, the regular ScaleFactor and the InsUnitsFactor. I think I have figured it out and don't see a way around it. The vla-insertblock method probably takes what it receives as a scale to be the regular scalefactor, Autocad determines the InsUnitsFactor and then the method recalculates the EffectiveScaleFactor so that the regular ScaleFactor can be maintained 😞

I guess I'll have to look at a different kind of solution
@paullimapa do you know a way to get the units from a .dwg if you only have the filename (full url) and it is not the active .dwg?

0 Likes
Message 7 of 14

paullimapa
Mentor
Mentor
Accepted solution

Usually these are the setvar I do prior to block insert to handle blocks with attributes 

(setvar "attreq" 0) ; disables request to enter values
(setvar "attdia" 0) ; disables dialog
(setvar "osnapcoord" 1) ; overrides running osnaps

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 8 of 14

Michiel.Valcke
Advisor
Advisor

Thx @paullimapa  I forgot about attreq. I'll try to see if I can work with it and change the routine to fit it, otherwise I'll do a scale check after insertion and rescale if necessary

 

 

0 Likes
Message 9 of 14

paullimapa
Mentor
Mentor

You are welcome…cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 10 of 14

paullimapa
Mentor
Mentor

here's an option assuming the drawing is already a block in the current dwg:

(defun get_blk_unt (blknam)
 (vlax-get-property (vla-item (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object))) blknam) "Units")
) 

Use the above function passing the block name to get the block definition to find the block's unit and then you insert the block in the dwg. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 11 of 14

Michiel.Valcke
Advisor
Advisor

that is a nice and concise way, and I'll be able to use in one of the conditionals of the routine, for the blocks being inserted from an external .dwg I'll have to scale after insertion. I think that will be the cleanest solution.

Thank you.

0 Likes
Message 12 of 14

paullimapa
Mentor
Mentor
Accepted solution

use the following code to get the units of a block from another dwg:

; get_odbx_blk_unt get unit of block inside another dwg
; Arguments:
; dwgnam = drawing name
; blknam = block name
; Example:
; (get_odbx_blk_unt "C:\\Users\\PauLpc\\Downloads\\SQ.dwg" "Test")
(defun get_odbx_blk_unt (dwgnam blknam / oDBX uni)
 (vl-load-com)
 (if 
   (vl-catch-all-error-p 
     (setq oDBX
      (vl-catch-all-apply 'vla-getinterfaceobject
       (list (vlax-get-acad-object)
        (if (< (setq oVer (atoi (getvar 'acadver))) 16)
           "objectdbx.axdbdocument"
           (strcat "objectdbx.axdbdocument." (itoa oVer))
        )
       )
      )
     )
   )
   (progn
     (princ "\nUnable to interface with ObjectDBX.")
     (setq oDBX nil)
   )
   (progn 
     (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-open (list odbx dwgnam)))
      (princ (strcat "\nError Opening Drawing: " dwgnam))
       (progn
        (setq uni (vlax-get-property (vla-item (vla-get-Blocks oDBX) blknam) "Units"))
       )
     )
     (vlax-release-object oDBX) 
   )
  ) ; if
 uni
)

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 13 of 14

Michiel.Valcke
Advisor
Advisor

This is beautiful, thank you so much.

0 Likes
Message 14 of 14

paullimapa
Mentor
Mentor

You are welcome and as long as you’re running AutoCAD 2021 and up that’s the perfect time to use the -InsertContent command:

https://help.autodesk.com/view/ACD/2025/ENU/?guid=GUID-B5D64510-561E-4FA9-8AD6-625445CCD81F


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes