Jump to content

Replicate copy command with copybase & pasteclip


Serhan_BAKIR

Recommended Posts

I'm trying to create a copy command alternative with copybase and then pasteclip. For a single copy below code works fine but for continuous multiple copying I couldn't figure out how to loop the pasteclip without hindering the visual aspect of the operation (as if you are using copymode=0). Help is highly appreciated.

 

(defun c:co (/ sset basepoint)
  (princ "\nSelect objects:")
  (setq sset (ssget))
  (setq basepoint (getpoint "\nSpecify base point:"))
  (vl-cmdf "_.copybase" basepoint sset "")
  (vl-cmdf "pasteclip" pause)
  (princ)
)

 

Link to comment
Share on other sites

Try this

(defun c:co (/ sset basepoint)
  (princ "\nSelect objects:")
  (setq sset (ssget))
  (setq basepoint (getpoint "\nSpecify base point:"))
  (vl-cmdf "_.copybase" basepoint sset "")
(while (setq pt (getpoint "Pick next point Enter to stop "))
(vl-cmdf "pasteclip" pt)
)
(princ)
)

 

  • Like 1
Link to comment
Share on other sites

Well I've tried that approach but it's not that convenient as using original multiple copy since I don't want to compromise the visual aspect. Perhaps we need a (grread) or some sort, to keep showing the elements floating. I tried to show the difference below. First is the lisp loop with getpoint, second is the original copy behaviour which I'd like to replicate.

 

Any further help will be appreciated. Thanks

 

co.gif

Link to comment
Share on other sites

  • 2 weeks later...

Anybody has any other ideas? I'm stuck. You'd ask why not just use copy.. Since the copy command clones the stored handle xdata, I'm using copybase instead (which renews the xdata) and I need above mentioned functionality with copybase and pasteclip.. Please help me out. 

Link to comment
Share on other sites

If the normal copy works visually for you how about use that and delete the xdata afterwards? Not sure if that would work for you. Might get problems if the user cancels the LISP before the xdata is removed.

 

Do a while loop, while cmdactive perhaps

then copy

then remove xdata

end while loop

 

Something like that

Link to comment
Share on other sites

Well actually for entities, I need that handle-xdata (soft pointer - 1005) to be regenerated, not cloned or removed. "copybase & pasteclip" regenerates it but "copy" clones the xdata.

 

I need to use pasteclip in a loop but couldn't find how to do it without loosing visuals. 

 

Thanks

Link to comment
Share on other sites

@Serhan_BAKIR

 

I think you don't need LISP for this kind of job... You need combo : ctrl+shift+C (copybase), pick point, select object(s) and the rest is simple... Just use multiple times ctrl+V (pasteclip)... You should be able to see where your object(s) are to be copied... Even more you can copybase+pasteclip between different DWG(s), but you can't do that between AutoCAD and BricsCAD, only during working in AutoCAD - between opened DWG(s), or between opened DWG(s) in BricsCAD session...

Link to comment
Share on other sites

A bit of a blunt approach below, copy the objects using a normal copy to give the visual impact you want, delete these and replace with 'copybase' copied objects, and repeat however you like. Below I have just put in a repeat 3 to give the loop effect, end the loop to your won preferences though.

 

