Jump to content

Recommended Posts

Posted

I've made a lisp function which utilises the command '._-insert' and '._-Layer' so it will paste a block from a separate file onto a user defined polyline at a specific distance but its rather slow

 

is there a way to create/ change this so it doesn't use the command feature so its much quicker? 

 

my current code:

(defun c:coneline (/ d1 d2 dist pline op startpt endpt tl tot)
  (defun coning(dist)
    (setq cmd (getvar 'CMDECHO)) (setvar "CMDECHO" 0)
    (command "_.layer" "s" "0" "") 
    (setq conepath "C:/.../.../Blocks/Cone.dwg")
    (setq startpt (vlax-curve-getStartPoint pline)
        endpt  (vlax-curve-getEndPoint pline)
        tot 0
        op  (if (minusp (- (vlax-curve-getdistatpoint pline (vlax-curve-getclosestpointto pline endpt))
                           (setq d1 (vlax-curve-getdistatpoint pline (vlax-curve-getclosestpointto pline startpt)))))
              -
              +)
        tl  (if (= op -)
              (vlax-curve-getdistatparam pline (vlax-curve-getstartparam pline))
              (vlax-curve-getdistatparam pline (vlax-curve-getendparam pline))))
    (while ((if (= op -)
      >=
      <=)   (setq d2 (op d1 tot))
      tl)
    (command "._-insert" conepath (setq startpt (vlax-curve-getpointatdist pline d2)) 0.3 0.3 0)
    (setq tot (+ tot dist)))
    (setvar 'cmdecho echo)
    (princ)
  )
  
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: "))))
  (setq dcl_id (load_dialog "C:\\...\\...\\Dialogs\\CONELINE.dcl"))
  (if (not (new_dialog "CONELINE" dcl_id))
    (exit))
  (action_tile "c10"  "(setq spacing 1)")
  (action_tile "c15"  "(setq spacing 1.5)")
  (action_tile "c20"  "(setq spacing 2)")
  (action_tile "c30"  "(setq spacing 3)")
  (action_tile "c45"  "(setq spacing 4.5)")
  (action_tile "c90"  "(setq spacing 9)")
  (action_tile "c18"  "(setq spacing 18)")
  (start_dialog)(unload_dialog dcl_id)
  (coning spacing)
  (princ)
)

 

Posted

This takes out most of the calculations probably where you slow down is.

 

Select spacing from dcl

select polyline

get its length

divide by the polyine by spacing and round to the whole number

(repeat by said number while adding spacing to dist to calculate the new point

 

 

(defun C:coneline (/ pline len spacing)
  (setq dcl_id (load_dialog "C:\\...\\...\\Dialogs\\CONELINE.dcl"))
  (if (not (new_dialog "CONELINE" dcl_id))
    (exit)
  )
  (action_tile "c10"  "(setq spacing 1)")
  (action_tile "c15"  "(setq spacing 1.5)")
  (action_tile "c20"  "(setq spacing 2)")
  (action_tile "c30"  "(setq spacing 3)")
  (action_tile "c45"  "(setq spacing 4.5)")
  (action_tile "c90"  "(setq spacing 9)")
  (action_tile "c18"  "(setq spacing 18)")
  (start_dialog)
  (unload_dialog dcl_id)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
  )
  (setvar 'clayer "0")
  (setq dist spacing)
  (setq conepath "C:/.../.../Blocks/Cone.dwg") ;could be combined with -insert
  (repeat (fix (/ len spacing)) 
    (command "._-insert" conepath "_non" (vlax-curve-getpointatdist pline dist) 0.3 0.3 0)
    ;(command "._-insert" "C:/.../.../Blocks/Cone.dwg" "_non" (vlax-curve-getpointatdist pline dist) 0.3 0.3 0)
    (setq dist (+ dist spacing))
  )    
  (setvar 'cmdecho 1)  
  (princ)
)

 

 

Posted

I am a bit confused about your code I think you are checking for pline pick end for direction.

 

(setq ent (entsel "\nSelect polyline: "))
(setq pt3 (cadr ent))
(setq pline (vlax-ename->vla-object (car ent)))
(setq pt1 (vlax-curve-getStartPoint pline))
(setq pt2 (vlax-curve-getEndPoint pline))
(setq d1 (distance pt1 pt3) d2 (distance pt2 pt3))
(if (> d1 d2)
(command "pedit" ent "R" "")
)

 

Because your doing insert block repeatedly you can get the length of the pline and use that in a while 

 

(while (< tot len)

 

Have you looked at the command Divide or Measure built in to CAD.

Posted

I've changed this slightly to vla-insertblock because its seems slightly quicker but its still very slow, would I the possible to insert the block at the start point then copy the block along the line at specific points?

 

I saw in the 'copyalongcurvelsp' a func which copies the block along the line but I'm having issues trying to selected the specific block (by name if possibe), the best I could get was to inset the block to 0 0 0 coordinated then selected via co-ords but the only issue with this is the block has to be rendered in and not overlapping with anything else. I want to selected just the cone block

 

(I've removed the dcl for now and hard coded a distance in just to shorten the code for now)

 

(defun c:testing ()
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
  )
  (setvar 'clayer "0")
  (setq dist 3)
  (repeat (fix (/ len 3)) 
    (vla-insertblock
      (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
      (vlax-curve-getpointatdist pline dist)
      "C:\\BricsCAD Scripts\\Tools\\Blocks\\Cone.dwg"
      0.3
      0.3
      0.3
      0
    )
    (setq dist (+ dist 3))
  )
)

 

9 hours ago, mhupp said:

This takes out most of the calculations probably where you slow down is.

 

Select spacing from dcl

select polyline

get its length

divide by the polyine by spacing and round to the whole number

(repeat by said number while adding spacing to dist to calculate the new point

 

 

(defun C:coneline (/ pline len spacing)
  (setq dcl_id (load_dialog "C:\\...\\...\\Dialogs\\CONELINE.dcl"))
  (if (not (new_dialog "CONELINE" dcl_id))
    (exit)
  )
  (action_tile "c10"  "(setq spacing 1)")
  (action_tile "c15"  "(setq spacing 1.5)")
  (action_tile "c20"  "(setq spacing 2)")
  (action_tile "c30"  "(setq spacing 3)")
  (action_tile "c45"  "(setq spacing 4.5)")
  (action_tile "c90"  "(setq spacing 9)")
  (action_tile "c18"  "(setq spacing 18)")
  (start_dialog)
  (unload_dialog dcl_id)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
  )
  (setvar 'clayer "0")
  (setq dist spacing)
  (setq conepath "C:/.../.../Blocks/Cone.dwg") ;could be combined with -insert
  (repeat (fix (/ len spacing)) 
    (command "._-insert" conepath "_non" (vlax-curve-getpointatdist pline dist) 0.3 0.3 0)
    ;(command "._-insert" "C:/.../.../Blocks/Cone.dwg" "_non" (vlax-curve-getpointatdist pline dist) 0.3 0.3 0)
    (setq dist (+ dist spacing))
  )    
  (setvar 'cmdecho 1)  
  (princ)
)

 

 

 

5 hours ago, abra-CAD-abra said:

 

  • Like 1
Posted

You could  calculate the Model Space outside of the repeat since it doesn't change and only have to run once rather then every time its inserting a block.

 

(defun c:testing (/ pline len MSpace dist)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
        MSpace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
        spacing 3
        dist spacing
  )
  (setvar 'clayer "0")
  (repeat (fix (/ len spacing)) 
    (vla-insertblock 
      MSpace
      (vlax-curve-getpointatdist pline dist)
      "C:\\BricsCAD Scripts\\Tools\\Blocks\\Cone.dwg"
      0.3
      0.3
      0.3
      0
    )
    (setq dist (+ dist spacing))
  )
)

 

Posted

thank you, I've amended this.

 

I think the only way to speed this up now to avoid using insert multiple times, but rather insert one to the start point then copy that block along the lin.

 

I've nearly sorted something for but I'm having an issue selecting the block I'm doing:

(if (setq blk (ssget "_X" (list '(0 . "INSERT") (cons 2 "Cone"))))
              (vlax-ename->vla-object (ssname blk 0)))

 but this is grabbing all block with that name, how could I filter/ limit it to only select one of the block? and then set the base point of the item?

 

33 minutes ago, mhupp said:

You could  calculate the Model Space outside of the repeat since it doesn't change and only have to run once rather then every time its inserting a block.

 

(defun c:testing (/ pline len MSpace dist)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
        MSpace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
        spacing 3
        dist spacing
  )
  (setvar 'clayer "0")
  (repeat (fix (/ len spacing)) 
    (vla-insertblock 
      MSpace
      (vlax-curve-getpointatdist pline dist)
      "C:\\BricsCAD Scripts\\Tools\\Blocks\\Cone.dwg"
      0.3
      0.3
      0.3
      0
    )
    (setq dist (+ dist spacing))
  )
)

 

 

Posted (edited)

Yeah I'm not pulling from a file so its pretty much instant here. so insert the file once, then pull from the block library for the rest with just the name of the block "Cone". its still an insert but technically acts like a copy.

 

(defun c:testing (/ pline len MSpace dist)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
        MSpace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
        spacing 3
        dist spacing
  )
  (vla-insertblock ;Insert "first" block from folder
    MSpace
    (vlax-curve-getpointatdist pline dist)
    "C:\\BricsCAD Scripts\\Tools\\Blocks\\Cone.dwg"
    0.3
    0.3
    0.3
    0
  )
  (setq dist (+ dist spacing))
  (repeat (- (fix (/ len spacing)) 1)  ;account for first insert
    (vla-insertblock
      MSpace
      (vlax-curve-getpointatdist pline dist)
      "Cone" ;pulls from block library no need to access other file speed up?
      0.3
      0.3
      0.3
      0
    )
    (setq dist (+ dist spacing))
  )
)

 

Edited by mhupp
Posted (edited)
14 minutes ago, Charpzy said:

I've nearly sorted something for but I'm having an issue selecting the block I'm doing:

(if (setq blk (ssget "_X" (list '(0 . "INSERT") (cons 2 "Cone"))))
              (vlax-ename->vla-object (ssname blk 0)))

 but this is grabbing all block with that name, how could I filter/ limit it to only select one of the block? and then set the base point of the item?

 

 

 

(if (and (setq blk (entlast)) (eq (cdr (assoc 2 (entget blk))) "Cone"))

Would set the last entity. So if the last thing was insert it would be the block.

---edit

if statement check if its a block named cone

Edited by mhupp
Posted
3 hours ago, mhupp said:

Yeah I'm not pulling from a file so its pretty much instant here. so insert the file once, then pull from the block library for the rest with just the name of the block "Cone". its still an insert but technically acts like a copy.

 

(defun c:testing (/ pline len MSpace dist)
  (setq pline (vlax-ename->vla-object (car (entsel "\nSelect polyline: ")))
        len (vla-get-length pline)
        MSpace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
        spacing 3
        dist spacing
  )
  (vla-insertblock ;Insert "first" block from folder
    MSpace
    (vlax-curve-getpointatdist pline dist)
    "C:\\BricsCAD Scripts\\Tools\\Blocks\\Cone.dwg"
    0.3
    0.3
    0.3
    0
  )
  (setq dist (+ dist spacing))
  (repeat (- (fix (/ len spacing)) 1)  ;account for first insert
    (vla-insertblock
      MSpace
      (vlax-curve-getpointatdist pline dist)
      "Cone" ;pulls from block library no need to access other file speed up?
      0.3
      0.3
      0.3
      0
    )
    (setq dist (+ dist spacing))
  )
)

 

 

 

worked perfect, thank you

  • Like 1

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