Measure Command Work Around

Measure Command Work Around

Anonymous
Not applicable
1,642 Views
17 Replies
Message 1 of 18

Measure Command Work Around

Anonymous
Not applicable

Hi all,

 

I need a command that essentially functions the same as the measure command however it allows you to select a start and end point for the insertion of the block.

 

If anyone could help or point me in the right direction that would be great!

 

-Devin

0 Likes
Accepted solutions (1)
1,643 Views
17 Replies
Replies (17)
Message 2 of 18

CodeDing
Advisor
Advisor

@Anonymous ,

 

Can you further clarify what the "start" and "end" points of a block are? Blocks have 1 insertion point. are you referring to rotation? or a parameter?

 

Best,

~DD

0 Likes
Message 3 of 18

Anonymous
Not applicable

Oh sorry, I meant select a start and end point on the line, pline or whatever line one would normally use the measure command on. So essentially if you have a line you want to insert multiple blocks on you can select a start point and an end point then like the measure command it will insert and align the blocks at set intervals between those two points on the line.

 

I hope this clarifies. If not let me know and I can try and clarify further or try and show you more what I'm searching for.

0 Likes
Message 4 of 18

CodeDing
Advisor
Advisor

@Anonymous ,

 

The MEASURE command actually already has this function built into it. After selecting your object to measure, you can use a custom Block.. Here's how it could be implemented in LISP if you didn't want to go through the full command:

(command "_.MEASURE" pause "b" "MyBlockName" "y" pause)
;1st pause - select object
;2nd pause - enter distance between blocks (can be typed or picked w/ points)

If you do not need to place blocks along the entire length of the object, you can create a secondary object OVER the existing, or BREAK the existing one. Here's a simple command to break a line at a single location (select line, then break point):