(defun c:testthis ( / pt1 pt2 MySS acount MyList)

  (setq pt1 (getpoint "Select Base Point")) ; base point
  (princ "Select Object to Copy")
  (setq MySS (ssget)) ; select objects

(repeat 3 ; do a loop however you want. 3 for demonstration purposes
    (command "copy" MySS "" pt1 pause) ; copy showing copy points
    (setq pt2 (getvar 'lastpoint)) ; 2nd point
 
    (setq acount 0)
    (while (< acount (sslength MySS))
      (entdel (entlast))
      (setq acount (+ acount 1))
    ) ; end while

    (command "copybase" pt1 MySS "")
    (command "pasteclip" pt2)
  ) ; end repeat

)

 

Link to comment
Share on other sites

23 hours ago, marko_ribar said:

I think you don't need LISP for this kind of job... You need combo : ctrl+shift+C (copybase), pick point, select object(s) and the rest is simple... Just use multiple times ctrl+V (pasteclip)...

Dear @marko_ribar, I wish I could say to hundreds of users that I'm canceling their copy command and they will use multiple ctrl+v from now on.. but it's not an option for us.

 

20 hours ago, Steven P said:

A bit of a blunt approach below, copy the objects using a normal copy to give the visual impact you want, delete these and replace with 'copybase' copied objects, and repeat however you like. Below I have just put in a repeat 3 to give the loop effect, end the loop to your won preferences though.

 

Thanks @Steven P, I also tried a similar approach to what you offer as below (addition to my first post). But the looping part is tricky :) I couldn't figure out how to form a loop which will end gracefully by a right click, enter or esc.

 

(repeat 3
    (vl-cmdf "_.copybase" basepoint sset "")
    (vl-cmdf "pasteclip" pause)
  )

 

I've been trying to implement grread but couldn't. I appreciate all the inputs, hopefully you'll lead me to right direction.

Thanks

Link to comment
Share on other sites

Without using grread, you could use an error function - loads of examples out there - and assuming that this is all you want the command to do, copy base point, then the error function could exit quietly?

 

Yes, I see how grread would work with this. I'll have a think

Link to comment
Share on other sites

An example using an error function at the end of a loop. Not the best way to do loops but it works. Loop ends on 'escape'

 

(defun c:testthis ( / pt1 pt2 MySS acount MyList)
  (defun trap1 (errmsg)                ;;refer to afraLISP
    (princ "\nCopyBase Cancelled. ")
    (princ)
  )

  (setq temperr *error*)               ;;store *error*
  (setq *error* trap1)                 ;;re-assign *error*

  (setq pt1 (getpoint "Select Base Point")) ;; Select base point
  (princ "Select Object to Copy")           ;; Select objects message
  (setq MySS (ssget))                       ;; select objects
  (setq endthis 0)                          ;; can use this to end the loop however else
  (while (= endthis 0)                      ;; Loop till escape pressed
    (setq result (command "copy" MySS "" pt1 pause)) ;; normal copy so can see copy
    (setq pt2 (getvar 'lastpoint))          ;; 2nd point
    (setq acount 0)                         ;; Remove copied items
    (while (< acount (sslength MySS))
      (entdel (entlast))
      (setq acount (+ acount 1))
    ) ; end while

    (command "copybase" pt1 MySS "")       ;;copybase selection sey
    (command "pasteclip" pt2)              ;;paste clip
    (princ "\nselect next point or <escape>")
  ) ; end while

  (setq *error* temperr)                   ;;restore *error*
  (princ)
)

 

Link to comment
Share on other sites

Here is an simple alternate method using an "acet" Express Tools function from the arx. Note: Express Tools must be installed.

(defun C:CBP (/ bp en p2 ss)
   
   (if (not (acet-util-ver))
      (arxload "acetutil.arx"
         (progn
            (princ "\nExpress Tools Failed to Load. Program Aborted.")
            (exit)
         )
      )
   )
   
   (if
      (and
         (progn (princ "\nSelect Objects to Copy: ")(setq ss (ssget)))
         (setq bp (getpoint "\nSelect Base Point of Displacement: "))
      )
      (progn
         (command "copybase" bp ss "")
         (while (setq p2 (acet-ss-drag-move ss bp "\nSelect Second Point of Displacement: " T))
            (command "pasteclip" p2)
         )
      )
   )
   (princ)
)

 

Edited by pkenewell
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

20 hours ago, Steven P said:

An example using an error function at the end of a loop. Not the best way to do loops but it works. Loop ends on 'escape'

Hello @Steven P I got it but this approach cancels out enter and right click options to end the loop and if these are used multiple copies occur at the primary basepoint.

 

19 hours ago, pkenewell said:

Here is an simple alternate method using an "acet" Express Tools function from the arx. Note: Express Tools must be installed.

Thank you @pkenewell I see that acet-ss-drag-move provides a solution which I couldn't do by myself. I'm hesitant to use express tools. I wish I could see how they coded this function :)  

Link to comment
Share on other sites

7 minutes ago, Serhan_BAKIR said:

Thank you @pkenewell I see that acet-ss-drag-move provides a solution which I couldn't do by myself. I'm hesitant to use express tools. I wish I could see how they coded this function :)  

@Serhan_BAKIR

1) Look at it this way - at least Autodesk directly supports Express Tools, rather than an independent free developer that might stop supporting it at any time.

2) You would need to learn how to program in C++ / arx, or dotNet to replicate the Express Tools behavior.

3) Using a grread solution would require a ton of extra code to capture things like object snaps, osnap tracking, polar tracking, function keys, etc. Some developers such as Lee Mac (example) have implemented some of these things, and you could put together much of the functionality - but is is really worth it? It would be LESS code to hunt for specific XDATA cloned from the copy command and remove it, rather than all that. Perhaps a redefined copy command or a reactor?

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