Jump to content

Move block to block attribute insertionpoint


pmxcad

Recommended Posts

Hello all,

I need help with the following. what I want to achieve is that I have a block diagram drawing with 2 panels and some separate components. I run the lisp and then select all component blocks and that they automatically connected to a panel based on tag value.

I have searched on various forums and found a lisp that comes in the direction of what I want. But this routine is stuck in a loop, I think. Can only get out by esc.

So I'm looking for a lisp which moves a block to a block attribute.

Does anyone have an idea how I can achieve this or adjust the lisp so that it works and what I can do with it?

 

(defun C:InsertAtAtt( / att_list )
(setq att_name (entnext (car (entsel))))
(while (not att_list)
(setq att_list (entget att_name))
(setq tag (cdr (assoc 1 att_list))
val (cdr (assoc 2 att_list))
prm (cdr (assoc 3 att_list))
a10 (cdr (assoc 10 att_list))
a11 (cdr (assoc 11 att_list))
)
(if (and (= tag "this_value")
(= val "this_value")
(= prm "this_value")
)
(command "_.insert" "block_name" a10 "" "" "")
(setq att_list nil)
)
)
)

 

 

thank you in advance,

 

PmxCAD

TEST.dwg

Link to comment
Share on other sites

  • Replies 29
  • Created
  • Last Reply

Top Posters In This Topic

  • rlx

    14

  • pmxcad

    11

  • Grrr

    3

  • BIGAL

    2

Top Posters In This Topic

Could you not edit the block and make the insertion point the attribute point ? Or is it only certain cases you want it moved, if thats what is wanted do a little defun that moves the block the correct amount in x and y 0,0 2.3,3.4

 

Thinking a bit more pick block get insertion point explode pick new pt undo so block comes back and move. Or just had a look move pickpoint _Insert pick attribute

Link to comment
Share on other sites

Hello BIGAL,

 

thanks for your comment.

It's like this, ... we first make a projection on the floorplan and if that is approved then we make the block diagram. I have made it like this, that with the lisp "TEST-Copy" copy the components of the floorplan to pasteboard. Then go to the block diagrams and paste the components with the "TEST-Paste-Rot-Scale-Sync.LSP" to paste, rotate to 0 and scale to 1: 1. at the pointed location. But the are stacked on top of each other. And then I have to pick them up and move them one by one.

The blocks of the block diagram are as they are and already in the block diagram template. The blocks of the floor plan take over the appearance of the block diagram blocks. Works well.

So I want to automate the move of those blocks to the panel blocks with the same tag value, or I want to paste the blocks, have them one by one under the pointer (in order) and then insert them in place i select.

The central block has attributes on the insert points. Do I have to make it visible for lisp routines?

I hope that I am more clear with what I would like to achieve.

 

thanks,

 

PmxCAD

TEST.dwg

TEST-Copy.LSP

TEST-floorplan.dwg

TEST-Paste-Rot-Scale-Sync.LSP

Link to comment
Share on other sites

Hi PmxCad,

 

I think I would take a different approach , one that would not need to paste the blocks from one drawing to the other. You could just export (or obtain with odbx) a list with all blocknames and its attribute value(s). So lets say you have two speaker-symbols with attribute value 01 and 02 and two light-symbols with value 05 and 07 on your plotplan. In the blockdiagram you would already have a symbol for a speaker and a light so you would only need to go through the list and insert symbol 'speaker' on insertionpoint of attribute 01 and 02 and symbol 'light' on 05 and 07 from your connectionbox. This would work if you have only so many symbols but else you can also copy the blockdefinition from one drawing to another using odbx.

 

gr. Rlx

Link to comment
Share on other sites

Hi Rlx,

I know a littlebit of lisp but nothing about odbx.

 

PmxCAD

 

Well that's no problem when you have a site like CadTutor. I'll see if I can come up with something and try to make it a little bit generic so it can be usefull for more users. Not to say your approach isn't good. In fact it is much simpler than what I have in mind, but its just a nice challenge. I'll let you know if and when I have something to show for you.

 

To help you with your own routine , if you have your connection block "!!00 1" and you have the number of your connection "1101" you can get the coordinates of the attribute you want with something like this :

 

; first select your connection block and then find the coordinates of the attribute with the value to match (just select any object on your panel symbol)

