Entmod question

Entmod question

Anonymous
Not applicable
1,344 Views
10 Replies
Message 1 of 11

Entmod question

Anonymous
Not applicable
I have a bunch of blocks, in which there is 1 line that has the linetype 'dashed'.

I have a routine that searches these blocks and creates a list of line entities which are dashed.

I then use foreach to go through this list, I get dxf values 10 and 11 then add 5 to the y value of each. This works fine on 1 block but is I choose more than 1 then they line is moved 5+5 in the second then 5+10 in the third 5+15 in the fourth.......

The routine is nothing special
Something like

(foreach x lst
(setq enlist (entget x))>>>subst and entmod dxf 10>>> subst and entmod dxf 11

lst is a list of line entities to move up 5mm
0 Likes
1,345 Views
10 Replies
Replies (10)
Message 2 of 11

Kent1Cooper
Consultant
Consultant

Post the code.  There's obviously some variable involved that is being cumulatively increased by 5 every time, and not set back to 0 for the next Line.

Kent Cooper, AIA
0 Likes
Message 3 of 11

Anonymous
Not applicable
I'll post the code tomorrow when I get back to my computer, I thought that so I removed all variables from the routine and did the entmod without saving any values and it still did it.
0 Likes
Message 4 of 11

SeeMSixty7
Advisor
Advisor
Are you processing BLOCKS or INSERTS?
0 Likes
Message 5 of 11

Anonymous
Not applicable
What's the difference?
0 Likes
Message 6 of 11

SeeMSixty7
Advisor
Advisor
A BLOCK is a single definition in the drawing.
If you update the definition of the block it updates all occurrences(INSERTS) within the drawing.

An INSERT is the actual reference to the block in the drawing. You can have many inserts of a block in a drawing but only 1 block definition of that BLOCK in the drawing.

The reason I ask, is because I was not sure if you were updating block definitions or if you were trying to update each insert in the drawing.
If this was the case of your routine, if you had 1 insert of the block in your drawing and your routine searched inserts and found one and updated it, it comes out correct, but if you add two then suddenly both inserts are now increased by 10, and three results in 15. It sounds like you might be updating for the number of inserts instead of just the one block definition.

This is all guessing at this point without some actual drawing file and lisp examples to sort through.
Good luck
0 Likes
Message 7 of 11

Kent1Cooper
Consultant
Consultant

@SeeMSixty7 wrote:
.... I was not sure if you were updating block definitions or if you were trying to update each insert in the drawing.
 .... if you had 1 insert of the block in your drawing and your routine searched inserts and found one and updated it, it comes out correct, but if you add two then suddenly both inserts are now increased by 10, and three results in 15. It sounds like you might be updating for the number of inserts instead of just the one block definition. ....

..

If that's what's happening, then this from Post 1:

 

"This works fine on 1 block but [if] I choose more than 1 then [the] line is moved 5+5 in the second then 5+10 in the third 5+15 in the fourth......."

 

would be incorrect, or at least misleading.  The line would be moved another 5 in the process of adjustment of the second, and so on, but all of them would be changed the same, that is, the earlier-adjusted ones would not remain as they were originally adjusted, but would all follow along with the further adjustments of later ones, since they're all insertions of the same Block definition.  @Anonymous, is that what's happening, or are they really remaining different from each other?  If so, are they dynamic Blocks that can be different from each other in use, with the same Block name?

Kent Cooper, AIA
0 Likes
Message 8 of 11

Anonymous
Not applicable
@SeeMSixty7 I realised what you meant whilst I was feeding the baby last night haha

The blocks are all inserts and @Kent1Cooper you are correct they are all different. I do a regen at the end of my routine which makes them all change and gives the odd result. They are not dynamic, just regular old blocks.
0 Likes
Message 9 of 11

Anonymous
Not applicable

So upon extracting the relevant bit of code i moved one line and i no longer get the compounding effect

 

I know its not very efficient but ive got it to work

 

The following line was to blame, it used to filter the dashed lines in the foreach x part as ive left in and commented out

 

((cond
((= (cdr (assoc 6 (entget ent))) "DASHED")

 

 

(defun C:mod-dashed(/ lst)
  
  (setq blks (ssget (list '(0 . "INSERT")))
	count 0)

  
  (repeat (sslength blks)
    
    (setq blk (cdr (assoc 2 (entget (ssname blks count)))))

    (if

      (setq ent (tblobjname "block" blk))

      (while

	(setq ent (entnext ent))

	(cond
	  ((= (cdr (assoc 6 (entget ent))) "DASHED")

	   (setq lst (cons ent lst))

	  )
	)
            
        );while
        
    );if

    (setq count (1+ count))

    );repeat

  (foreach x lst
    
    ;(cond
      
      ;((= (cdr (assoc 6 (entget x))) "DASHED")

       (setq enlist (entget x)
	     new-dxf (cons 62 211)
	     dxfdata (subst new-dxf (assoc 62 enlist) enlist))
       (entmod dxfdata)

       (setq enlist (entget x)
	     new-dxf (cons 10 (list (+ 0 (car (cdr (assoc 10 enlist)))) (+ -5 (cadr (cdr (assoc 10 enlist)))) 0))
	     dxfdata (subst new-dxf (assoc 10 enlist) enlist))
       (entmod dxfdata)

       (setq enlist (entget x)
	     new-dxf (cons 11 (list (+ 0 (car (cdr (assoc 11 enlist)))) (+ -5 (cadr (cdr (assoc 11 enlist)))) 0))
	     dxfdata (subst new-dxf (assoc 11 enlist) enlist))
       (entmod dxfdata)

      ;)
      
    ;);cond
    
  );foreach

    
    
  ;);repeat

  (regendrawing);<<<seperate lisp
  
);defun

 

0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... 

I know its not very efficient but ive got it to work

.... 


Here's an interesting efficiency upgrade for you to consider:

 

For entries in entity data for which there can be only one per entity, such as the start- and end-points of a Line, if there are more than one of a given such entry, the later one wins out over the earlier one, and the earlier one disappears and is replaced by the later one.  That means that you don't actually need to (subst) a new value in place of the old one, but can simply tack it onto the end of the entity data list.  And you can tack on all three of those [color, start-point, end-point] at once, even inside just one (entmod) function.  Try this [lightly tested]:

 

(foreach x lst
  (entmod
    (append
      (setq edata (entget x))
      (list
        '(62 . 211)
        (list 10 (cadr (assoc 10 edata)) (- (caddr (assoc 10 edata)) 5) (cadddr (assoc 10 edata)))
        (list 11 (cadr (assoc 11 edata)) (- (caddr (assoc 11 edata)) 5) (cadddr (assoc 11 edata)))
      ); list
    ); append
  ); entmod
); foreach

[I replaced your adding of -5 to the Y coordinates with subtracting 5 from them.  And instead of pulling the 10's off the entries to make coordinate lists, adjusting coordinates, and (cons)-ing the 10's back onto the fronts of those lists, I just built the lists directly with the 10 and each coordinate.  One other little difference from yours is that I retained whatever the Z coordinate of each end might be, rather than forcing them all to 0, but you can have it do the latter by replacing both instances of (cadddr (assoc 10 edata)) with 0.]

 

Kent Cooper, AIA
0 Likes
Message 11 of 11

dbroad
Mentor
Mentor

Daniel,

As I see it, the main problem with your code is that you could select several inserts with the same block name.  You are trying to change the block definition. When the block definition changes, it affects every insert.  If you select 2 of the same block, the same lines will be adjusted twice.

 

While there is nothing wrong with  your entget/enmod approach, you need to make a list of unique insert names first and then process that list rather than the selection set.  By doing so, you can avoid the double moves.  Your routine suffers also because it assumes that what is dashed is a line.  Also, if you apply the routine to blocks you've already processed, it will move the lines again.  Open the spoiler to see another ActiveX approach that processes the selection set first to find names and then processes the block definitions.  This could process other object types however so you may need to filter for lines only if that is your intent.  The color is filtered so that items processed will not be processed twice.

Spoiler
(defun c:test (/ p1 p2 doc blks names name blk)
  (if (ssget '((0 . "insert")))	;select blocks
    ;;then objects selected
    (progn (setq p1   (vlax-3d-point '(0 0 0)) ;from point
		 ;;your OP indicated +5, your code indicated -5
		 ;;modify here if y value incorrect.
		 p2   (vlax-3d-point '(0 5 0)) ;to point
		 doc  (vla-get-activedocument (vlax-get-acad-object))
		 blks (vla-get-blocks doc)
	   )
	   (vlax-for blk (vla-get-activeselectionset doc)
	     (setq name (vla-get-name blk))
	     (if (not (member name names))
	       (setq names (cons name names))
	     )
	   )
	   (foreach name names
	     (setq blk (vla-item blks name))
	     (vlax-for itm blk
	       		;;modify only dashed objects
	       (if (and	(vlax-property-available-p itm 'linetype)
			(= (vla-get-linetype itm) "DASHED")
			;;filter object types here if necessary
			;;filter out color 211 if avoiding repeated moves
			(/= (vla-get-color itm) 211)
		   )
		 (progn	;;move up 5 units wrt block definition - assumes applicable method
			(vla-move itm p1 p2)
			;;assumes property available.
			;;setting nested entity colors is usually a bad idea.
			(vla-put-color itm 211)
		 )
	       )
	     )
	   )
	   ;;regenerate drawing
	   (vla-regen doc acAllViewports)
    )
    ;;else
    (princ "\nNo objects selected")
  )
  (princ)
 

 

Architect, Registered NC, VA, SC, & GA.
0 Likes