TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Mark on October 13, 2004, 02:40:49 PM

Title: (challenge) newbie Create a line function .......
Post by: Mark on October 13, 2004, 02:40:49 PM
This is a challenge for all the newbies out there. Write a function that draws a line based two arguments, point1 and point2. Use the entmake function to create the line.

Bonus:
Write another line function but use ActiveX methods to create the line.
Title: (challenge) newbie Create a line function .......
Post by: daron on October 13, 2004, 04:47:19 PM
Most newbie's don't understand how this: (defun newline (point1 point2)...) works. Maybe a way to prime into this would be to write a command using getpoint, then try to develop it into reusable code. Maybe if we get enough (any) participation, someone can help them begin to understand reusability. I personally hope some newbie's will take this challenge.

Come on newbie's.. What are you waiting for: Us to do it?
Title: (challenge) newbie Create a line function .......
Post by: JohnK on October 13, 2004, 05:35:41 PM
...Im working on it, im working on it! *Sheesh!*
Title: (challenge) newbie Create a line function .......
Post by: danny on October 13, 2004, 07:37:05 PM
Code: [Select]
(entmake '((0 . "line")
;start point
(10 0.0 0.0 0.0)

ok im lost..
Title: (challenge) newbie Create a line function .......
Post by: TR on October 14, 2004, 01:10:55 AM
I'm lost already.
Title: (challenge) newbie Create a line function .......
Post by: SMadsen on October 14, 2004, 05:30:42 AM
Quote from: danny
Code: [Select]
(entmake '((0 . "line")
;start point
(10 0.0 0.0 0.0)

ok im lost..

Nah, that's an excellent start, Danny. Try finishing the ENTMAKE function first by reading up on it in the help files. You've already supplied the entity type and the start point. For ENTMAKE to create a line it only requires one more piece of information ...
Title: (challenge) newbie Create a line function .......
Post by: JohnK on October 14, 2004, 08:32:51 AM
w00t! your half way there! Keep going.

Is there anything in specific your having a hard time with?
Title: (challenge) newbie Create a line function .......
Post by: MP on October 14, 2004, 08:43:20 AM
I agree with Mr. Madsen, that's an excellent start Danny, you're just missing a few bits.

What might help is if you observe the data for an entity that already exists.

Make a line the normal way, that is by typing the line command at the AutoCAD command line. When prompted for the endpoints perhaps key in the coordinates instead of picking them with the mouse (entering coordinates easy to remember).

Then load and run this code little program, selecting the line you just made when prompted.

Code: [Select]
(defun c:ListData ( / myprinc ename )
    (defun myprinc (tabs x)
        (repeat tabs (princ "    "))
        (princ x)
        (princ "\n")
    )
    (cond
        (   (setq ename (car (entsel)))
            (myprinc 0 (strcat "\n" (chr 40)))
            (foreach x (entget ename)
                (myprinc 1 x)
            )
            (myprinc 0 (chr 41))
        )
    )
    (princ)
)

You should see something like this:

Code: [Select]
(
    (-1 . <Entity name: 7ef54e88>)
    (0 . LINE)
    (330 . <Entity name: 7ef54cf8>)
    (5 . 89)
    (100 . AcDbEntity)
    (67 . 0)
    (410 . Model)
    (8 . 0)
    (100 . AcDbLine)
    (10 10.0 10.0 0.0)
    (11 20.0 20.0 0.0)
    (210 0.0 0.0 1.0)
)

What do you notice? Do you see the endpoints you specified?

Some of the data you'll see is not requred to entmake a line, but would be a result of an entmake request; group codes like the -1, 330 and 5 (which you will come to know in time so don't sweat them for now).

Other group codes are the result of default values, that is, you can specifiy their values but if you don't default values are assumeed; group codes like 67, 410, 8 and 210.

So ... what is left? :)

Hope this helps a little.

Cheers, Michael.
Title: (challenge) newbie Create a line function .......
Post by: daron on October 14, 2004, 08:47:53 AM
Question for the newbie's???
Where can you find much of the dxf (Drawing intereXchange Format) information that you might be able to decipher what (8 . "0") means?
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 09:02:26 AM
Ok I'll give this a try....
Code: [Select]

(defun c:acitvexline ()
  (vl-load-com)
  (setq acadObject   (vlax-get-acad-object))
  (setq mSpace       (vla-get-ModelSpace acadDocument))
  (setq startPt (getpoint "Pick the Start Point"))
  (setq endpt (getpoint "Pick the End Point"))
  (vla-addline mSpace (vlax-3d-point startPt) (vlax-3d-point endPt))
 )



--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 09:06:25 AM
Oops forgot a line...

(defun c:acitvexline ()
  (vl-load-com)
  (setq acadObject   (vlax-get-acad-object))
  (setq acadDocument (vla-get-ActiveDocument acadObject))
  (setq mSpace       (vla-get-ModelSpace acadDocument))
  (setq startPt (getpoint "Pick the start point"))
  (setq endpt (getpoint "Pick the End Point"))
  (vla-addline mSpace (vlax-3d-point startPt) (vlax-3d-point endPt))
 )