(command "_.BREAK" pause "f" pause (getvar 'LASTPOINT))

Does this help?

 

Best,

~DD

0 Likes
Message 5 of 18

Anonymous
Not applicable

I appreciate the effort but unfortunately that doesn't really help me. I written some code to use the measure command but the limitation there for me is that you cant specify the start and end of the line you'd be inserting the blocks on it simply goes from start to end. The idea of creating a second entity and then just using the command on that isn't a bad idea but I want it to be automated so I would pick two points on the original and it would copy what's between the two points and then creates a new line from it. Let me know if that doesn't really makes sense.

0 Likes
Message 6 of 18

hencoop
Advisor
Advisor

Automate the duplication of the polyline except start the duplicate with your start point and end it with your end point.

You can step through the Vertices and find the pair that has your start/end point on it.  Discard those that precede your start and that follow your end.

For a line it just becomes a new line along the same vector but having your start and end points for the (ASSOC 10 ...) and ASSOC 11 ...) respectively.

Do the Measure on this new object, (ENTLAST) can select it.

Then delete the duplicate object after the Measure is complete..

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 7 of 18

Anonymous
Not applicable

Would you be able to help with the coding on that? I can usually dissect code and a make it suit my needs but not the best writing it from scratch.

0 Likes
Message 8 of 18

CodeDing
Advisor
Advisor

@hencoop ,

 

Your simplification of this process does not appear to account for arcs/bulges. That is where the complexity factor would come in.

 

Best,

~DD

0 Likes
Message 9 of 18

CodeDing
Advisor
Advisor

@Anonymous ,

 

To get my foot in the door on this, I would need a function that returns a POINT at XX distance along an object (given a start point along said object)... And I currently have no such function laying around. It's still a bit above my skill level.

 

Best,

~DD

0 Likes
Message 10 of 18

hencoop
Advisor
Advisor

You are correct that they are complex but I have addressed them in routines I have written for my own use.

Instead of just capturing the polyline points it is necessary to capture the bulge factors for each of them as well for use in creating the new polyline.  If the start vertex or the vertex preceding the end point has a bulge factor other than 0.0 a new bulge factor must be calculated for the new start or end point; otherwise, using the exsting bulge factor for each vertex will duplicate the curves as well.

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 11 of 18

hencoop
Advisor
Advisor

@Anonymous ,

This should at least get you started.  Curved polylines can be done with this so long as the segments for your start and end are not curved.  Making it do the start and.or end curves requires a bit more which I've discussed in my comments in the lisp file.

 

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 12 of 18

hencoop
Advisor
Advisor

In the attached lisp file on line # 46 I incorrectly state:

;;; It will find the perpindicular intersection from your start/end point to the chord of any curved vertices involved.

I had thought to make that so but I did not do that.

 

The correct statement is as follows:

;;; If the distance from your start/end point to both the arc ends of the curved vertices involved is less than the chord length then your new point will be used but with the existing bulge.

 

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 13 of 18

dlanorh
Advisor
Advisor

Give this a try. It uses the curve functions which are usable on all types of lines curves arcs polylines splines etc.

 

It's rough and ready but works. Blocks are automatically rotated to follow the line.

 

Once the incremented distance is > the distance at the end point it stops

 

It currently swaps start and end points on arc entities if the start point if further than the end point as arcs are always counter clockwise.

 

(defun c:mym ( / c_doc c_spc ent blk spt ept s_pt e_pt i_dist pt p r o)

  (setq c_doc (vla-get-activedocument (vlax-get-acad-object))
        c_spc (vlax-get-property c_doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
        ent (car (entsel "\nSelect Line\Polyline\Spline : "))
        blk (cdr (assoc 2 (entget (car (entsel "\nSelect Block : ")))))
        spt (getpoint "\Select Start Point : ")
        ept (getpoint "\Select End Point : ")
        s_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent spt))
        e_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent ept))
        i_dist (getdist "\nEnter Spacing for Blocks : ")
  )
  (if (> s_pt e_pt) (setq tmp s_pt s_pt e_pt e_pt tmp))
  (while (< s_pt e_pt)
    (setq pt (vlax-curve-getpointatdist ent s_pt)
          p (vlax-curve-getparamatpoint ent pt)
          r (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv ent p))
          o (vla-insertblock c_spc (vlax-3d-point pt) blk 1 1 1 r)
          s_pt (+ s_pt i_dist)
    )
  )
)

I am not one of the robots you're looking for

Message 14 of 18

ВeekeeCZ
Consultant
Consultant

@dlanorh wrote:

...It currently swaps start and end points on arc entities if the start point if further than the end point as arcs are always counter clockwise.

 

This is version that makes sense me.. I was going to write that at some point.. but glad you did.

Anyway, IMHO quoted idea makes the result unpredictable. I think the block insertion should always begin at the picked startpoint and if the endpoint is closer to beginning of the curve it should simply subtract the step distance.

0 Likes
Message 15 of 18

dlanorh
Advisor
Advisor
Accepted solution

Perhaps this

 

;;My Measure
(defun c:mym ( / c_doc c_spc ent blk spt ept s_pt e_pt i_dist t_f i_f pt p r o)

  (setq c_doc (vla-get-activedocument (vlax-get-acad-object))
        c_spc (vlax-get-property c_doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
        ent (car (entsel "\nSelect Line\Polyline\Spline : "))
        blk (cdr (assoc 2 (entget (car (entsel "\nSelect Block : ")))))
        spt (getpoint "\Select Start Point : ")
        ept (getpoint "\Select End Point : ")
        s_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent spt))
        e_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent ept))
        i_dist (getdist "\nEnter Spacing for Blocks : ")
  )
  (if (> s_pt e_pt) (setq t_f '> i_f '-) (setq t_f '< i_f '+))
  (while ((eval t_f) s_pt e_pt)
    (setq pt (vlax-curve-getpointatdist ent s_pt)
          p (vlax-curve-getparamatpoint ent pt)
          r (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv ent p))
          o (vla-insertblock c_spc (vlax-3d-point pt) blk 1 1 1 r)
          s_pt ((eval i_f) s_pt i_dist)
    )
  )
)

