Jump to content

Each unique block reference to separate DXF file


Skierz

Recommended Posts

Hi,

I hope you guys are doing well!
I want help from you guys regarding some task involving blocks in the AutoCAD .I was wondering if it is possible through lisp.
So here is the explanation of the flow of the process-
 

  • Allow user to select multiple blocks (through method such as window, crossing polygon,etc)
  • Filter out the unique block references/names from the above selection set. (For Eg- Suppose user select the 30 blocks  (10 each instances of block named as test1, test2 , test3) , then here we need to filter out three unique block reference namely test1, test2 ,test3)
  • Create a separate DXF files for each unique block reference with the same name as that of the respective block in the drawing. These DXF files should be automatically saved in the same path and directory as that of dwg. (For Eg- If there are three unique block reference in the drawing named as test1, test2, test3 , so three DXF files should be created named as test1.dxf , test2.dxf, test3.dxf saved in the same path as that of dwg)
  • Each DXF file created should contain only the single instance of the respective block with default properties of rotation (value zero) and scale (value one) and unit.(For Eg- Suppose the drawing contain the multiple instance of the block "test1" at different rotation and different scale value but the DXF file created for this block (test1.dxf) should contain the single instance of the test1 block with default value of rotation (zero value) and scale (value one) .Same logic goes for other blocks)


Note- I am not aware of the block details (name,etc) beforehand since the already created dwg is provided to me 

I am attaching the sample dwg for reference .

Thanks

Blocks_SD_CT.dwg
 

Link to comment
Share on other sites

6 hours ago, BIGAL said:

Any way wblock will do what you want export individual blocks.


@BIGAL
But WBlock export only one block at a time .I want something like selection of multiple blocks and exporting each unique block to separate file .
Also, my first priority is to get them exported in .dxf format. 
If not possible then ,somehow I will manage with dwg format 

Thanks

 

Link to comment
Share on other sites

Actually what the OP describes does not match the behavior of the Wblock command. The OP wants an insert of the block in the file. Which, BTW, would be a bad idea (recursion) if the file is then inserted as a block.

Link to comment
Share on other sites

2 hours ago, Roy_043 said:

Actually what the OP describes does not match the behavior of the Wblock command. The OP wants an insert of the block in the file. Which, BTW, would be a bad idea (recursion) if the file is then inserted as a block.


No I want to use  the block in other application (hence DXF format is desirable) and will not re-use the blocks in the AutoCAD

Link to comment
Share on other sites

Change the DXF version and accuracy to suit:

(defun KGA_Conv_Pickset_To_ObjectList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) ret))
    )
  )
)

