Selecting object inside the block

Selecting object inside the block

eakos1
Advocate Advocate
2,194 Views
23 Replies
Message 1 of 24

Selecting object inside the block

eakos1
Advocate
Advocate

Is it possible somehow select single objects which are inside of a block?

 

If ssget can select only primary entity, what means this ":V" option? I've tried it but it not works. What is it for if not select subentity inside the block? 

  • (ssget "_:V") - force subentity selection

 

This is the detailed description. 

:V Forces subentity selection. Treats all interactive, graphic selections performed by the user as subentity selections. The returned selection set contains subentities only. This option cannot be combined with the duplicate (":D") or nested (":N") selection modes. This option is supported only with interactive selections, such as window and crossing. It is not supported for all, filtered, or group selections.

0 Likes
Accepted solutions (1)
2,195 Views
23 Replies
Replies (23)
Message 2 of 24

komondormrex
Mentor
Mentor

nentsel selects single graphical entity inside block. the question is what are you going to do with it? because it belongs to block definition.

0 Likes
Message 3 of 24

eakos1
Advocate
Advocate

It is promising.  🙂

 

For example I can get the length of the lines, and I can change the color ect. 

 

I've just tried, this code works:

(while
(setq Ent (nentsel "\nPick an entity or subEntity: "))
(setq Length_of_selected (vla-get-length (vlax-ename->vla-object (car Ent))))
(vla-put-Color (vlax-ename->vla-object (car Ent)) 4)
(command "regen" )
)

 

 

0 Likes
Message 4 of 24

Moshe-A
Mentor
Mentor
Accepted solution

@eakos1 hi,

 

Just a info you might want to know 😀

 

although (nentsel) returns the ename of an subentity and you can enquire it for points, layer, color and all other properties and seems even you can modify it, the next time you enter to modify the block (BEDIT) all these changes is vanish. only attributes can be modified on block references (inserts).

 

Moshe

 

0 Likes
Message 5 of 24

eakos1
Advocate
Advocate

I don't understand you concern. 

 

I've created a drawing with lines and a block - insider more line and polylines. 

I've saved it. Reopend it, run my lisp, changed the color. Go in edit in place and the color was the new color, I've moved the objects, make some longer ect. , closed it. 

Saved and the changes were saved. 

 

 

0 Likes
Message 6 of 24

john.uhden
Mentor
Mentor

@Moshe-A ,

I think the point you're making is that you can temporarily change the properties inside a block reference (which I didn't know 'cause I've never tried it), but it won't hold.  Instead you must change the object in the block definition.

Now how you retrieve the corresponding object in the definition, I have no idea as yet.  Sure, attributes are easy, but a plain line or circle etc. would I think require some special technique.

Yes, it's easy to change say the color of all entities in a definition, but how to distinguish one entity from a block reference is another story.  Sounds like a challenge to me, without using BEDIT.

John F. Uhden

0 Likes
Message 7 of 24

Moshe-A
Mentor
Mentor

@eakos1 ,

 


@eakos1 wrote:

I don't understand you concern. 

 

I've created a drawing with lines and a block - insider more line and polylines. 

I've saved it. Reopend it, run my lisp, changed the color. Go in edit in place and the color was the new color, I've moved the objects, make some longer ect. , closed it. 

Saved and the changes were saved. 

 

 


yes turns out you are right, never thought of doing that.

 

 

 

0 Likes
Message 8 of 24

eakos1
Advocate
Advocate

I've mad a more complicated trial - manipulating polyline. I have a code what goes through the polyline and if one radius is smaller then 3 will make it bold. 

And it really do it inside of the block. It really woks!

 

eakos1_1-1685136385674.png

 

 

           (setq width 1)   ;width o the arc segments in the polyline
           (setq radius 2.99999) ;the defined smallest radius, ARC with smaller radius
           (setq numberPolyArc 0)

           (setq Ent (nentsel "\nPick an subEntity in the Block: "))
	   (setq name (car Ent))

