Jump to content

Select objects based on its Layer & Rotation


MannyM
 Share

Recommended Posts

Hello Admin,

Hello to the amazing helpers

 

Forgive me if there is anything that I may have missed here, this is my first time posting


Is there a LISP program where I could select objects and blocks based on their current Layer + Rotation/Angle?

 

I wanna be able to select a group of blocks with some lines, text and separate them from the other similar group that are all intersecting each other, so I figure to achieve this is to have a LISP that can pick an object and blocks based on their layer & rotation/angle

 

If you are asking why dont I just group or change their layer from the start before they get scrambled is because this is how they would have been drawn from the first place and most of the drawing I get are like this so unfortunately this is my only way

 

I would be grateful for any help

 

Thank you for reading :)

Test.dwg

Link to comment
Share on other sites

(50 . 0) is the rotation in radians:
 

(sssetfirst nil (ssget '((0 . "INSERT") (50 . 0))))

 

Here's a quickie to set the rotation from a picked block:

(defun c:foo (/ a e s)
  (cond
    ((and (setq e (car (entsel "\nPick a block to set rotation: "))) (setq a (assoc 50 (entget e))))
     (sssetfirst nil (ssget "_X" (list '(0 . "INSERT") a)))
    )
  )
  (princ)
)

 

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

Tho you should probably get the name as well or your selection set will be any block at X angle.

 

(defun c:foo (/ a n e s)
  (cond
    ((and (setq e (car (entsel "\nPick a block to set rotation: "))) (setq a (assoc 50 (entget e))) (setq n (assoc 2 (entget e))))
     (sssetfirst nil (ssget "_X" (list '(0 . "INSERT") a n)))
    )
  )
  (princ)
)

 

 

  • Like 1
Link to comment
Share on other sites

5 minutes ago, mhupp said:

Tho you should probably get the name as well or your selection set will be any block at X angle.

 

(defun c:foo (/ a n e s)
  (cond
    ((and (setq e (car (entsel "\nPick a block to set rotation: "))) (setq a (assoc 50 (entget e))) (setq n (assoc 2 (entget e))))
     (sssetfirst nil (ssget "_X" (list '(0 . "INSERT") a n)))
    )
  )
  (princ)
)

 

 

I left it out on purpose since the OP says 'blocks', no mention of name. 😉

  • Like 1
Link to comment
Share on other sites

Hello ronjonp & mhupp, thank you for your replies

 

Are we able to change this to "pick object & blocks selection based on its current layer + its rotation/angle"? not block name + x angle

 

Objects on the selection will always be Lines, Polylines, Mtexts, Texts, Blocks & they will all be in one specific layer, the only property that differentiate them from the other group is their Rotation/Angle - thats why I was hoping if there is a LISP that picks a specific layer with a specific rotation/angle ill be able to separate these groups from each other

 

If not too much can you please give me the full LISP code for it? I cant actually program a LISP yet but im willing to!

 

Thank you for your help guys

Link to comment
Share on other sites

Assoc 8 is layer, so maybe try changing Assoc 2, the selection will be based on the layer that is current for block picked. Learning about what the numbers mean will help you with understanding selection set filters. Some of the dxf numbers are always the same like 8.

  • Like 1
Link to comment
Share on other sites

If it's not a one block, it's not a specific shape, it's in the same layer, it's overlapping locations, 

how does the CAD know that it's same group?

 

in your sample dwg, text and rectangle blocks can be found by angle property values

but in the case of lines, it seems difficult to know if they are in the same group of blocks and texts's.

  • Like 1
  • Agree 1
Link to comment
Share on other sites

Thanks BIGAL,

 

exceed - "in your sample dwg, text and rectangle blocks can be found by angle property values but in the case of lines, it seems difficult to know if they are in the same group of blocks and texts's" - correct me if im wrong, texts and blocks property values are rotation but straight lines are angles right? There will be no other shapes in that group aside from a straight line, the rest are blocks and text

 

So basically to be more accurate a "group" will consist of only blocks, straight lines running across the same axis and 1 text

 

If I could pick out groups based on their layer + rotation/angle then I will be able to separate them from other groups that are clashing on top of the others

 

I have attached a more refined sample drawing, it includes the dynamic blocks, lines & text on the group that I want to be able to separate


Thank you for helping guys I appreciate

Test.dwg

Link to comment
Share on other sites

2 hours ago, MannyM said:

Thanks BIGAL,

 

exceed - "in your sample dwg, text and rectangle blocks can be found by angle property values but in the case of lines, it seems difficult to know if they are in the same group of blocks and texts's" - correct me if im wrong, texts and blocks property values are rotation but straight lines are angles right? There will be no other shapes in that group aside from a straight line, the rest are blocks and text

 

So basically to be more accurate a "group" will consist of only blocks, straight lines running across the same axis and 1 text

 

If I could pick out groups based on their layer + rotation/angle then I will be able to separate them from other groups that are clashing on top of the others

 

I have attached a more refined sample drawing, it includes the dynamic blocks, lines & text on the group that I want to be able to separate


Thank you for helping guys I appreciate

Test.dwg 50.12 kB · 3 downloads

 

 

 

 

 

(vl-load-com)
(defun c:study ( / )
  (princ "\n Select a sample objects. There must be only 1 MTEXT.")
  (setq ss (ssget ":L"))
  (setq ssl (sslength ss))
  (setq index 0)
  (setq sublist '())
  (repeat ssl
    (setq ename (ssname ss index))
    (setq obj (vlax-ename->vla-object ename))
    (setq type (vlax-get-property obj 'EntityName))
    (cond
      ((= type "AcDbMText") 
        (setq textcontents (vlax-get-property obj 'TextString))
        (setq textrotation (vlax-get-property obj 'Rotation))
        (setq textinsertionpoint (vlax-safearray->list (vlax-variant-value (vlax-get-property obj 'InsertionPoint))))
        (setq baselist (list type textcontents textrotation textinsertionpoint))
      )
      ((= type "AcDbBlockReference")
        (setq blockname (vlax-get-property obj 'Name))
        (setq blockrotation (vlax-get-property obj 'Rotation))
        (setq blockinsertionpoint (vlax-safearray->list (vlax-variant-value (vlax-get-property obj 'InsertionPoint))))
        (setq subsublist (list type blockname blockrotation blockinsertionpoint))
        (setq sublist (cons subsublist sublist))
      )
      ((= type "AcDbLine")
        (setq linestartpoint (vlax-safearray->list (vlax-variant-value (vlax-get-property obj 'StartPoint))))
        (setq lineendpoint (vlax-safearray->list (vlax-variant-value (vlax-get-property obj 'EndPoint))))
        (setq subsublist (list type linestartpoint lineendpoint))
        (setq sublist (cons subsublist sublist))
      )
    )
    (setq index (+ index 1))
  );end of repeat
  (princ "\n base Mtext - ")
  (princ baselist)
  (princ "\n sub objects - ")
  (princ sublist) 

  ; calculate delta
  (setq baserotation (caddr baselist))
  (setq basepoint (cadddr baselist))

  (setq sublistlen (length sublist))
  (setq index2 0)
  (setq deltalist '())

  (repeat sublistlen
    (setq subitem (nth index2 sublist))
    (setq subtype (car subitem))
    (cond      
      ((= subtype "AcDbBlockReference")
        (setq subangle (angle basepoint (cadddr subitem)))
        (setq sublength (distance basepoint (cadddr subitem)))
        (setq anglediffer (- baserotation (caddr subitem)))
        (setq subsubsublist (list subtype (cadr subitem) anglediffer subangle sublength))
        (setq deltalist (cons subsubsublist deltalist))
      )
      ((= subtype "AcDbLine")
        (setq subangle1 (angle basepoint (cadr subitem)))
        (setq sublength1 (distance basepoint (cadr subitem)))
        (setq subangle2 (angle basepoint (caddr subitem)))
        (setq sublength2 (distance basepoint (caddr subitem)))
        (princ basepoint)
        (princ (cadr subitem))
        (setq subsubsublist (list subtype subangle1 sublength1 subangle2 sublength2))
        (setq deltalist (cons subsubsublist deltalist))
      )
    );end of cond
    (setq index2 (+ index2 1))
  );end of repeat

  (princ "\n delta objects - ")
  (princ deltalist)

  (princ "\n Set Find Range.")
  (setq ss2 (ssget ":L"))
  (setq ss2l (sslength ss2))
  (setq index3 0)

  (setq mtextlist '())
  (setq sublist2 '())

  (repeat ss2l
    (setq ename2 (ssname ss2 index3))
    (setq obj2 (vlax-ename->vla-object ename2))
    (setq type2 (vlax-get-property obj2 'EntityName))
    (cond
      ((= type2 "AcDbMText") 
        (setq textcontents2 (vlax-get-property obj2 'TextString))
        (if (= textcontents2 (cadr baselist))
          (progn
            (setq textrotation2 (vlax-get-property obj2 'Rotation))
            (setq textinsertionpoint2 (vlax-safearray->list (vlax-variant-value (vlax-get-property obj2 'InsertionPoint))))
            (setq baselist2 (list obj2 textrotation2 textinsertionpoint2))
            (setq mtextlist (cons baselist2 mtextlist))
          )
        )
      )
      ((= type2 "AcDbBlockReference")
        (setq blockname2 (vlax-get-property obj2 'Name))
        (setq blockrotation2 (vlax-get-property obj2 'Rotation))
        (setq blockinsertionpoint2 (vlax-safearray->list (vlax-variant-value (vlax-get-property obj2 'InsertionPoint))))
        (setq subsublist2 (list type2 obj2 blockname2 blockrotation2 blockinsertionpoint2))
        (setq sublist2 (cons subsublist2 sublist2))
      )
      ((= type2 "AcDbLine")
        (setq linestartpoint2 (vlax-safearray->list (vlax-variant-value (vlax-get-property obj2 'StartPoint))))
        (setq lineendpoint2 (vlax-safearray->list (vlax-variant-value (vlax-get-property obj2 'EndPoint))))
        (setq subsublist2 (list type2 obj2 linestartpoint2 lineendpoint2))
        (setq sublist2 (cons subsublist2 sublist2))
      )
    )
    (setq index3 (+ index3 1))
  );end of repeat

  (princ "\n finded mtext list - ")
  (princ mtextlist)
  (princ "\n lego box - ")
  (princ sublist2)

  (setq mtextlistlen (length mtextlist))
  (setq index4 0)
  (setq sublist2len (length sublist2))
  (setq deltalistlen (length deltalist))

;|
  (repeat mtextlistlen
    (setq ss3 (ssadd))
    (setq mtextselected (nth index4 mtextlist))
    (setq mtextselectedrotation (cadr mtextselected))
    (setq mtextselectedpoint (caddr mtextselected))
    (setq index5 0)
    (repeat sublist2len 
      (setq sublist2selected (nth index5 sublist2))
      (setq type3 (car sublist2selected))
      (cond
        ((= type3 "AcDbBlockReference")
          (setq index6 0)
          (repeat deltalistlen
            (setq deltaatom (nth index6 deltalist))
            (setq deltatype (car deltaatom))
            (if (= deltatype type3) 
              (if (= (caddr deltalist) (- mtextselectedrotation (cadddr sublist2selected)))
                (if (= 




            

|;  

  (princ)
);end of defun

 

This is just a direction not answer. currently, it simply prints a list.

I stopped because I have no time. 

i think it would be faster to just manually make 1000 blocks than to make this by my low level of lisping. haha

 

 

for someone who want to do this, so I writing down the thinking

 

If there is one mtext that is the standard for all groups

 

Recognize a group as a list like a sample group. Make the list by (text string, rotation, and position) of the base mtext, 

List the rest of the objects (blocks, lines). 

 

In case of block (block name, insertion point, rotation) 

For lines (start point, end point) 

 

Then, compare the base mtext list with this list to create a list of difference values. 

The distance from the insertion point of the mtext, the angle, and the difference between the rotation angle of the mtext and the rotation angle of each object 

should be entered in this list. 

 

The vla-object id is also included in the list to make it easier to choose the right one later. 

 

Then create a new selection set to put the search range in. 

Or select entire drawing with x After that, 

a new list is created by selecting the standard mtext from the selection set. 

 

Since this list will be compared to the base list, 

it should contain the textstring, angle and insertion point of the mtexts. 

And make a lego box that is not organized with blocks and lines except for the rest of the mtext. 

 

Then, calculate the angle difference between the angles of the mtexts that satisfy the conditions and the angles of the base mtext,

and use polar to find the appropriate ones in the lego box with the angle and length values in the delta list and put them in the new selection set. 

 

The problem here is that only the first value must be obtained after the condition is satisfied in case the components overlap in the exact same position.

And you have to think about the case where only some of the components are satisfied. 

 

After that, each object is made into a block,

and the existing individual objects are deleted and replaced with a block. It's easier than this to list or create statistics using blocks.

 

 

This is how you can make a machine understand "looks like a block to a human". 

This is just my novice thinking.

 

Maybe someone else with a good idea can solve it with one line of code.😀

  • Like 1
Link to comment
Share on other sites

Amazing! thank you for your input exceed!

You did quite a long LISP there my man I appreciate it! Thanks for your time looking into this

 

Hope someone will get a chance to finish this

 

Thank you for reading this topic :)

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

 Share

×
×
  • Create New...