TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: iliekater on January 18, 2008, 07:34:55 AM

Title: Loading a block in the drawing without inserting it
Post by: iliekater on January 18, 2008, 07:34:55 AM
I know it may sound stupid but I need this in order to load an arrow block which to set it as symbols for dimensions . If that's not possible , is any other way to do this ?
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 08:18:17 AM
If the block exists in another drawing, say a 'standards' drawing, you can use ObjectDBX to import it.  You could also create it from scratch via code in the drawing.  Which would you like to do?
Title: Re: Loading a block in the drawing without inserting it
Post by: CAB on January 18, 2008, 09:00:37 AM
You can emake a BLOCK, which is then ready to be an INSERT.

Code: [Select]
;;  Example of a Entmake of a Block
;;
(defun makearrow (blockname)
  ;;==============================================
  ;;       Start of Block definition             
  ;;==============================================
  (entmake
    (list '(0 . "BLOCK") '(100 . "AcDbEntity") '(100 . "AcDbBlockBegin")
          (cons 2 blockname)  '(8 . "0")               
          '(70 . 0)                  0= No Attributes, 2= Attributes
          '(10 0.0 0.0 0.0)         
    )
  )
  ;;==============================================

  ;;==============================================
  ;;            Block objects                     
  ;;==============================================
  (entmake '((0 . "SOLID") (8 . "0") (10 66.0 -1.42109e-014 0.0) (11 52.8688 -2.32308 0.0)
             (12 52.8688 2.32308 0.0) (13 52.8688 2.32308 0.0) (39 . 0.0)))
  (entmake '((0 . "LINE") (8 . "0") (10 0.0 0.0 0.0) (11 66.0 -1.42109e-014 0.0)))
  (entmake '((0 . "LINE") (8 . "0") (10 29.1563 -16.9136 0.0) (11 33.0 -7.10543e-015 0.0)))
  (entmake '((0 . "LINE") (8 . "0") (10 23.8848 16.2547 0.0) (11 29.1563 -16.9136 0.0)))
  (entmake '((0 . "LINE") (8 . "0") (10 16.6366 -8.7863 0.0) (11 23.8848 16.2547 0.0)))
  (entmake '((0 . "LINE") (8 . "0") (10 12.1311 8.7863 0.0) (11 16.6366 -8.7863 0.0)))
  ;;==============================================

  ;;==============================================
  ;;     This is the end of block marker         
  ;;==============================================
  (entmake (list '(0 . "ENDBLK") '(100 . "AcDbBlockEnd") '(8 . "0")))
  ;;==============================================
)
Title: Re: Loading a block in the drawing without inserting it
Post by: SomeCallMeDave on January 18, 2008, 09:15:26 AM
What about something like

Code: [Select]
(setq fileName (findfile "YourBlockNameHere"))
(command "insert" FileName break)


Title: Re: Loading a block in the drawing without inserting it
Post by: iliekater on January 18, 2008, 09:19:24 AM
jbuzbee :
Quote
You can use ObjectDBX to import it.
What's ObjectDBX ? I couldn't find it in the Help files . Let me Specify here that I am using AutoCAD 2004 .

jbuzbee :
Quote
You could also create it from scratch via code in the drawing
No , the symbol sometimes is very complicated . For example one of the symbols is a skull ! Therefor I can't redraw it with code .

CAB : I didn't understand the code . I think you use the entmake to create an entinity of block that will contain some lines . Unfortunatelly I couldn't run it .  :cry:
Title: Re: Loading a block in the drawing without inserting it
Post by: iliekater on January 18, 2008, 09:24:34 AM
SomeCallMeDave :
Quote
Code: [Select]
(setq fileName (findfile "YourBlockNameHere"))
(command "insert" FileName break)

Wow , it really worked ! Thanks !

But how exactly does the "break" key work ?
Title: Re: Loading a block in the drawing without inserting it
Post by: CAB on January 18, 2008, 09:39:37 AM
You said:
is any other way to do this ?
You can entmake the block needed. All I posted was an example of making a block without inserting it.
It wasn't the block you want because you did not share that with us.
This was just an alternate solution.
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 09:43:02 AM
ObjectDBX is an undocumented ActiveX library that let's you "open" a drawing with out actuially opening it in the editor and extract data into another drawing.  I use it to import all our standards: blocks, layers, dimstyles, textstyles, annotation tags, etc.  It's very, very handy.

Title: Re: Loading a block in the drawing without inserting it
Post by: daron on January 18, 2008, 10:49:10 AM
Wouldn't it be just as easy to use the design center to update or insert a block without actually inserting it? That functionality exists through DC.
Title: Re: Loading a block in the drawing without inserting it
Post by: iliekater on January 18, 2008, 01:24:14 PM
Daron :
Quote
Wouldn't it be just as easy to use the design center to update or insert a block without actually inserting it?
It would be easy but code is much faster !

jbuzbee :
Quote
ObjectDBX is an undocumented ActiveX library that let's you "open" a drawing with out actuially opening it in the editor and extract data into another drawing.
Sounds very interesting . Maybe it's a silly question , but where do I find it ? I can load as an ARX ?

CAB :
Quote
It wasn't the block you want because you did not share that with us.
Well it smells like powder here , yet I'll add a frase from my initial post :
Quote
I need this in order to load an arrow block
Title: Re: Loading a block in the drawing without inserting it
Post by: daron on January 18, 2008, 01:44:44 PM
What I used to do when I wanted a drawing in the DB, but not the drawing space itself is insert it to the center of the screen and erase it, through code of course.
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 01:48:15 PM
This is my Import Block routine - The majority of the code was originally penned by Tony Tanzillo. (thanks Tony!)

Code: [Select]
;;; ObjectDBX functions
;;;
;;;
(vl-load-com)

;This will load the ObjectDBX activex module
(if (< (atoi (getvar "AcadVer")) 16)
  (cond ((vl-registry-read "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"))
        ((not (setq dbxserver (findfile "AxDb15.dll")))
         (alert "Error: Can't locate ObjectDBX Library (AxDb15.dll)"))
        (t
         (startapp "regsvr32.exe" (strcat "/s \"" dbxserver "\""))
         (or (vl-registry-read "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID")
             (alert "Error: Failed to register ObjectDBX ActiveX services.")))))

;;;(setq dwgname(findfile "AecLayerStd.dwg"))
;;; Open a dbxDoc ;
;;; use (setq dbxDocument(jb:OpenDbxDocument dwgname)) ;
(defun jb:OpenDbxDocument  (DwgName / app doc dbxopen dbxDoc)
  (setq app (vlax-get-acad-object)
        doc (vla-get-ActiveDocument app))
  (if (/= dwgname (vla-get-fullname doc))
    (progn (cond ((= (substr (getvar "ACADVER") 1 5) "15.06")
                  (setq dbxDoc  (vla-GetInterfaceObject app "ObjectDBX.AxDbDocument")
                        dbxopen (vl-catch-all-apply 'vla-open (list dbxDoc DwgName))))
                 (t
                  (setq dbxDoc  (vla-GetInterfaceObject
                                  app
                                  (strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2)))
                        dbxopen (vl-catch-all-apply 'vla-open (list dbxDoc DwgName)))))
           (if (vl-catch-all-error-p dbxopen)
             (setq dbxDoc nil))))
  dbxDoc)

;;; (vlax-dump-Object dbxDoc t)
;;; Close dbxDoc
;;; (jb:CloseDbxDocument dbxDocument)
(defun jb:CloseDbxDocument  (dbxdoc)
  (if (= (type dbxDoc) 'VLA-OBJECT)
    (progn (vlax-release-object dbxDoc) (setq dbxDoc nil))))

;;; ;
;;; Import a Block from a DBX Document ;
;;; Arguments: dwg; a valid drawing name and path ;
;;;   block; name of the block to import ;
;;; Return: the block object ;
;;; ;

(defun jb:ImportBlock  (dwg block / dbxDoc bb dbb newblk)
  (if dwg
    (setq dbxDoc (jb:OpenDbxDocument dwg)))
  (if dbxDoc
    (progn (setq bb  (vla-get-blocks dbxDoc)
                 dbb (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))))
           (if (not
                 (vl-catch-all-error-p (vl-catch-all-apply 'vla-item (list bb block))))
             (setq newblk (vl-catch-all-apply
                            'vla-CopyObjects
                            (list dbxDoc
                                  (vlax-safearray-fill
                                    (vlax-make-safearray vlax-vbObject '(0 . 0))
                                    (list (vla-item bb block)))
                                  dbb))))))
  (if dbxdoc
    (jb:closedbxdocument dbxDoc))
  newblk)

;;; ;
;;; Import Multiple Blocks from a DBX Document ;
;;; Arguments: dwg; a valid drawing name and path ;
;;;   listofblocks; list of names to import;
;;; Return: the block object ;
;;; ;


(defun jb:ImportBlocks  (dwg listofblocks / dbxDoc ii bb dbb newblk blockstoImport)
  (if dwg
    (setq dbxDoc (jb:OpenDbxDocument dwg)))
  (if dbxDoc
    (progn (setq bb  (vla-get-blocks dbxDoc)
                 dbb (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))))
      (foreach i listofblocks
           (if (not
                 (vl-catch-all-error-p (vl-catch-all-apply 'vla-item (list bb i))))
    (setq blockstoImport(append blockstoImport(list i)))))
      (if blockstoImport
(foreach ii blockstoImport
             (setq newblk (vl-catch-all-apply
                            'vla-CopyObjects
                            (list dbxDoc
                                  (vlax-safearray-fill
                                    (vlax-make-safearray vlax-vbObject '(0 . 0))
                                    (list (vla-item bb ii)))
                                  dbb)))))))
  (if dbxdoc
    (jb:closedbxdocument dbxDoc))
  (vlax-release-object dbb)
  newblk)
 
;;; ;
;;; Return Block list from a DBX Document ;
;;; Arguments: dwg; a valid drawing name and path ;
;;;   ;
;;; Return: List of strings ;
;;; ;

(defun jb:ReturnDBXBlocks  (dwg / dbxDoc ret)
  (if dwg
    (setq dbxDoc (jb:OpenDbxDocument dwg)))
  (if dbxDoc
    (progn (vlax-for x(vla-get-blocks dbxDoc)
           (if (and(= (vlax-get x 'isxref) 0)
                   (not(vl-string-search(chr 42)(vla-get-name x)))
                      (not(vl-string-search(chr 124)(vla-get-name x))))
                
             (setq ret (append ret(list (vla-get-name x))))))))
  (if dbxdoc
    (jb:closedbxdocument dbxDoc))
  ret)

Notice that this accesses the dbxDocuments "Block" collection.  These functions can be easily modified to access any collection: Layers, Views, etc.  Also remember that ModelSpace and PaperSpace(s) are Blocks.  So you can access graphical data as well.
Title: Re: Loading a block in the drawing without inserting it
Post by: T.Willey on January 18, 2008, 02:19:32 PM
This is my Import Block routine - The majority of the code was originally penned my Tony Tanzillo. (thanks Tony!)
 
<snip>

A little TMI JB.   :wink:
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 02:22:17 PM
oops.  I've been seizing allot today.  time to get off the computer . . ..
Title: Re: Loading a block in the drawing without inserting it
Post by: T.Willey on January 18, 2008, 02:38:30 PM
oops.  I've been seizing allot today.  time to get off the computer . . ..
I hope everything is alright, and it is always a good thing to get off the computer every now and then.
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 02:45:16 PM
Yea. I'm alright - thanks.  Stress and the monitor (not to mention the stuff used to relieve said stress) is taking a toll.  But - I'm getting close to never needing to be on a computer - ever.  (reason for said stress).

jb

Title: Re: Loading a block in the drawing without inserting it
Post by: T.Willey on January 18, 2008, 03:08:09 PM
Yea. I'm alright - thanks.  Stress and the monitor (not to mention the stuff used to relieve said stress) is taking a toll.  But - I'm getting close to never needing to be on a computer - ever.  (reason for said stress).

jb
I'm sure it will all work out for the best in the end, but until then I hope you can take some time a relax, and forget about the stress.  Good luck to you, and I hope one day to be there (never needing a computer) too.
Title: Re: Loading a block in the drawing without inserting it
Post by: CAB on January 18, 2008, 03:54:35 PM
CAB :
Quote
It wasn't the block you want because you did not share that with us.
Well it smells like powder here , yet I'll add a frase from my initial post :
Quote
I need this in order to load an arrow block

OK, here is an example. I have a lisp that produces the core code by selecting the block in a drawing.
You then place this code in your ACADdoc.lsp file and when you open a drawing the block is created if
it doesn't exist.
Note, this is just an example, post a drawing with your arrowhead inserted in it & I will give you the code for it.
Code: [Select]
(defun eMakeArchTick ()
  (entmake '((0 . "BLOCK") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockReference")
  (2 . "_ArchTick") (10 0.0 0.0 0.0) (70 . 0)))
  (entmake '((0 . "LWPOLYLINE") (100 . "AcDbEntity") (67 . 0) (8 . "0") (62 . 0) (100 . "AcDbPolyline")
  (90 . 2) (70 . 0) (43 . 0.15) (38 . 0.0) (39 . 0.0) (10 -0.5 -0.5) (40 . 0.15) (41 . 0.15)
  (42 . 0.0) (10 0.5 0.5) (40 . 0.15) (41 . 0.15) (42 . 0.0)))
  (entmake '((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
  (princ)
)
(or (tblserch "BLOCK"  "_ArchTick") (eMakeArchTick)) ; make the block
Title: Re: Loading a block in the drawing without inserting it
Post by: JohnK on January 18, 2008, 04:06:38 PM
Object DBX is very cool but also fickle.

That code you posted from Tony worked good, but i have an ``improved'' version i hacked together somewhere in my files. I will see if i can locate it if you would like.
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 04:57:09 PM
Quote
Object DBX is very cool but also fickle.

I havn't had any problems at all.  My programs that use ObjectDBX:

Import Layers
(http://www.studio2405.com/jdb/iml.jpg)

Working States - reads Layer States in an external standards drawing to set active drawings layers
(http://www.studio2405.com/jdb/ws.jpg)

Import Views
(http://www.studio2405.com/jdb/iv.jpg)

Block Manager
(http://www.studio2405.com/jdb/bm.jpg)


Detail Manager
(http://www.studio2405.com/jdb/dm-01.gif)

What types of problems have you had?  There are some limitations you have to be aware of.
Title: Re: Loading a block in the drawing without inserting it
Post by: JohnK on January 18, 2008, 05:22:12 PM
no problems, works great, continue on, have fun.
Title: Re: Loading a block in the drawing without inserting it
Post by: iliekater on January 18, 2008, 05:34:21 PM
Daron :
Quote
Insert it to the center of the screen and erase it
Yes , you are right . I thought about that back there but forgot to ask . You see inserting a block and erasing it will do the trick , but one cannot erase it by selecting it as the last object because it may not be visible . Therefor , is there a way to get the middle of the current view ?

jbuzbee , let me ask you something : how did you make those wonderful snapshots ? I use the PrintScreen and paste it on the Paint program , but I never manage to select correctly the margins of the dialog boxes ...
Title: Re: Loading a block in the drawing without inserting it
Post by: ronjonp on January 18, 2008, 05:39:56 PM
You could use something like this:

(vla-delete (vlax-ename->vla-object (entlast)))


I'd use CAB's entmake method....
Title: Re: Loading a block in the drawing without inserting it
Post by: jbuzbee on January 18, 2008, 05:59:59 PM
iliekater:

I use photoshop - don't know about paint - but when you start a new file in photoshop it checks the clipboard for a default size . . . paste, done.
Title: Re: Loading a block in the drawing without inserting it
Post by: daron on January 18, 2008, 06:10:27 PM
Daron :
Quote
Insert it to the center of the screen and erase it
Therefor , is there a way to get the middle of the current view ?
Insert block with:
(getvar 'viewctr)
and then erase "last" shouldn't give a problem, unless the insertion point and the objects in the block are too far away from each other.
Title: Re: Loading a block in the drawing without inserting it
Post by: daron on January 18, 2008, 06:12:03 PM
iliekater:

I use photoshop - don't know about paint - but when you start a new file in photoshop it checks the clipboard for a default size . . . paste, done.
GIMP's good at that too, if you can't afford PS.
Title: Re: Loading a block in the drawing without inserting it
Post by: iliekater on January 19, 2008, 12:34:46 PM
Yes , Photoshop seems a good idea . First paste the whole picture , use the magic wand and then "select inverse" , cut and paste it on another file (which as jbuzbee said , is initialy made on the dimensions of the picture stored in the clipboard) . Thanks .

I am off to try what you said about erasing the last objects (entinities) .
Title: Re: Loading a block in the drawing without inserting it
Post by: MP on January 19, 2008, 12:43:26 PM
Off topic but in Paint Shop Pro (http://www.corel.com/servlet/Satellite/us/en/Product/1184951547051) one just pastes to new image. If the original screen capture is via <alt> <prtscn> poof | wallah -- no trimming required.

Of course there's always SnagIt (http://www.techsmith.com/screen-capture.asp) if one's real lazy.

:)