replace 3d polyline with block

replace 3d polyline with block

eng.girgis.adly
Enthusiast Enthusiast
2,332 Views
14 Replies
Message 1 of 15

replace 3d polyline with block

eng.girgis.adly
Enthusiast
Enthusiast

Dears ,

I need a lisp to repace 3d polylines by block in Autocad to do the same job as the lisp in the below video

https://youtu.be/FLHMoSoHLdI

- i need to replace the yellow 3d polylines in the attached drawing by green block 

 

0 Likes
Accepted solutions (1)
2,333 Views
14 Replies
Replies (14)
Message 2 of 15

diagodose2009
Collaborator
Collaborator

Please you upload one DWG (old-version Acad2011+).Please  you downloading the RevCad you test this routine inside DWG. You create on left-screen (BEFORE) and right-screen(AFTER).Is very hard to understand on AIR online.

 

0 Likes
Message 3 of 15

eng.girgis.adly
Enthusiast
Enthusiast

please see the attached drawing

0 Likes
Message 4 of 15

Sea-Haven
Mentor
Mentor

So convert what you have to blocks of a pattern  ? It makes sense to ignore the patterns as they appear to be trying to create solids etc.

 

So make some new blocks

1 & 3 a circle with hatch solid.

2 an ellipse with hatch solid

4 two circles

5 make block as fairly simple pattern.

 

For all of them can use Bounding box to get a x and y distance insert the correct block compared to type at mid pt of bounding box.

 

 An example for say 4 draw an outside circle Dia 1 inside rad in proportion. Then use the x dist for scale. If want polygon do so.

 

Need to use bounding box for multi items need to find. Lee-mac multi bounding box comes to mind.

 

Note for 2 that ellipse is rotated 90 so check length X & Y if required swap and insert so is oriented correct.

 

The ellipses are a problem there is 7125 objects so multi bounding box takes a while it may be faster to just get minx maxx miny maxy. Possible fastest is pick four points also simplest. There are 4 ellipses so doing calcs I expect slower than pick 4 points. I tried pick 4 times small amounts still got 672 objects.

 

I may be looking at this wrong.

 

screenshot230.png

 

 

0 Likes
Message 5 of 15

Sea-Haven
Mentor
Mentor

Fastest for the ellipse was "ellipse" cen, top, right, then hatch last, solid. Way faster than getting the bounding box. Done manually.

0 Likes
Message 6 of 15

eng.girgis.adly
Enthusiast
Enthusiast

thanks for your support 

your ideas is a way but there is a lisp which do all that steps like the video in the link, I ask if someone have a similar lisp 

0 Likes
Message 7 of 15

Sea-Haven
Mentor
Mentor

It can be done, what I referred to was the problem with the ellipse having so many lines making the solid, I tested hence the 7128 objects but its slow. It needs a few routines so pick the correct type to make. Look at youtube.

 

The simple objects like circle filled or dual circle are quick to process. If I have time will do something.

 

Did you contact the youtube author ttps://payazed.wordpress.com/revcad/h

 

0 Likes
Message 8 of 15

trevor.bird.au
Advocate
Advocate
Accepted solution

Hi Girgis,

 

Please try the following which will replace an AutoCAD Group of objects with a selected block inserted at the centre of the bounding box that contains the Group:

 

;;  ReplaceGroups.lsp by Trevor Bird
;;
;;  2020-07-22