(defun c:Exp2Dxf ( / doneLst fld fnm nme ref spc ss)
  (if
    (and
      (or
        (= 1 (getvar 'dwgtitled))
        (prompt "\nError: DWG must be saved first ")
      )
      (setq ss (ssget '((0 . "INSERT"))))
    )
    (progn
      (setq fld (getvar 'dwgprefix))
      (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (foreach obj (KGA_Conv_Pickset_To_ObjectList ss)
        (if (not (vl-position (strcase (setq nme (vla-get-effectivename obj))) doneLst))
          (progn
            (setq doneLst (cons (strcase nme) doneLst))
            (setq ref (vla-insertblock spc (vlax-3d-point 0.0 0.0 0.0) nme 1.0 1.0 1.0 0.0))
            (vla-put-layer ref "0")
            (command "_.zoom" "_object" (vlax-vla-object->ename ref) "")
            (setq fnm (strcat fld nme ".dxf"))
            (vl-file-delete fnm) ; Delete existing file.
            (command
              "_.dxfout"
              fnm ; Full path.
              "_entities"
              (vlax-vla-object->ename ref)
              ""
              "_version"
              "2000"  ; Valid DXF version.
              6       ; Accuracy
            )
            (vla-delete ref)
          )
        )
      )
    )
  )
  (princ)
)

 

  • Like 1
Link to comment
Share on other sites

Roy beat me to it but here's another to export to DWG :)

(defun c:exportblocks (/ c n p s)
  ;; RJP » 2020-05-14
  (cond	((and (setq s (ssget '((0 . "insert"))))
	      (or (vl-file-directory-p (setq p (strcat (getvar 'dwgprefix) "_ExportedBlocks\\")))
		  (vl-mkdir p)
	      )
	      (setq s (vl-remove-if 'listp (mapcar 'cadr (ssnamex s))))
	 )
	 (setvar 'filedia 0)
	 (setvar 'cmdecho 0)
	 (foreach x s
	   (cond ((not (member (setq n (vla-get-effectivename (vlax-ename->vla-object x))) c))
		  (command "._-wblock" (strcat p n) n)
		  (setq c (cons n c))
		 )
	   )
	 )
	 (setvar 'filedia 1)
	 (setvar 'cmdecho 1)
	)
  )
  (princ)
)
(vl-load-com)

 

Edited by ronjonp
  • Like 1
Link to comment
Share on other sites

8 minutes ago, Tharwat said:

@ronjonp you may need to correct the file name with the variable 'n' instead of the entity name. 

Ooops 😳 Fixed .. thanks!

Link to comment
Share on other sites

On 5/14/2020 at 6:44 PM, Roy_043 said:

Change the DXF version and accuracy to suit:


(defun KGA_Conv_Pickset_To_ObjectList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) ret))
    )
  )
)

(defun c:Exp2Dxf ( / doneLst fld fnm nme ref spc ss)
  (if
    (and
      (or
        (= 1 (getvar 'dwgtitled))
        (prompt "\nError: DWG must be saved first ")
      )
      (setq ss (ssget '((0 . "INSERT"))))
    )
    (progn
      (setq fld (getvar 'dwgprefix))
      (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (foreach obj (KGA_Conv_Pickset_To_ObjectList ss)
        (if (not (vl-position (strcase (setq nme (vla-get-effectivename obj))) doneLst))
          (progn
            (setq doneLst (cons (strcase nme) doneLst))
            (setq ref (vla-insertblock spc (vlax-3d-point 0.0 0.0 0.0) nme 1.0 1.0 1.0 0.0))
            (vla-put-layer ref "0")
            (command "_.zoom" "_object" (vlax-vla-object->ename ref) "")
            (setq fnm (strcat fld nme ".dxf"))
            (vl-file-delete fnm) ; Delete existing file.
            (command
              "_.dxfout"
              fnm ; Full path.
              "_entities"
              (vlax-vla-object->ename ref)
              ""
              "_version"
              "2000"  ; Valid DXF version.
              6       ; Accuracy
            )
            (vla-delete ref)
          )
        )
      )
    )
  )
  (princ)
)

 


@Roy_043 fantastic code. It is working well. Thank you for looking into my request
Just one small change request ,is it possible to create a subfolder  (to store these exported dxf block files) in the same directory as that of dwg.
The subfolder can be named in the format such as "Drawing Name -Exported Blocks" which will be easy to organize and follow up.
For eg- If the drawing file name is floorplan.dwg ,  a subfolder should be created named as "floorplan-Exported Blocks" to store the exported dxf block files.

Don't know how difficult is this change request as I have very basic knowledge of lisp

Thanks for consideration
Have a nice day!!

Edited by Skierz
Link to comment
Share on other sites

6 hours ago, Skierz said:


@Roy_043 fantastic code. It is working well. Thank you for looking into my request
Just one small change request ,is it possible to create a subfolder  (to store these exported dxf block files) in the same directory as that of dwg.
The subfolder can be named in the format such as "Drawing Name -Exported Blocks" which will be easy to organize and follow up.
For eg- If the drawing file name is floorplan.dwg ,  a subfolder should be created named as "floorplan-Exported Blocks" to store the exported dxf block files.

Don't know how difficult is this change request as I have very basic knowledge of lisp

Thanks for consideration
Have a nice day!!

 

I'll be your guidance in this matter... It's a very small line added, but that's about it.

 

(defun KGA_Conv_Pickset_To_ObjectList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) ret))
    )
  )
)

(defun c:Exp2Dxf ( / doneLst fld fnm nme ref spc ss)
  (if
    (and
      (or
        (= 1 (getvar 'dwgtitled))
        (prompt "\nError: DWG must be saved first ")
      )
      (setq ss (ssget '((0 . "INSERT"))))
    )
    (progn
      (setq fld (getvar 'dwgprefix))

      ;; Added line by Jonathan Handojo
      
      (if (null (vl-file-directory-p (setq fld (strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)) "-Exported Blocks\\"))))
	  (vl-mkdir fld)
	  )
      
      ;; That's all the change
      
      (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (foreach obj (KGA_Conv_Pickset_To_ObjectList ss)
        (if (not (vl-position (strcase (setq nme (vla-get-effectivename obj))) doneLst))
          (progn
            (setq doneLst (cons (strcase nme) doneLst))
            (setq ref (vla-insertblock spc (vlax-3d-point 0.0 0.0 0.0) nme 1.0 1.0 1.0 0.0))
            (vla-put-layer ref "0")
            (command "_.zoom" "_object" (vlax-vla-object->ename ref) "")
            (setq fnm (strcat fld nme ".dxf"))
            (vl-file-delete fnm) ; Delete existing file.
            (command
              "_.dxfout"
              fnm ; Full path.
              "_entities"
              (vlax-vla-object->ename ref)
              ""
              "_version"
              "2000"  ; Valid DXF version.
              6       ; Accuracy
            )
            (vla-delete ref)
          )
        )
      )
    )
  )
  (princ)
)

 

Link to comment
Share on other sites

On 5/16/2020 at 7:02 AM, Jonathan Handojo said:

I'll be your guidance in this matter... It's a very small line added, but that's about it.


@Jonathan Handojo @Roy_043   I would like to highlight one issue which I am facing because of this program - that my drawing save template/environment is changed and it is set to DXF default . Even if I am opening existing drawing files or creating new files in which I don't want to run this program, the save/saveas command is giving dxf default option which is quite irritating. (refer below image)

image.thumb.png.22b25e718a7c8400302c34ade2b7778f.png

 Can you guys please modify this program so that it restore the default settings after its completion  ?

Thanks 

Edited by Skierz
Link to comment
Share on other sites

BricsCAD uses a SAVEFORMAT setting and the _DxfOut command does not change this setting.

In AutoCAD, apparently (https://www.cadforum.cz/cadforum_en/qaID.asp?tip=6439), this approach should be used:

(defun KGA_Conv_Pickset_To_ObjectList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) ret))
    )
  )
)

(defun c:Exp2Dxf ( / doneLst fld fnm nme oldFormat ref spc ss)
  (if
    (and
      (or
        (= 1 (getvar 'dwgtitled))
        (prompt "\nError: DWG must be saved first ")
      )
      (setq ss (ssget '((0 . "INSERT"))))
    )
    (progn
      (setq oldFormat (getenv "DefaultFormatForSave")) ; https://www.cadforum.cz/cadforum_en/qaID.asp?tip=6439
      (setq fld (strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)) "-Exported Blocks\\"))
      (if (not (vl-file-directory-p fld))
        (vl-mkdir fld)
      )
      (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (foreach obj (KGA_Conv_Pickset_To_ObjectList ss)
        (if (not (vl-position (strcase (setq nme (vla-get-effectivename obj))) doneLst))
          (progn
            (setq doneLst (cons (strcase nme) doneLst))
            (setq ref (vla-insertblock spc (vlax-3d-point 0.0 0.0 0.0) nme 1.0 1.0 1.0 0.0))
            (vla-put-layer ref "0")
            (command "_.zoom" "_object" (vlax-vla-object->ename ref) "")
            (setq fnm (strcat fld nme ".dxf"))
            (vl-file-delete fnm) ; Delete existing file.
            (command
              "_.dxfout"
              fnm ; Full path.
              "_entities"
              (vlax-vla-object->ename ref)
              ""
              "_version"
              "2000"  ; Valid DXF version.
              6       ; Accuracy
            )
            (vla-delete ref)
          )
        )
      )
      (setenv "DefaultFormatForSave" oldFormat)
    )
  )
  (princ)
)

 

Link to comment
Share on other sites

16 hours ago, Roy_043 said:

BricsCAD uses a SAVEFORMAT setting and the _DxfOut command does not change this setting.

In AutoCAD, apparently (https://www.cadforum.cz/cadforum_en/qaID.asp?tip=6439), this approach should be used:


(defun KGA_Conv_Pickset_To_ObjectList (ss / i ret)
  (if ss
    (repeat (setq i (sslength ss))
      (setq ret (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) ret))
    )
  )
)

(defun c:Exp2Dxf ( / doneLst fld fnm nme oldFormat ref spc ss)
  (if
    (and
      (or
        (= 1 (getvar 'dwgtitled))
        (prompt "\nError: DWG must be saved first ")
      )
      (setq ss (ssget '((0 . "INSERT"))))
    )
    (progn
      (setq oldFormat (getenv "DefaultFormatForSave")) ; https://www.cadforum.cz/cadforum_en/qaID.asp?tip=6439
      (setq fld (strcat (getvar 'dwgprefix) (vl-filename-base (getvar 'dwgname)) "-Exported Blocks\\"))
      (if (not (vl-file-directory-p fld))
        (vl-mkdir fld)
      )
      (setq spc (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (foreach obj (KGA_Conv_Pickset_To_ObjectList ss)
        (if (not (vl-position (strcase (setq nme (vla-get-effectivename obj))) doneLst))
          (progn
            (setq doneLst (cons (strcase nme) doneLst))
            (setq ref (vla-insertblock spc (vlax-3d-point 0.0 0.0 0.0) nme 1.0 1.0 1.0 0.0))
            (vla-put-layer ref "0")
            (command "_.zoom" "_object" (vlax-vla-object->ename ref) "")
            (setq fnm (strcat fld nme ".dxf"))
            (vl-file-delete fnm) ; Delete existing file.
            (command
              "_.dxfout"
              fnm ; Full path.
              "_entities"
              (vlax-vla-object->ename ref)
              ""
              "_version"
              "2000"  ; Valid DXF version.
              6       ; Accuracy
            )
            (vla-delete ref)
          )
        )
      )
      (setenv "DefaultFormatForSave" oldFormat)
    )
  )
  (princ)
)

 


@Roy_043 thanks for your helping hand. This fixed the issue.
I just wanted to add a final prompt to be displayed at the command line after the program completion , using something like
(prompt "\n "x" blocks exported as a dxf file")

Now the main challenge for me is how to calculate value of x (which is the no of blocks exported as dxf files) since it will differ from case to case. For some cases, it may be 3 blocks , for other it may be 10 blocks and so on.

Thanks


 

Link to comment
Share on other sites

Good to hear that the solution works.

 

A tip regarding your challenge: Inside the foreach loop the doneLst gets updated. One item is added to the list for each DXF created.

Link to comment
Share on other sites

Roy-043 has given a good method

 

hint1 (length list)

 

hint2 (+ x 1) and (alert (strcat "there was " (rtos x 2 0) " blocks changed"))

 

Link to comment
Share on other sites

17 hours ago, Roy_043 said:

Good to hear that the solution works.

 

A tip regarding your challenge: Inside the foreach loop the doneLst gets updated. One item is added to the list for each DXF created.


Thanks @Roy_043 @BIGAL for your guidance. Since I am quite a novice in LISP , so after doing some research based on the given hints, I completed this part succesfully 😀

(setq ct (length doneLst))
(prompt (strcat "\nNumber of blocks exported as DXF file - "(rtos ct 2 0)" "))

Here is the snapshot of the result obtained for one of the case (it is working fine)
image.png.ccae647dce782113ae1a8ed5d3795466.png


Thanks 

Link to comment
Share on other sites

Alert will pop a dialogue onto the screen and you have to click ok to continue v's Prompt or Princ which will display on command line.

 

Alert can be multi line answer note the \n 

 

(alert (strcat "You have (rtos x 2 0) " Blocks \nAnd they were on layer " lay))

 

For  Briscad users \n \n for multi line a reported issue to Bricscad.

 

I use alert where you want a user to read a message maybe (alert "To use type Exp2Dxf")

 

 

Edited by BIGAL
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...