Jump to content

Joining Objects with very large SelectionSet


AM-AP

Recommended Posts

Hi all,

 

I'm working on some code to handle potential selectionset counts of up to 500,000 objects (Large contour files made from lines/single segment polylines/polylines with multiple segments)

 

 

 

Currently, the file has many, many polyline contours with given z values, and some 'broken' segments; ie

 

  • Polyline Contour '1' with a z value of 100 goes from Point 'A', to 'B', to 'C', to 'D'
  • Polyline Contour '2' with a z value of 100 goes from Point 'E' to 'F', to 'G'
  • Line/Polyline '1' with an elevation 100 goes from Point 'D' to point 'G'

 - All three of these objects could be joined into a single polyline contour

 

Another example would be 

  • Polyline Contour '3' with a z value of 100 goes from Point 'A', to 'B', to 'C', to 'D'
  • Polyline Contour '4' with a z value of 100 goes from Point 'E' to 'F', to 'G' to 'A'

 - These two objects could be joined into one object

 

I found this lisp from Kent Cooper, but I find it does not work very well with these very large selectionset object counts I'm working with.

 

I will note that the single segment lines/polylines are far fewer in object count than the large contour polylines. I thought perhaps I could filter the single segment lines out from the larger selectionset, and then check each segment end if these is another object touching them. But I do not know how to do this, and it wouldn't account for broken contours made up of two (or more) multi-segment polylines

 

Is there a more efficient way of handling large selection sets? Has this been done before? I haven't handled large selectionsets before in LISP, and I'm not sure where to start.

I'd really appreciate any thoughts/advice, or points in the right direction.

 

Cheers!

 

AM

;;  PolylineJoin.lsp [command name: PJ]
;;  Joins viable objects [Lines/Arcs/LWPolylines/not-splined-or-fitted 2DPolylines]
;;    into connected LWPolylines.
;;  Rejects splined/fitted 2DPolylines, [joining them to other objects removes their
;;    spline/fit curvature] and 3DPolylines [can't be joined].
;;  If one viable object is selected, joins all other possible objects [contiguous at ends to
;;    it and to each other] to it, into one LWPolyline.
;;  If multiple viable objects are selected, joins them into as many LWPolylines as
;;    appropriate, not including anything contiguous at ends that was not selected.
;;  Leaves selected Lines/Arcs that are not contiguous to anything else as Lines/Arcs,
;;    not converted into one-segment Polylines.
;;  Concept from c:pljoin by beaufordt on AutoCAD Customization Discussion Group
;;  Streamlined by Kent Cooper, June 2011; expanded capabilities July 2012
;;  Last edited 16 July 2012

(defun PJ ; = Polyline Join
    (selset / *error* pjss cmde peac nextent pjinit inc edata pjent)
    
    (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*
    
    (setq
        pjss selset
        cmde (getvar 'cmdecho)
        peac (getvar 'peditaccept)
        nextent (entlast); starting point for checking new entities
    ); setq
    (repeat 
        (setq 
            pjinit (sslength pjss) 
            inc pjinit
        ); PJ INITial-selection quantity & incrementer
        (if
            (and
                (=
                    (cdr 
                        (assoc 0 
                            (setq edata 
                                (entget 
                                    (setq pjent 
                                        (ssname pjss 
                                            (setq inc (1- inc))
                                        )
                                    )
                                )
                            )
                        )
                    )
                    "POLYLINE" ; 2D "heavy" or 3D Polyline
                ); =
                (or
                    (= 
                        (cdr 
                            (assoc 100 
                                (reverse edata)
                            )
                        ) "AcDb3dPolyline"
                    ); 3D
                    (member 
                        (boole 1
                            6 
                            (cdr 
                                (assoc 70
                                    edata
                                )
                            )
                        )
                        '(2 4)
                    ); splined or fitted 2D
                ); or
            ); and
            (ssdel pjent pjss); remove 3D, splined/fitted 2D from set
        ); if
    ); repeat
    (setvar 'cmdecho 0)
    (command "_.undo" "_begin")
    (setvar 'peditaccept 1)
    (setvar 'plinetype 2); [just in case; assumes no desire to save and set back if different]
    
    (if pjss ; selected qualifying object(s)
        (cond ; then
            (
                (= 
                    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 <= 1 of multiple selection viable."))
        ); cond
        (prompt "\nNothing viable selected.")
    ); outer if
    (while (setq nextent (entnext nextent)); start with first newly-created Pline, if any
        (if ; revert any un-joined Lines/Arcs back from Pline conversion
            (and ; newly-created single-segment Pline from unconnected Line/Arc
                (= 
                    (cdr 
                        (assoc 90 
                            (entget nextent)
                        )
                    ) 
                    2
                )
                (not (vlax-curve-isClosed nextent))
            ); and
            (command "_.explode" nextent)
        ); if
    ); while
    (setvar 'peditaccept peac)
    (command "_.undo" "_end")
    (setvar 'cmdecho cmde)
    (princ)
); defun

(defun C:PJ1 ()
    (PJ (ssget '((0 . "LINE,ARC,*POLYLINE"))))
    (princ)
); defun

 

Edited by AM-AP
Clarity
Link to comment
Share on other sites

I never tried with so many objects, but can't you just select a polyline enter PE (polyline edit), J (join), and when AutoCAD prompts you to select the objects, enter ALL and let AutoCAD to do the hard work?

  • Like 1
Link to comment
Share on other sites

BricsCAD has a join command that should work very well for this. 

 

AutoCAD has this too, just type join and select all

Edited by Danielm103
Link to comment
Share on other sites

The LISP you have from Kent Cooper - doesn't work very well - can you describe how it doesn't work very well? Might be something in there that can be fixed if the basis of the code works well for fewer objects

Link to comment
Share on other sites

To cut down on the size of the set, could you select them by elevation and do one group at a time? Maybe draw a line, select by crossing, cycle through each elevation, change the resulting contours to a temporary layer, and continue until there's nothing left? A little clunky, but better than the alternative.

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