I am not one of the robots you're looking for

0 Likes
Message 16 of 18

dlanorh
Advisor
Advisor

Fleshed out

 

;;My Measure
(vl-load-com)
(defun c:mym ( / *error* sv_lst sv_vals c_doc c_spc ent what flg blk spt ept s_pt e_pt i_dist t_f i_f pt p r o)

  (defun *error* ( msg )
    (mapcar 'setvar sv_lst sv_vals)
    (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
    (if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nOops an Error : " msg " occurred")))
    (princ)
  );end_defun_*error*

  (setq sv_lst (list 'cmdecho 'osmode 'dynmode 'dynprompt)
        sv_vals (mapcar 'getvar sv_lst)
        c_doc (vla-get-activedocument (vlax-get-acad-object))
        ent (car (entsel "\nSelect Line\Polyline\Spline : "))
        c_spc (vlax-get-property c_doc (if (= 1 (cdr (assoc 67 (entget ent)))) 'paperspace 'modelspace))
  );end_setq

  (mapcar 'setvar sv_lst (list 0 0 3 1))

  (initget "Blocks Points")
  (setq what (cond ( (getkword "\nInsert Blocks or Points [Blocks/Points] <Points> : ")) ("Points")))

  (cond ( (= what "Points") (setq flg nil) (if (= (getvar 'pdmode) 0) (setvar 'pdmode 3)))
        (t (setq flg t blk (cdr (assoc 2 (entget (car (entsel "\nSelect Block : ")))))))
  );end_cond

  (setq spt (getpoint "\Select Start Point : ")
        ept (getpoint "\Select End Point : ")
        s_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent spt))
        e_pt (vlax-curve-getdistatpoint ent (vlax-curve-getclosestpointto ent ept))
        i_dist (getdist (strcat "\nEnter Spacing for " what " : "))
  );end_setq

  (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
  (vla-startundomark c_doc)

  (if (> s_pt e_pt) (setq t_f '> i_f '-) (setq t_f '< i_f '+))

  (while ((eval t_f) s_pt e_pt)
    (setq pt (vlax-curve-getpointatdist ent s_pt))
    (cond (flg
              (setq p (vlax-curve-getparamatpoint ent pt)
                    r (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv ent p))
                    o (vla-insertblock c_spc (vlax-3d-point pt) blk 1 1 1 r)
              );end_setq
          )
          (
            (setq o (vla-addpoint c_spc (vlax-3d-point pt)))
          )
    );end_cond
    (setq s_pt ((eval i_f) s_pt i_dist))
  );end_while

  (if (and c_doc (= 8 (logand 8 (getvar 'UNDOCTL)))) (vla-endundomark c_doc))
  (mapcar 'setvar sv_lst sv_vals)
  (princ)
);end_defun

I am not one of the robots you're looking for

0 Likes
Message 17 of 18

john.uhden
Mentor
Mentor

What I would do, though I am not writing it for you, is to use (nentsel) to get the two points on the object.  The point of (nentsel) is that it returns both the pick point and the entity name, the latter being most important to be sure you have selected the same entity for the second point as the first.  With each, I recommend that you use (vlax-curve-getclosest pointto) to make sure the pick points are exactly on the curve object.

Then check that the entity is actually a curve object and use (vlax-curve-getdistatpoint) to determine the curvilinear positions of the two points and subtract one from the other (paying attention to which is greater than the other).  Then add/subtract the measure distance from each distance to determine the points to use via (vlax-curve-getpointatdist).

John F. Uhden

0 Likes
Message 18 of 18

Anonymous
Not applicable

@CodeDing  @john.uhden @dlanorh @ВeekeeCZ @hencoop 

Thank you all for you time and effort this has helped me a great deal!

0 Likes