Author Topic: ObjectDBX Xref for block  (Read 19706 times)

0 Members and 1 Guest are viewing this topic.

OcCad

  • Guest
ObjectDBX Xref for block
« on: October 31, 2007, 03:08:21 PM »
[Backround] We typically xref all our details to paperspace as to ignore multiple scales on one sheet and creating lots of viewports in paper space. We keep each detail in a separate file, each of which we can paste on any drawing, copy to other projects, and manage as a separate component. It also makes it easy for multiple users to work on details that appear on the same sheet.

I am curious to find a way to create a lisp routine that will access a variable within the xref to scale it down from 1:1 to paperspace scale. I have done a lot of research and it seems as if there is no way (not even through ObjectDBX) to access the dimscale of an unopened drawing.

Also there has been mention of creating dictionaries/libraries that hold the dimscale value (whether it be xdata or xrecords) for all our details in our typical detail library so that they may be accessed later from a lisp routine but would that work for project specific details created later?

Lastly, there has been some light as to opening the xref through DBX, scanning it for a block's scale factor (detail border typically used) and then using that as my variable. Only thing is that I dont know how to, after inserting, find the scale of a nested block with a known name.

My desired result would be to browse for a drawing, attach it through the normal dialouge box (with options such as overlay or attach), after insertion the xref to scale down, then at completion for the command line to tell me what was inserted and to what scale. I'm open to all suggestions. Thank you in advance

Guest

  • Guest
Re: ObjectDBX Xref for block
« Reply #1 on: October 31, 2007, 04:10:35 PM »
What about blocks that react to the drawing's annotations scale??

Oh....wait... what version of AutoCAD are you using??!?

mkweaver

  • Bull Frog
  • Posts: 352
Re: ObjectDBX Xref for block
« Reply #2 on: November 01, 2007, 07:15:29 AM »
One thought I have had, since our workflow is similar, is to select a piece of text/mtext in the block/xref that has(is) the scale factor and scale it from there.  Not quite as nice as being able to scale it as it's attached.

Another method would be to have a block inserted in the detail xref that contains the scale factor, either as an attribute value, or possibly as xdata.  This scale could then be found and used by your insertion routine.

Joe Burke

  • Guest
Re: ObjectDBX Xref for block
« Reply #3 on: November 01, 2007, 08:40:29 AM »

Lastly, there has been some light as to opening the xref through DBX, scanning it for a block's scale factor (detail border typically used) and then using that as my variable. Only thing is that I dont know how to, after inserting, find the scale of a nested block with a known name.


Here's some code which demonstrates use of the XrefDatabase object. It does not use ObjectDBX.

Program flow might be something like this.
1. Check the active drawing for any existing xrefs and make a list of xref names.
   Assign symbol exnamelst to that list.
2. Xref all the details.
3. Step through the blocks collection again looking new xrefs using the existing
   xref name list to eliminate those as below.

Totally untested, but I hope it offers some ideas.