;;;	   (setq name (ssname selection counter))
	   (setq data (entget name))
	   (setq typ (cdr (assoc 0 data)))
	   ----------------------------------------------------------------------------------

	   (if (or (= typ "POLYLINE") (= typ "LWPOLYLINE"))
	      (progn
		 (setq element (fix (vlax-curve-getendparam name))) ;number of segments of the polyline
		 (setq segmentindex -1)
		 (setq obj (vlax-ename->vla-object name))
		 ;; 
		 (repeat element
		    (print (setq p1 (vlax-curve-getpointatparam name (setq segmentindex (1+ segmentindex))))
		    )
		    (setq bulge (vla-getbulge (vlax-ename->vla-object name) segmentindex))
		    ;print the co-ordinates
		    (princ (strcat " bulge = " (rtos bulge))) ;print the bulge

		    -------------------------------------------------------------------------

		    ;If radius small then change the width
		    (if	(/= bulge 0)
		       (progn (setq p2 (vlax-curve-getpointatparam name (1+ segmentindex)))
			      (setq l (distance p1 p2))
			      (setq angarc (* 4.0 (atan bulge)))
			      (setq r (abs (/ (/ l 2) (sin (/ angarc 2.0)))))
			      (princ (strcat " r = " (rtos r)))
			      (if (< r radius)
				 (progn
				    (vla-setwidth obj segmentindex width width)
				    (setq numberPolyArc (1+ numberPolyArc))
				 ) ;end progn
				 (vla-setwidth obj segmentindex 0 0)
			      ) ;end if
		       ) ;end progn
		    ) ;end if

		   
		    -------------------------------------------------------------------------
		 )  ;end repeat
	      )	    ;progn
	   )	    ;if
(command "regen")

 

The only disadvantage is that we need to select one by one the polylines. Luckily we have max. 4 polylines in one block. 

For this checking program I can use the nentsel command and we do not need go anymore inside the block. 

 

0 Likes
Message 9 of 24

eakos1
Advocate
Advocate

My other goal is to make a program to select one cell in a table. After then select polylines inside a block with nentsel and get the lengths of the polylines, add together them and the total length put inside the selected cell in the table. 

 

This code will be good to get which cell was selected. 