; test it with this : (_get_attribute_insertionpoint "1101" (vlax-ename->vla-object (car (entsel))))
(defun _get_attribute_insertionpoint ( a b )
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-textstring x))) (_get_insertion_point x)))(vlax-invoke b 'getattributes)))

(defun _get_insertion_point ( e )
 (cond
   ((and (vlax-property-available-p e 'alignment) (= (vla-get-alignment e) 0))
    (reverse (cdr (reverse (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint e)))))))
   ((and (vlax-property-available-p e 'alignment) (/= (vla-get-alignment e) 0))
    (reverse (cdr (reverse (vlax-safearray->list (vlax-variant-value (vla-get-TextAlignmentPoint e)))))))
 )
)
; oh and don't forget (vl-load-com)

This should return the coordinates of the attribute with value 1101 in the block you select. (assuming the block you select has an attribute with this value)

 

I assume each connection box or panel can contain but so many inputs so you can have multiple panels and maybe each transmitter in the room would not only have an attribute for the channel but also for the panel number? This would be usefull when you want to be able to automaticly select (ssget) the right panel in your blockdiagram or would you typicly have only just one panel per blockdiagram?

 

Wel hope this can help you a little step further

 

gr. Rlx

Link to comment
Share on other sites

Hi Rlx,

 

Selecting a block with lisp succeeds me and by attribute value also. But I would not know how I "(_get_attribute_insertionpoint" 1101 "(vlax-ename-> custard object (car (entsel)))) " apply in your lisp.

And I sure want to try an odbx solution. But if I get you lisp working, I'm already on my way.

 

gr.

PmxCAD

Link to comment
Share on other sites

this is what I have so far :

 

(defun c:PmxCad_GenerateBlockDiagram
      ( / err acApp actDoc actSpace acDocs all-open objDBX floor-plan scan-block-list io-attribute io-value io-position
      connection-box-name connection-box-object ss)
 (_init)
 (_Select_Floorplan)
 (_Exit)
 (terpri)
 (princ)
)

(defun _Init ()
 (Odbx_Init)  (setq err *error*)  (defun *error* (s)(princ s)(_Exit))
 (setq scan-block-list (list (cons "U00010" "TEXT1") (cons "U00025" "TEXT1")))
 (setq connection-box-name "!!00 1" ss (ssget "X" (list (cons 0 "INSERT") (cons 2 connection-box-name))))
 (if ss
   (setq connection-box-object (vlax-ename->vla-object (ssname ss 1)))
   (alert (strcat "Connectionbox " connection-box-name " not found")))
)

(defun _Exit () (Odbx_ReleaseAll))

(defun _Select_Floorplan ( / odbxdoc layout obj blkname)
 (if (and (setq floor-plan (getfiled "Select Floorplan" "d:/Temp/Lisp/Cad-tutor/PmxCad/" "dwg" 0)) (setq odbxdoc (odbx_open floor-plan)))
   (progn
     (vlax-for layout (vla-get-layouts odbxdoc)
   (vlax-for obj (vla-get-block layout)
     (if (and (eq "AcDbBlockReference" (vla-get-objectname obj))
          (setq blkname (strcase (_get_block_name obj)))
          (setq io-attribute (cdr (assoc blkname scan-block-list)))
          (setq io-value (_get_attribute_value io-attribute obj))
          (setq io-position (_get_attribute_insertionpoint io-value connection-box-object))
         )
       (_insert_it)
     )
   )
     );vlax
     (vlax-release-object odbxdoc)
   );prog
 );if
)

; currently just testing
(defun _insert_it ( / blk )
 (if (and (tblsearch "BLOCK" blkname) (setq blk (vla-insertblock actSpace io-position blkname 1 1 1 0)))
   (_put_attribute_value io-value io-attribute blk))
 ;(princ (strcat "\n" blkname "\t" io-value "\tposition : ")) (princ io-position)
)


(defun _get_block_name (b)
 (cond ((vlax-property-available-p b 'effectivename) (vla-get-effectivename b)) ((vlax-property-available-p b 'name) (vla-get-name b))))

(defun _get_attribute_value ( a b )
 (if (= (type b) 'ENAME)(setq b (vlax-ename->vla-object b)))
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-tagstring x))) (vla-get-textstring x)))(vlax-invoke b 'getattributes)))

(defun _put_attribute_value ( v a b )
 (if (= (type b) 'ENAME)(setq b (vlax-ename->vla-object b)))
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-tagstring x))) (vla-put-textstring x v)))(vlax-invoke b 'getattributes)))

; (_get_attribute_insertionpoint "1101" (car (entsel)))
(defun _get_attribute_insertionpoint ( a b )
 (if (= (type b) 'ENAME)(setq b (vlax-ename->vla-object b)))
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-textstring x))) (get_ip x)))(vlax-invoke b 'getattributes)))

(defun get_ip ( e )
 (if (and (vlax-property-available-p e 'alignment) (/= (vla-get-alignment e) 0)) (vla-get-TextAlignmentPoint e) (vla-get-InsertionPoint e)))


;--- Odbx ------------------------------------------------- Begin Odbx Section --------------------------------------------------- Odbx ---

(defun Odbx_Init (/ acVer)
 (setq acApp (vlax-get-acad-object) actDoc (vla-get-activedocument acApp) actSpace (vla-get-ModelSpace actDoc)
   acDocs (vla-get-documents acApp) acVer (atoi (getvar "ACADVER"))
   all-open (vlax-for dwg acDocs (setq all-open (cons (strcase (vla-get-fullname dwg)) all-open)))
   objDBX (vl-catch-all-apply 'vla-getinterfaceobject (list acApp (if (< acVer 16)
       "objectdbx.axdbdocument" (strcat "objectdbx.axdbdocument." (itoa acVer))))))
 (if (or (void objDBX)(vl-catch-all-error-p objDBX))(setq objDBX nil)))

(defun Odbx_ReleaseAll ()
 (mapcar '(lambda(x)(if (and (= 'vla-object (type x)) (not (vlax-object-released-p x)))
              (vlax-release-object x))(set (quote x) nil)) (list acDocs objDBX actSpace actDoc acApp)) (gc))