Code: [Select]
  (setq blocks
    (vla-get-blocks
      (vla-get-activedocument
        (vlax-get-acad-object))))
  (vlax-for xref blocks
    (if
      (and
        (eq acTrue (vla-get-IsXRef xref))
        (not (vl-position (vlax-get xref 'Name) exnamelst))
      )
      (vlax-for blk (vla-get-blocks (vlax-get xref 'XrefDatabase))
        (if
          (and
            (eq "KnownBorderName" (vlax-get blk 'Name))
            (equal (setq xscale (vlax-get blk 'XScaleFactor))
                   (vlax-get blk 'YScaleFactor)
                   1e-4
            )
          )
          (progn
            (setq xscale (/ 1.0 xscale))
            (vlax-put xref 'XScaleFactor xscale)
            (vlax-put xref 'YScaleFactor xscale)
            (vlax-put xref 'ZScaleFactor xscale)
          )
        )
      )
    )
  )

If the "KnownBorderName" block is found in an xref, the xref in the active drawing should be scaled
by the inverse of its scale factor.

OcCad

  • Guest
Re: ObjectDBX Xref for block
« Reply #4 on: November 01, 2007, 12:21:08 PM »
Matt W: We use AutoCAD2008 but our detail library has been compiled over the years so they have not been updated with annotative blocks.

Mkweaver: in our most updated typical details we do have a line of text within our detail border that has the scale factor within parenthesis. Only thing is that the entire detail library has yet to be completely updated so the older ones do not. Also our borders are either blocks or dynamic blocks so how would we scan for a line of text? If they were attriburtes, would seem a bit easier.

Joe: How am i to use this code? If i just insert it within what I have already "xscale" does not return me a value? May you please explain more?

Code: [Select]
(defun c:xrs ()
 (vl-load-com)
  (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")
 (INITDIA)
  (command "xattach" pause)

    (setq EntName (entlast))
    (setq EntData (entget EntName))
    (setq InsName (cdr (assoc 2 EntData)))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))
    (setq blocks
    (vla-get-blocks
      (vla-get-activedocument
        (vlax-get-acad-object))))

  (vlax-for xref blocks
    (if
      (and
        (eq acTrue (vla-get-IsXRef xref))
        (not (vl-position (vlax-get xref 'Name) exnamelst))
      )
      (vlax-for blk (vla-get-blocks (vlax-get xref 'XrefDatabase))
        (if
          (and
            (eq "Detail-Bdr" (vlax-get blk 'Name))
            (equal (setq xscale1 (vlax-get blk 'XScaleFactor))
                   (vlax-get blk 'YScaleFactor)
                   1e-4
            )
          )
          (progn
            (setq xscale (/ 1.0 xscale))
            (vlax-put xref 'XScaleFactor xscale)
            (vlax-put xref 'YScaleFactor xscale)
            (vlax-put xref 'ZScaleFactor xscale)
          )
        )
      )
    )
  )
   
   (command "scale" EntName "" InsPoint xscale)

;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)

And if anyone can shed some light on how I might ObjectDBX to search for "Detail-bdr" with if/thens for three possible names that would be great.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX Xref for block
« Reply #5 on: November 01, 2007, 12:23:51 PM »
Do you know how to use ActiveX controls within lisp?  You will need to know this to use ObjectDBX.

ps. Welcome to theSwamp.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

OcCad

  • Guest
Re: ObjectDBX Xref for block
« Reply #6 on: November 01, 2007, 12:30:32 PM »
T: No idea :-(

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX Xref for block
« Reply #7 on: November 01, 2007, 01:02:30 PM »
T: No idea :-(
Check out the .doc file attached in the first post here.  This will help you get started, and once you do that then you can search for 'ObjectDBX' as there are a lot of examples here using it.  When you don't understand something post back and I'm sure someone will help you through those parts.

The theory to this community is to teach instead of give code.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

OcCad

  • Guest
Re: ObjectDBX Xref for block
« Reply #8 on: November 01, 2007, 01:05:51 PM »
Hey, I wanna live not eat for a day. Thanks a bunch!  :wink:

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX Xref for block
« Reply #9 on: November 01, 2007, 01:08:28 PM »
Hey, I wanna live not eat for a day. Thanks a bunch!  :wink:
You will get along fine here then.  You're welcome.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

OcCad

  • Guest
Re: ObjectDBX Xref for block
« Reply #10 on: November 01, 2007, 01:21:56 PM »
Okay... I'm still pretty fresh to Lisp so with VBA and ActiveX and ObjectDBX things are getting a bit overwhelming. The post covers an example of copying a block from xref into current drawing and it seems as if all the "vla-... " commands are a whole other story. It leads me as far as acquiring my desired blocks but I'm confused about where to go from there. Is there another resource that can give me a list of possible commands like (vla-get-scale, vla-get-scalefactor)? Within Lisp I only know them as group codes like 41,42,43

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX Xref for block
« Reply #11 on: November 01, 2007, 01:30:42 PM »
In the help, get to 'Developer Documentation' -> ActiveX and VBA reference -> Properties...

It can be a little confusing going from the help to lisp, but once you know what you are looking for the help is really nice.  For instance 'vla-get-ScaleFactor' is a call to 'get' the property 'ScaleFactor' of an object.  So in the help you would look under the property section for 'ScaleFactor'.

Here is a simple routine that will let you select an entity and will print out what ActiveX controls are available.

Code: [Select]
(defun c:DList ()

(vlax-dump-object
(vlax-ename->vla-object
(car
(entsel "\n Select entity to see all properties and methods: ")
)
)
T
)
(textscr)
(princ)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

OcCad

  • Guest
Re: ObjectDBX Xref for block
« Reply #12 on: November 01, 2007, 01:51:21 PM »
Okay this is what i've put together so far but it is giving me a ; error: ActiveX Server returned an error: Parameter not optional."

Code: [Select]
(defun c:xrs ()
 
  (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")
 (INITDIA)
  (command "xattach" pause)

    (setq EntName (entlast))
    (setq EntData (entget EntName))
    (setq InsName (cdr (assoc 2 EntData)))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))   

 (vl-load-com)
    (setq dwgName InsName)
    (setq dbxDoc (vla-GetInterfaceObject (vlax-get-acad-object)
         ObjectDBX.AxDbDocument.16))
      (vlax-invoke dbxDoc "Open" dwgName)

    (setq dbxBlocks (vla-get-blocks dbxDoc))
      (setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))
    (setq dbxBscale (vla-get-xscalefactor dbxBlock))

    (vlax-release-object dbxDoc)
      (setq dbxDoc nil)
   
   (command "scale" EntName "" InsPoint (/ 1 dbxScale))

;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)


p.s. loved that code by the way

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: ObjectDBX Xref for block
« Reply #13 on: November 01, 2007, 01:59:09 PM »
OcCad,
Welcome to the swamp, been a busy day for me.
Looks like you are in good hands.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: ObjectDBX Xref for block
« Reply #14 on: November 01, 2007, 02:05:42 PM »
This line is what I think is causing the problem.
Code: [Select]
(setq dbxBscale (vla-get-xscalefactor dbxBlock))
The reason is that you found the blocks definition, not where it is inserted, so it has no scale property.  To find out where it is inserted there are a few ways to go.  Here is one that might be easier for you at the moment.

Once you get the block here
Code: [Select]
(setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))Convert the object to an ename
Code: [Select]
(setq dbxEname (vlax-vla-object->ename dbxBlock))Now we want to get the dxf code information from it
Code: [Select]
(setq dbxEntData (entget dbxEname))Now all the codes 331 are the inserts associated with the block, so to get the scale use
Code: [Select]
(setq dbxBlockInsert (cdr (assoc 331 dbxEntData)))
(setq dbxScale (cdr (assoc 41 (entget dbxBlockInsert))))

Hope that makes sense.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.