;;----------------------------------------------------------------------------------------
(defun c:replacegroups
  (
    /

    assoc_330

    bbmax_wcs_list
    bbmax_wcs_sa
    bbmin_wcs_list
    bbmin_wcs_sa

    dps_340

    group_dxf
    group_ename

    list_340
    list__ss_source

    midpoint_wcs_list

    obj_insert_replacement
    obj_insert_source
    obj_source

    progress_int

    reactors_dxf

    source_dxf
    source_ename
    ss_filter
    ss_insert
    ss_source
  )
  (setq ss_filter
    (list
      (if (= (getvar 'CVPORT) 1)
        (cons 410 (getvar 'CTAB))
        '(410 . "Model")
      );if
    );list
  );setq




  (cond
    ( (not
        (progn
          (princ "\nSelect source Groups for replacement:")
          (setq ss_source (ssget ss_filter))
        );progn
      );not
      (princ "\nNo source Groups selected.")
    )


    ( (not
        (progn
          (princ "\nSelect replacement block:")
          (setq ss_insert (ssget ":S" (cons '(0 . "INSERT") ss_filter)))
        );progn
      );not
      (princ "\nNo replacement block selected.")
    )


    (ss_source
      ;;  Replacement block
      (setq obj_insert_source (vlax-ename->vla-object (ssname ss_insert 0)))


      ;;  Groups for replacement
      (setq list__ss_source   (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss_source))))

      (while list__ss_source
        (setq source_ename      (car list__ss_source)
              list__ss_source   (cdr list__ss_source)
              source_dxf        (entget source_ename)
        );setq


        (cond
          ( (not (setq reactors_dxf (member '(102 . "{ACAD_REACTORS") source_dxf))))
          ( (not (setq reactors_dxf (reverse (member '(102 . "}") (reverse reactors_dxf))))))
          ( (not (setq assoc_330    (assoc 330 reactors_dxf))))
          ( (not (setq group_ename  (cdr assoc_330))))
          ( (not (setq group_dxf    (entget group_ename))))

          (group_dxf
            (setq dps_340         (vl-remove-if-not '(lambda ( _dp ) (= (car _dp) 340)) group_dxf)
                  list_340        (mapcar 'cdr dps_340)
                  bbmin_wcs_list  nil
                  bbmax_wcs_list  nil
            );setq

            (setq progress_int  0)
            (if acet-ui-progress-init (acet-ui-progress-init "Processing group" (length list_340)))

            (foreach fe__ename list_340
              ;;  Remove all objects in group from list__ss_source
              (setq list__ss_source (vl-remove fe__ename list__ss_source)
                    obj_source      (vlax-ename->vla-object fe__ename)
              );setq

              (vlax-invoke-method obj_source 'GetBoundingBox 'bbmin_wcs_sa 'bbmax_wcs_sa)

              ;;  From Lee Mac - Selection Set Bounding Box
              (setq bbmin_wcs_list  (mapcar 'min (vlax-safearray->list bbmin_wcs_sa) (cond (bbmin_wcs_list) ((vlax-safearray->list bbmin_wcs_sa))))
                    bbmax_wcs_list  (mapcar 'max (vlax-safearray->list bbmax_wcs_sa) (cond (bbmax_wcs_list) ((vlax-safearray->list bbmax_wcs_sa))))
              );setq


              (vlax-invoke-method obj_source 'Delete)
              (vlax-release-object obj_source)

              (setq progress_int  (1+ progress_int))
              (if acet-ui-progress-safe (acet-ui-progress-safe progress_int))
            );fe__ename

            (if acet-ui-progress-done (acet-ui-progress-done))


            ;;  Midpoint of group bounding box
            (setq midpoint_wcs_list
              (list
                (/ (apply '+ (mapcar 'car (list bbmin_wcs_list bbmax_wcs_list))) 2.0)
                (/ (apply '+ (mapcar 'cadr (list bbmin_wcs_list bbmax_wcs_list))) 2.0)
                (/ (apply '+ (mapcar 'caddr (list bbmin_wcs_list bbmax_wcs_list))) 2.0)
              );list
            );setq

            (setq obj_insert_replacement  (vlax-invoke-method obj_insert_source 'Copy))
            (vlax-put-property obj_insert_replacement 'InsertionPoint (vlax-3d-point midpoint_wcs_list))

            (vlax-release-object obj_insert_replacement)
          );group_dxf
        );cond
      );while


      (vlax-release-object obj_insert_source)
    );ss_source
  );cond


  (princ)
);c:replacegroups




;;----------------------------------------------------------------------------------------
(princ "\nReplaceGroups loaded. Start command with REPLACEGROUPS.")
(princ)

 

 ReplaceGroups.gif

 The video was edited to speed up the time it took to process the last Group selected which had 14253 objects.

I also reset the insertion point of some of the blocks which was not local to the objects in the block.

 

Regards,

Trevor

Message 9 of 15

eng.girgis.adly
Enthusiast
Enthusiast

wow , you are great

it is exactly what I need 

thanks alot my dear 🙂

 

0 Likes
Message 10 of 15

Sea-Haven
Mentor
Mentor

The issue was with the dual 7128 objects in the ellipse how long it took to work out a bounding box, so a block could be placed. That way a group is not required. I dont know if finding the end points is any faster so get a box also. 

0 Likes
Message 11 of 15

Sea-Haven
Mentor
Mentor

This is instant on the 14,000 lines just need to work out the rest etc. At least have a bounding box so can work out centre and scale. This is useful if its lines not groups.

 

 

(setq xmin 10000000.0)
(setq xmax 0.0)
(setq ymin 10000000.0)
(setq ymax 0.0)
(setq ss (ssget '((0 . "line"))))
(repeat (setq x (sslength ss))
(setq ent (entget (ssname ss (setq x (- x 1)))))
(setq st (cdr (assoc 10 ent)))
(setq end (cdr (assoc 11 ent)))
(if (> xmin (car st))(setq xmin (car st)))
(if (> xmin (car end))(setq xmin (car end)))
(if (< xmax (car st))(setq xmax (car st)))
(if (< xmax (car end))(setq xmax (car end)))
(if (> ymin (cadr st))(setq ymin (cadr st)))
(if (> ymin (cadr end))(setq ymin (car end)))
(if (< ymax (cadr st))(setq ymax (cadr st)))
(if (< ymax (cadr end))(setq ymax (cadr end)))
)
(princ (strcat (rtos xmin 2 3) " " (rtos xmax 2 3) " " (rtos ymin 2 3) " "(rtos ymax 2 3)))

 

  

0 Likes
Message 12 of 15

eng.girgis.adly
Enthusiast
Enthusiast

have I add this code to the main code or it is a separate lisp?

0 Likes
Message 13 of 15

Sea-Haven
Mentor
Mentor

The response was directed to sonic as like him the time to look at a group and get bounding box is lengthy for some objects so maybe get all objects of a group and use the example code. Need to test.

0 Likes
Message 14 of 15

tomwilhelm
Contributor
Contributor

Hello Trevor,

what commands did you use after selecting the desired group?

Whenever I run the lisp it allows me to select the groups. After I selected the group it then Errors after pressing Enter for the next step. The Error in console referrs to an incorrect Charactersequence for  ssget-Mode:

Befehl: REPLACEGROUPS
Select source Groups for replacement:36 gefunden
Select replacement block:; Fehler: Fehlerhafte Zeichenfolge für ssget-Modus
Befehl:

It did not give me the option to select the block to replace with.

 

0 Likes
Message 15 of 15

trevor.bird.au
Advocate
Advocate

Hi Tom,

 

Please try the following; the selection method may require an underscore "_" for foreign language support.

Replace:
(setq ss_insert (ssget ":S" (cons '(0 . "INSERT") ss_filter)))


with:
(setq ss_insert (ssget "_:S" (cons '(0 . "INSERT") ss_filter)))

 

Regards,

Trevor