Removing entities from list of entities if all the entity's points are unique to it

Removing entities from list of entities if all the entity's points are unique to it

Jonathan_Bell82GXG
Enthusiast Enthusiast
900 Views
7 Replies
Message 1 of 8

Removing entities from list of entities if all the entity's points are unique to it

Jonathan_Bell82GXG
Enthusiast
Enthusiast

I'm trying to think of how this logic would work:

 

  • I have a list of all points of a given set of entities (hypothetically including some duplicates if, for instance, there are 2 connected lines)
  • From this list, I will get a list of all unique points (non-duplicates)
  • Then if a given entity contains only unique points, I will remove it from the entity list

 

The goal should be to end up with a list of entities that are each connected to/share points with (not joined to) at least one other entity. Does this rough outline make sense? How can I then translate it into code?

0 Likes
Accepted solutions (1)
901 Views
7 Replies
Replies (7)
Message 2 of 8

Sea-Haven
Mentor
Mentor

Not code but idea make a list of all points, line = start & end, pline= vertices and so on.

 

The list would be ((x1 y1 entity1)(x2 y2 entity1)(x3 y3 entity3).......  A dbl sort on the X&Y would make the list showing points that touch. ((x1 y1 entity1)(x32 y32 entity32) a matching pair. You would need to do a loop and look at (nth x lst) & (nth (+ x 1) lst) are the X & Y equal. 

 

eg 5 lines start and end points.

((1817667.18502166 -162980.992387923 <Entity name: 735959b0>) (1817667.18502166 -160208.246143584 <Entity name: 735959b0>) (1816713.11664995 -163285.707894655 <Entity name: 73595df0>) (1816713.11664995 -160512.961650315 <Entity name: 73595df0>) (1815762.9530616 -163604.03275768 <Entity name: 73595d70>) (1815762.9530616 -160831.28651334 <Entity name: 73595d70>) (1814946.57833349 -163985.307917107 <Entity name: 735952f0>) (1814946.57833349 -161212.561672767 <Entity name: 735952f0>) (1814200.0 -164272.74624434 <Entity name: 73590d70>) (1814200.0 -161500.0 <Entity name: 73590d70>))

 

0 Likes
Message 3 of 8

Kent1Cooper
Consultant
Consultant

@Jonathan_Bell82GXG wrote:

....

The goal should be to end up with a list of entities that are each connected to/share points with (not joined to) at least one other entity. ....


If you want that information simply in order to join those that can be joined, try the PJ command in PolylineJoin.lsp, >here<.

Kent Cooper, AIA
Message 4 of 8

Jonathan_Bell82GXG
Enthusiast
Enthusiast

It works perfectly, thanks! However, when using the command for an empty selection set (choosing no entities when prompted), I get this error:

Select objects: Specify opposite corner: 0 found
Select objects:
Error: bad argument type: lselsetp nil
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

I think the issue is with the error handler, line 6:

(defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg))
    ); if
    (setvar 'peditaccept peac)
    (command "_.undo" "_end")
    (setvar 'cmdecho cmde)
    (princ)
  ); defun - *error*

 Any suggestions for improvement? I tried using command-s and the push/pop error methods but couldn't get it to work

0 Likes
Message 5 of 8

Kent1Cooper
Consultant
Consultant
Accepted solution

@Jonathan_Bell82GXG wrote:

.... when using ... for an empty selection set (choosing no entities when prompted), I get this error: ....


I was less sophisticated about such things 12 years ago, and I think (command-s) did not yet exist.  If I just add the -s in the *error* handler, it at least works to avoid that (command)-vs,-(command-s) message.  But it was worth updating the whole Undo begin/end approach and a couple of other little things.  See the attached updated version of PolylineJoin.lsp, which in that situation now just politely informs you that you didn't pick any viable objects.

Kent Cooper, AIA
Message 6 of 8

Jonathan_Bell82GXG
Enthusiast
Enthusiast

Thanks! If I have a selection set, then join whatever entities can be joined, and I then want to get an updated selection set (including all the original entities that couldn't be joined, plus the newly made polylines), I'm thinking this would be the general process:

 

    ; get current or prompt for selection set
    (setq ss1 (ssget '((0 . "LINE,ARC,*POLYLINE,CIRCLE"))))
  
    ;;; HERE
    ; get list of entities in selection set
    ; get 1 pt from each entity
  
    (polylineJoin ss1)
    ; make new selection set using list of points 
    ; remove duplicates (should return list of all entities to then offset)

 

Any suggestions or ideas for functions that might be helpful?

 

Note this is the version of your polylineJoin function I'm using (modified slightly):

(defun polylineJoin 
       
  (pjss / *error* doc svn svv nextent pjinit inc edata pjent)
  
  ; VARLIST
    ;; INPUTS
      ;;; pjss - input selection set, must be filered before inputting: '((0 . "LINE,ARC,*POLYLINE")) (PICKSET)    
    ;; LOCAL VARS
      ;;; *error* - local error handling function (SYM)
      ;;; doc - AutoCAD active document, for purposes of end/start undo mark (VLA-OBJECT)
      ;;; svn - system variable names (LIST)
      ;;; svv - system variable values (LIST)
      ;;; nextent - entity used as starting point to check for new entities to join (ENAME)
      ;;; pjinit - initial number starting for loop (INT)
      ;;; inc - for loop incrementer (INT)
      ;;; edata - entity definition data, for purposes of removing invalid entities or fixing joined entities (ASSOC LIST)
      ;;; pjent - entity to be deleted from selection set if invalid shape (ENAME)

  ; general error handling
  (defun *error* (errmsg)
    
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
        (princ (strcat "\nError: " errmsg))
    )
    
    ; reset system variables, end undo, exit quietly
    (mapcar 'setvar svn svv)
    (vla-endundomark doc)
    (princ)
  )

  ; if there is a valid selection set
  (if pjss
    (progn
      
      ; start undo mark
      (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
      
      ; get initial system vars and next joining entity reference
      (setq
        svn '(cmdecho peditaccept)
        svv (mapcar 'getvar svn)
        nextent (entlast)
      )
      
      ; loop through selection set
      (repeat (setq pjinit (sslength pjss) inc pjinit)
      
        ; remove any 2D "heavy", 3D polylines, or splined/fitted 2D lines from selection set
        (if 
          (and
            (= 
              (cdr (assoc 0 (setq edata (entget (setq pjent (ssname pjss (setq inc (1- inc))))))))
              "POLYLINE" ; 2D "heavy" or 3D Polyline
            )
            (=
              (= (cdr (assoc 100 (reverse edata))) "AcDb3dPolyline"); 3D
              (member (boole 1 6 (cdr (assoc 70 edata))) '(2 4)); splined or fitted 2D
            )
          )
          (ssdel pjent pjss)
        )
      )
      
      ; turn off command echo, turn on peditaccept
      (mapcar 'setvar svn '(0 1))
      
      ; in case of older polylines (extreme edge case)
      (setvar 'plinetype 2)
      
      ; if the remaining selection set is valid
      (if pjss
      
        ; join entities based on different scenarios
        (cond
          ( (= pjinit (sslength pjss) 1); selected only one, and it qualifies
            (command "_.pedit" pjss "_join" "_all" "" ""); join everything possible to it
          ); single-selection condition
          
          ( (> (sslength pjss) 1); more than one qualifying object
            (command "_.pedit" "_multiple" pjss "" "_join" "0.0" "")
          ); multiple qualifying condition
          
          ((prompt "\nSingle object not viable, or no more than 1 of multiple selection viable."))
        )
        
        ; else
        (prompt "\nNothing viable selected.")
      )
      
      ; look through entities in selection set to set arcs/lines back to arcs/lines (may have gotten converted to plines)
      (while (setq nextent (entnext nextent))
      
        (setq edata (entget nextent))
        (if
        
          (and
            (= (cdr (assoc 90 edata)) 2)
            (not (vlax-curve-isClosed nextent))
          )
          
          (command "_.explode" nextent)
        )
      )
      
      ; reset system vars, end undo mark
      (mapcar 'setvar svn svv)
      (vla-endundomark doc)
    )
    
    (prompt "\nNo qualifying object(s) selected.")
  )
  
  (princ)
)
0 Likes
Message 7 of 8

Kent1Cooper
Consultant
Consultant

How about, in stepping through all newer things to look for what were originally unconnected Lines/Arcs [to Explode back into Lines/Arcs], putting each thing [either the thing itself or the result of Exploding it, as appropriate] into the initial selection set? [untested]:

 

      (while (setq nextent (entnext nextent))
        (setq edata (entget nextent))
        (if
          (and
            (= (cdr (assoc 90 edata)) 2)
            (not (vlax-curve-isClosed nextent))
          )
          (progn ; then
            (command "_.explode" nextent)
            (ssadd (entlast) pjss); put Explode result into initial set
          ); progn
          (ssadd nextent pjss); else -- put into initial set
        ); if
      )

 

It may depend on what you want to do with them.  That will leave you a selection set that includes entity names of things that no longer exist.  If that's a problem, start a new initially-empty selection set and put them into that.

Kent Cooper, AIA
0 Likes
Message 8 of 8

Jonathan_Bell82GXG
Enthusiast
Enthusiast

As for first making that empty selection set, it seems like first declaring a nil variable and then using ssadd with that doesn't work. Would the best practice be to do something like:

(setq emptyss  (ssdel (ssname (ssget "_L") 0) (ssget "_L")))

 

Also, it seems like that method still won't retrieve the newly created entities (results of joining connected entities)

0 Likes