October 2014

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  










« Selecting the edge of a nested solid in ObjectARX | Main | Calling AutoCAD commands from .NET »

August 28, 2006

Calling DIMARC from Visual LISP

This is an interesting little problem that came in from Japan last week. Basically the issue is understanding how to call the DIMARC command programmatically from LISP using (command).

The DIMARC command was introduced in AutoCAD 2006 to dimension the length of arcs or polyline arc segments. What's interesting about this problem is that it highlights different aspects of entity selection in LISP.

Firstly, let's take a look at the DIMARC command (I've put the keyboard-entered text in red below):

Command: DIMARC

Select arc or polyline arc segment:

Specify arc length dimension location, or [Mtext/Text/Angle/Partial/Leader]:

Dimension text = 10.6887

The first prompt is for the arc or polyline arc segment, the second is for the dimension location (we're not going to worry about using other options).

The classic way to select an entity is to use (entsel):

Command: (entsel)

Select object: (<Entity name: 7ef8e050> (22.1694 32.2269 0.0))

This returns a list containing both the entity-name and the point picked when selecting the entity. This is going to be particularly useful in this problem, as the DIMARC command needs to know where the point was picked: this is because it has to support picking of a "complex" entity, as it works not only on arcs but on arc segments of polylines. If you use the classic technique of using (car)stripping off the point, to just pass in the entity name, it fails:

Command: DIMARC

Select arc or polyline arc segment: (car (entsel))

Select object: <Entity name: 7ef8e050>

Command:

Whereas just passing the results of (entsel) works fine:

Command: DIMARC

Select arc or polyline arc segment: (entsel)

Select object: (<Entity name: 7ef8e050> (22.2696 32.2269 0.0))

Specify arc length dimension location, or [Mtext/Text/Angle/Partial/Leader]:

Dimension text = 24.3844

So it's clear we need to keep the point in there. So we know what we have to do to select arc entities - we can pass in the results of (entsel).

Polyline entities are trickier. You can pass in the entity name, with or without the point, and the command won't work:

Command: DIMARC

Select arc or polyline arc segment: (entsel)

Select object: (<Entity name: 7ef8e058> (51.0773 29.5726 0.0))

Object selected is not an arc or polyline arc segment.

Select arc or polyline arc segment:

But we can pass in the point picked by (entsel), and let the DIMARC command do the work of determining whether the segment picked was actually an arc or not:

Command: DIMARC

Select arc or polyline arc segment: (cadr (entsel))

Select object: (52.6305 29.5726 0.0)

Specify arc length dimension location, or [Mtext/Text/Angle/Partial/Leader]:

Dimension text = 9.4106

So now we're ready to put it all together.

[ Note: The below example does not take into consideration the user cancelling from (getpoint) or (entsel) - that is left as an exercise for the reader. ]

(defun c:myDimArc(/ en pt ed)

  (setq en (entsel "\nSelect arc or polyline arc segment: ")

        pt (getpoint "\nSpecify arc length dimension location: ")

        ed (entget (car en))

  )

  ; If the object selected is a 2D polyline (old or new)

  ; then pass the point instead of the entity name

  (if (member (cdr (assoc 0 ed)) '("POLYLINE" "LWPOLYLINE"))

    (setq en (cadr en))

  )

  (command "_.DIMARC" en pt)

  (princ)

)

This is just an example of how you need to call the DIMARC command programmatically - with this technique you clearly lose the visual feedback from the dragging of the entity during selection (what we call the "jig" in ObjectARX). And this is ultimately an unrealistic example - you're more likely to need to call DIMARC automatically for a set of entities in a drawing than just define a simple command to request user input and pass it through.

One thing this example does demonstrate is that different commands have different needs in terms of entity selection information (some just need a selection set or an entity name, some need more that than).

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200d834ac185253ef

Listed below are links to weblogs that reference Calling DIMARC from Visual LISP:

blog comments powered by Disqus

Feed/Share

10 Random Posts