--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 09:11:13 AM
Quote from: Daron
Question for the newbie's???
Where can you find much of the dxf (Drawing intereXchange Format) information that you might be able to decipher what (8 . "0") means?


Developer Help File?  The Swamp?




--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: Mark on October 14, 2004, 10:16:08 AM
Quote from: ImaJayhawk
Ok I'll give this a try....
--ImaJayhawk


That's it, just make it a subroutine that requires two arguments, point1 point2.
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 10:50:17 AM
Quote from: Mark Thomas

That's it, just make it a subroutine that requires two arguments, point1 point2.


How about:
Code: [Select]

(defun acitvexline ( startpt endpt / )
  (vl-load-com)
  (setq acadObject   (vlax-get-acad-object))
  (setq acadDocument (vla-get-ActiveDocument acadObject))
  (setq mSpace       (vla-get-ModelSpace acadDocument))
  (vla-addline mSpace (vlax-3d-point startPt) (vlax-3d-point endPt))
 )


Code: [Select]

(setq pt1 '(0 0 0))
(setq pt2 '(1 0 0))
(acitvexline pt1 pt2)





--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: Mark on October 14, 2004, 11:02:13 AM
Excellent!

How about something like this.

remember to localize your var's
Code: [Select]

(defun acitvexline ( startpt endpt / acadObject acadDocument mSpace)
  (vl-load-com)
  (setq acadObject   (vlax-get-acad-object))
  (setq acadDocument (vla-get-ActiveDocument acadObject))
  (setq mSpace       (vla-get-ModelSpace acadDocument))
  (vla-addline mSpace (vlax-3d-point startPt) (vlax-3d-point endPt))
 )

(defun a-main (/ pt1 pt2 ax_line)

  (while (setq pt1 (getpoint "\nStart Point: "))
(if (setq pt2 (getpoint pt1 "\nEnd Point: "))
 (progn
(setq ax_line (acitvexline pt1 pt2))
(vlax-release-object ax_line)
)
 )
)

  (princ)

  )
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 12:33:54 PM
Are there any other ways using activex?  :obsessed:



--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: JohnK on October 14, 2004, 12:36:42 PM
Quote from: ImaJayhawk
Are there any other ways using activex?  :obsessed:...


yep.  See this: "getpoint" Try to find the ActiveX equilivant for that.

Then we can move on from there.
Title: (challenge) newbie Create a line function .......
Post by: ImaJayhawk on October 14, 2004, 05:19:11 PM
Ok took a little research.....

Code: [Select]

(defun activexline ( startpt endpt / acadObject acadDocument mSpace)
  (vl-load-com)
  (setq acadObject   (vlax-get-acad-object))
  (setq acadDocument (vla-get-ActiveDocument acadObject))
  (setq mSpace (vla-get-ModelSpace acadDocument))
  (setq util (vla-get-utility acadDocument))
  (vla-addline mSpace startpt endPt)
 )

(defun a-main (/ pt1 pt2 ax_line)
   (while  (setq pt1 (vla-getpoint util nil "\nSpecify First Point : "))
   (if (setq pt2 (vla-getpoint util pt1 "\nSpecify Second Point : "))
     (progn
      (setq ax_line (activexline pt1 pt2))
      (vlax-release-object ax_line)
      )
     )
   )

  (princ)

  )



Not sure I understand the syntax for vla-getpoint or what
(setq util (vla-get-utility acadDocument)) does.  
 :?:


--ImaJayhawk
Title: (challenge) newbie Create a line function .......
Post by: csgoh on October 15, 2004, 05:29:03 AM
Code: [Select]

  (setq acadObject   (vlax-get-acad-object))
  (setq acadDocument (vla-get-ActiveDocument acadObject))
  (setq mSpace (vla-get-ModelSpace acadDocument))
  (setq util (vla-get-utility acadDocument))

What are these 4 lines for???
Looking at the codes, these 4 variables are nout used at all. Or do we have do define it everytime we use ActiveX???
Title: (challenge) newbie Create a line function .......
Post by: SMadsen on October 15, 2004, 07:26:23 AM
All variables are used in the code. Objects are ordered in a hierarchial manner, which means that in order to access a particular object you often need to query several objects.

At the first line, the parent of all objects within AutoCAD is accessed; it's the application itself. The next line queries the application object in order to retrieve the active document. This object is always present as a child of the application but is assigned on the fly to point to the active document. It corresponds to the ThisDrawing object in VBA.

As the purpose of the routine is to draw a line, it needs to access a drawing area where a line can be drawn. A document object holds a number of child objects in itself, one of which is the modelspace drawing area. Of course, it's not literally an "area" but simply a collection of graphical objects such as lines and circles etc. So before a line can be added, the routine needs to query the active document to get hold of the modelspace object.

Except for the very first function that retrieves the application, notice that the queried object is always given as the first argument to a VLA function.

The 4th object is one that gives access to user interface functions. They are (typically) ActiveX equivalents to those we know as GETxxx functions in AutoLISP. Notice the first argument in VLA-GET-UTILITY. It means that the Utility object is a child of the application.

The whole thing could schematically look like this:
Code: [Select]

AutoCAD application  -->  Utilities object (to get points etc.)
        |                       |
        v                  vla-getPoint pt1
  Active document          vla-getPoint pt2
        |                       |
        v                       v
   Modelspace        -->   vla-addLine Modelspace pt1 pt2
                                |
                                v
                           Line object
Title: (challenge) newbie Create a line function .......
Post by: Mark on October 15, 2004, 11:08:05 AM
Nice explanation Mr. Madsen.

Major code overkill, but maybe it will help.
Code: [Select]

(defun c:aline (/ get-utilobj get-mspace vl-get-point acitvexline pt1 pt2 ax_line)
  (vl-load-com)

  ;;; this program will draw a line between the two user selected points
  ;;; it uses all activeX methods including the point selection.

  ;----------------------------------------------------------------------
  ; *internal function*
  ;
  ; returns the utility object (VLA-OBJECT IAcadUtility)
  ; for the active document
  ;----------------------------------------------------------------------
  (defun get-utilobj ()
    (vla-get-utility
      (vla-get-activedocument
        (vlax-get-acad-object)
        )
      )
    )

  ;----------------------------------------------------------------------
  ; *internal function*
  ;
  ; returns the modelspace object (VLA-OBJECT IAcadModelSpace2)
  ; for the active document
  ;----------------------------------------------------------------------
  (defun get-mspace ()
    (vla-get-modelspace
      (vla-get-activedocument
        (vlax-get-acad-object)
        )
      )
    )

  ;----------------------------------------------------------------------
  ; *internal function*
  ;
  ; a getpoint function that uses the Utility object of the active document
  ;
  ; returns a variant (three-element array of doubles) #<variant 8197 ..>
  ; of the user selected point or NIL.
  ;
  ; (vl-get-point variant_array_of_dbls,[nil] "message for user prompt")
  ;----------------------------------------------------------------------
  (defun vl-get-point (pt msg / pt_variant)

    (setq pt_variant
          (vl-catch-all-apply
            'vlax-invoke-method
            (list
              (get-utilobj)
              'GetPoint
              pt
              (vlax-make-variant msg)
              )
            )
          ); setq

    (if (vl-catch-all-error-p pt_variant)
      nil pt_variant
      ); if
    )

  ;----------------------------------------------------------------------
  ; *internal function*
  ;
  ; creates and returns a line object (VLA-OBJECT IAcadLine)
  ;
  ; (acitvexline variant_array_of_dbls variant_array_of_dbls)
  ;----------------------------------------------------------------------
  (defun acitvexline (startpt endpt)
    (vla-addline (get-mspace) startPt endPt)
    )

  ;; ========== body of main function (aline) starts here ===========

  ;; loop while we're getting valid input.
  (while (setq pt1 (vl-get-point nil "\nStart Point: "))

         (if (setq pt2 (vl-get-point pt1 "\nEnd Point: "))
           (progn
             (setq ax_line (acitvexline pt1 pt2))
             (vlax-release-object ax_line)
             )
           )

         ); while

  (princ)

  )
Title: Re: (challenge) newbie Create a line function .......
Post by: Oak3s on July 26, 2006, 06:13:51 PM
very old challenge but i was busy trying to figure it out anyway. so here is what i have. striped down, no error handling stab at it.
Code: [Select]
(defun c:YL (/)
(setq pt1 (getpoint "Starting point : ")
          pt2 (getpoint "Ending point : "))
(entmake (list '(0 . "line") '(62 . 2) (cons 10 pt1) (cons 11 pt2)))
)

the quote ' was what was messing me up. i still dont really get why its working with the ' before the dxf code and not my variables...but it works. any suggestions or comments welcome.
Title: Re: (challenge) newbie Create a line function .......
Post by: T.Willey on July 26, 2006, 06:18:10 PM
very old challenge but i was busy trying to figure it out anyway. so here is what i have. striped down, no error handling stab at it.
Code: [Select]
(defun c:YL (/)
(setq pt1 (getpoint "Starting point : ")
          pt2 (getpoint "Ending point : "))
(entmake (list '(0 . "line") '(62 . 2) (cons 10 pt1) (cons 11 pt2)))
)

the quote ' was what was messing me up. i still dont really get why its working with the ' before the dxf code and not my variables...but it works. any suggestions or comments welcome.
The quote means take things literial, so
'(0 . "line") = (0 . "line")
'(cons 10 pt1) = (cons 10 pt1)

And since you have variables in the dxf code, you have to use (list... instead of '(...... with your entmake.  This is because you have to evaluate the variables [pt1 pt2].

Hope that makes it clearer.
Title: Re: (challenge) newbie Create a line function .......
Post by: Bob Wahr on July 26, 2006, 06:20:51 PM
Nice 3Oaks ;)
Title: Re: (challenge) newbie Create a line function .......
Post by: Joe Burke on July 27, 2006, 06:45:01 AM
One more thing which is on my mind since I forgot to do it in some
code I posted yesterday.

If the points are derived from getpoint, trans those to WCS for correct
operation in a UCS. Both entmake and vla-Add methods require WCS points.

(setq p1 (trans (getpoint "\nFirst point: ") 1 0))