(defun Odbx_Open (dwg)
 (if objDBX (if (member (strcase dwg) all-open)
          (odbx_open_copy (findfile dwg)) (vl-catch-all-apply 'vla-open (list objDBX (findfile dwg)))))  objDBX )

(defun odbx_open_copy (dwg / copy)
 (vl-file-copy (findfile dwg) (setq copy (vl-filename-mktemp nil nil ".dwg"))) (vla-open objDBX (findfile copy)) objDBX)

(defun void (x) (if (member x (list "" " " "  " "   " "       " nil '())) t nil))

;--- Odbx -------------------------------------------------- End Odbx Section ---------------------------------------------------- Odbx ---


; (c:PmxCad_GenerateBlockDiagram)




At this time you have 2 connection boxes so I hard coded to selected the one on the right-side (ssname ss 1) in the init part of the code. First edit the path I use to select your plotplan in the code above.

I use "d:/Temp/Lisp/Cad-tutor/PmxCad/" , change it to whatever folder you use or just put "" there.

 

You can close your plotplan and only open the blockdiagram. Load routine (it auto-starts) , you select the plotplan and it then lists all attributes and it coordinates.

 

Will continue later because I'm starting to see double (sadly not alcohol related)

 

gr. Rlx

Edited by rlx
Link to comment
Share on other sites

'listen verry carefully... I have tested this only once' (from allo allo)

 

(defun c:tst2 ( / transmitters transmitter panels input-channel input-channel-ip )
 (vl-load-com)
 (if (setq transmitters (ssget "X" (list (cons 0 "INSERT") (cons 2 "U000##"))))
   (setq transmitters (mapcar 'vlax-ename->vla-object (SS->Lst transmitters))))
 (if (setq panels (ssget "X" (list (cons 0 "INSERT") (cons 2 "!!00 1"))))
   (setq panels (mapcar 'vlax-ename->vla-object (SS->Lst panels))))
 (if (and transmitters panels )
   (foreach transmitter transmitters
     (setq input-channel (get_attribute_value "TEXT1" transmitter))
     (if (setq input-channel-ip (vl-some '(lambda (x) (find_attribute_insertionpoint input-channel x)) panels))
   (vla-Move transmitter (vla-get-InsertionPoint transmitter) input-channel-ip)
     )
   )
 )
)

(defun SS->Lst (ss) (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))

(defun get_attribute_value ( a b )
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-tagstring x))) (vla-get-textstring x)))(vlax-invoke b 'getattributes)))

(defun find_attribute_insertionpoint ( a b )
 (vl-some '(lambda (x)(if (equal (strcase a) (strcase (vla-get-textstring x))) (get_attribute_ip x)))(vlax-invoke b 'getattributes)))

(defun get_attribute_ip ( e )
 (if (and (vlax-property-available-p e 'alignment) (/= (vla-get-alignment e) 0)) (vla-get-TextAlignmentPoint e) (vla-get-InsertionPoint e)))

(c:tst2)

have to do my weekly sunday visits now...

 

gr. Rlx

Link to comment
Share on other sites

Hi Rix,

Your first lisp "PmxCad_GenerateBlockDiagram" gives an error "error: no function definition: VOID".

Your second works in collaboration with my lisp "TEST-Paste-Rot-Scale-Sync" and copy blocks to clipboard, run my lisp and you lisp "tst2". Works well/perfect.

But what is the use of the first lisp ("PmxCad_GenerateBlockDiagram")? Copying the blocks? Is it also possible to replace the part of the location of the other drawing to a use an open drawing?

Both drawings are always open at the same time.

 

 

 

PmxCAD

Link to comment
Share on other sites

Hi Rix,

Your first lisp "PmxCad_GenerateBlockDiagram" gives an error "error: no function definition: VOID".

Your second works in collaboration with my lisp "TEST-Paste-Rot-Scale-Sync" and copy blocks to clipboard, run my lisp and you lisp "tst2". Works well/perfect.

But what is the use of the first lisp ("PmxCad_GenerateBlockDiagram")? Copying the blocks? Is it also possible to replace the part of the location of the other drawing to a use an open drawing?

Both drawings are always open at the same time.

 

 

 

PmxCAD

 

ah , void... just me getting tired last night and forget to include one of my library functions (know bad habbit , but then again , I'm a bad dragon ;-) Just replace 'void' with 'null'. Odbx version is far from complete , just posted it so you have an idea of how it could look like. Last code was indeed intended to supplement your own code. Will work on the odbx thing when I have some time.

 

gr. Rlx

Link to comment
Share on other sites

Hi Rix,

gave another error (to many arguments).

But that does not matter, I am very happy with that other lisp in collaboration with mine. I am very grateful for your time.

 

PmxCAD

(Driebergen)

Link to comment
Share on other sites

Rather than use odbx could you not just have two sessions of Autocad open one running script doing all the work of changing the blocks. I do admit to not trying it.

Link to comment
Share on other sites

Rather than use odbx could you not just have two sessions of Autocad open one running script doing all the work of changing the blocks. I do admit to not trying it.

 

@BigAl

 

Possible...

 

just had the idea of as little possible user input so best option would be having an empty drawing , starting command to generate blockdiagram by only selecting the right plotplan and nothing else. That would mean having a standard blockdiagram in your searchpath or location stored in program config. Program would scan plotplan , insert standard block diagram and fill it with data collected from plotplan. Whether this is best coding option is open for discussion ofcourse...

Link to comment
Share on other sites

Hi Rix and BIGAL,

The combination of both lisps is perfect. only the tst2.lisp puts an exact copy on top of it. You do not see it, I found out when I wanted to delete a block, but It did not go away. So there is a copy of each block.

 

PmxCAD

Link to comment
Share on other sites

Hi Rix and BIGAL,

The combination of both lisps is perfect. only the tst2.lisp puts an exact copy on top of it. You do not see it, I found out when I wanted to delete a block, but It did not go away. So there is a copy of each block.

 

PmxCAD

 

Shouldn't happen (and it doesn't in my test-dwg)? Think you have to remove the last line in the lsp (c:tst2). This line was only so routine executes automaticly when loaded from vlisp editor.

 

gr. Rlx

Link to comment
Share on other sites

Hi Rix,

Another question: Is it possible to place the block "relay" on the outputs of the module "ETV" and "EIDS" (OC output) if a block is / is placed on these attributes or coordinates. It is always a U000 .. block. It is only use for these modules and NOT for the I / O module, which already has relay outputs.

So the question is, is it possible to check if blocks (U000 ..) are placed on an output?

 

Thanks,

PmxCAD

test2.dwg

Link to comment
Share on other sites

Hi Rix,

Another question: Is it possible to place the block "relay" on the outputs of the module "ETV" and "EIDS" (OC output) if a block is / is placed on these attributes or coordinates. It is always a U000 .. block. It is only use for these modules and NOT for the I / O module, which already has relay outputs.

So the question is, is it possible to check if blocks (U000 ..) are placed on an output?

 

Thanks,

PmxCAD

 

Problably not today I can :sleeping: but will have a look at it later. First thing that comes to mind is to check for every block with name ending on ETV or EIDS make a list of coordinates from all output attributes and then check those against all U00052 blocks and if the match we have a winner...or the other way around , the fact that a U00052 is inserted in the first place and then just check if it is connected to the right block and that can be done by scanning all coordinates or just ssget on insertion point of U00052 and see what else is in selectionset... gr. RLX

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...