(vla-HitTest

    (vlax-ename->vla-object (car xxx))

    (vlax-3d-point (cadr xxx))

    (vlax-3d-point (trans (getvar 'ViewDir) 1 0))

    'outRow

    'outCol

)

 

I never used tables before. If I have the total length how can I put the value into the selected cell?

Can someone help me?

 

0 Likes
Message 10 of 24

john.uhden
Mentor
Mentor

You are a good man, @Moshe-A .

John F. Uhden

0 Likes
Message 11 of 24

Moshe-A
Mentor
Mentor

thank you John, so you 😀

but what have i done to get that this time?

 

 

0 Likes
Message 12 of 24

Sea-Haven
Mentor
Mentor

Do you want all plines in the block or just 1 or 2 ? If all can read the block definition and get the plines. Then * by number of blocks gives a grand total.

0 Likes
Message 13 of 24

komondormrex
Mentor
Mentor

@eakos1 wrote:

I never used tables before. If I have the total length how can I put the value into the selected cell?

Can someone help me?


for example you can pick a cell in a table with this.

(defun get_cell_row_column (/ cell_picked table_selected_object row_number column_number checking_vector table_sset)
	(setq checking_vector (vlax-3d-point (getvar 'viewdir)))
	(while (null cell_picked)
		(setq picked_point (vl-catch-all-apply 'getpoint (list "\nPick a cell of a table to get its row and column: ")))
		(cond
			(
				(vl-catch-all-error-p picked_point)
					(setq cell_picked t)
			)
			(
				(null picked_point)
			)
			(
				t
					(setq table_sset (ssget "_f" (list
					  					picked_point
					  					(list (car picked_point) (+ (cadr (getvar 'viewctr)) (/ (getvar 'viewsize) 2.0)))
				 				 	)
				 					'((0 . "ACAD_TABLE"))
									)
					)
					(cond
						(
							(null table_sset)
						)
						(
							(and
								(= :vlax-true (vla-hittest (setq table_selected_object (vlax-ename->vla-object (ssname table_sset 0)))
														   (vlax-3d-point picked_point) checking_vector 'row_number 'column_number
											  )
								)
								(or
									(= :vlax-true (vla-get-titlesuppressed table_selected_object))
									(and
										 (= :vlax-false (vla-get-titlesuppressed table_selected_object))
										 (not (zerop row_number))
									)
								)
							)
								(setq cell_picked t)
						)
						(
							t
						)
					)
			)
		)
	)
  	(list table_selected_object (cons row_number column_number))   
)

 

and get get returned list of table object and dotted pair of cell row and cell column. then you can place calculated plines total length into that cell by

 

(vla-setcellvalue table_selected_object row_number column_number calculated_lenght)

 

0 Likes
Message 14 of 24

john.uhden
Mentor
Mentor

@Moshe-A ,

You are man enough to recognize and admit that you learned something from someone other than the regular brainiacs, even though you are one of them in my book.

John F. Uhden

Message 15 of 24

mruPRQUJ
Advocate
Advocate

thanks a lot, have a wonderful day!

0 Likes
Message 16 of 24

eakos1
Advocate
Advocate

I have to select the needed 1 or 2. So this is not an option for me.

0 Likes
Message 17 of 24

john.uhden
Mentor
Mentor

@eakos1 ,

You can do 1, 2, or N...

(while (setq e (car (nentsel)))

...

)

You just can't pick objects in a block or xref by window, crossing, etc.

Well, not at least until someone invents a way.

John F. Uhden

0 Likes
Message 18 of 24

eakos1
Advocate
Advocate

I've realized an interesting thing.  😀

I want to get work my program with both LWPOLYLINE and 2DPOLYLINE too selecting inside the block. 

As far as I know the vla-get-length works with both type but after nentsel by 2DPOLYLINE it gives an error. 

I've realized if I click on a 2DPOLYLINE the type will be not POLYLINE but VERTEX !

It seems the nentsel will select the LWPOLYLINE item but if I click on the 2DPOLYLINE it will select only a VERTEX and I have to read the original name of the 2DPOLYLINE from the VERTEX. 

But I could manage it finally. 

 

Message 19 of 24

Moshe-A
Mentor
Mentor

@eakos1 , 

 

That's true a "POLYLINE" or  "AcDb2dPolyline" is the old pline object of AutoCAD (if i remember right it was up to R13 since R14 AutoCAD gave us the "LWPOLYLINE" a new object that is meant to be smaller in memory lighter\quicker then the old.) the old polyline was build from a parent "LWPOLYLINE" object contains child objects vertexes each one is one segment (line \ polyarc)

 

to get ename of "AcDb2dPolyline" you could do this:

(setq pick (nentsel "\nSelect pline: ")) return a list of two items.

the first item is the ename of the vertex and the second is the point you picked - agree?!

now: 

(setq pt (cadr pick)) ; return the picked point

 

(setq ss (ssget pt)) ; runs with no pause

                                   ; return selection set of main objects the first object in ss is the parent polyline.

 

Moshe

 

0 Likes
Message 20 of 24

eakos1
Advocate
Advocate

Your solution works not for me, it gives an error massage:  error: bad argument type: consp <Entity name: 7ff44aa0eb40>

After nentsel I've tried this to get the length but error. 

  (setq pt (cadr Ent))
  (setq ss (ssget pt))
  (ssname ss 0)
  (vla-get-length (vlax-ename->vla-object (cdr (car (cdr (cdr (entget (car (ssname ss 0)))))))))

 

I'm using this and this works:   (cdr (car (cdr (cdr (entget (car Ent))))))

This gives back really the name of the polyline. 

(setq
    Ent
     (nentsel
       "\nPick the POLYLINE's one by one (It can be insed of a block too): "
     )
  )
  (cdr (car (cdr (cdr (entget (car Ent))))))

  (vla-get-length (vlax-ename->vla-object (cdr (car (cdr (cdr (entget (car Ent))))))))

 

 

0 Likes