Jump to content

Using entmakex in UCS


CALCAD

Recommended Posts

While replacing some command calls in my lisps with entmakes (thanks to Lee Mac), I ran into a case where I needed to draw a variety of things in an arbitrary UCS. I managed to get points working with a modified entmake like this :

 

(defun Point (pt / exv) ; draw point in the current UCS 
 (setq pt (trans pt 1 0)) 
 (setq exv (trans (list 0 0 1) 1 0 T)) 
 (entmakex (list (cons 0 "POINT") 
                 (cons 10 pt) 
                 (cons 210 exv))) 
)

 

Something similar works for lines. But I can't figure out how to do it with arcs or circles. Has anybody done this before? I'd appreciate some hints. Thanks.

Link to comment
Share on other sites

You will need to convert angles to allow for the UCS X-Axis rotation:

 


(setq xAng (angle '(0. 0. 0.) (trans (getvar 'UCSXDIR) 0 (trans '(0. 0. 1.) 1 0 t) t)))

;; Convert WCS Angle (ang) to UCS:

(setq ang (+ ang xAng))

;; Convert UCS Angle (ang) to WCS:

(setq ang (- ang xAng))

Link to comment
Share on other sites

Here's what I have so far.

 

; Functions to draw primitive entities by entmakex in any UCS.
; Modifications to original code by Lee Mac on Cadtutor forum.

; Draw point in the current UCS

(defun Point (pt / exv)  
 (setq pt (trans pt 1 0))
 (setq exv (trans (list 0 0 1) 1 0 T))
 (entmakex (list (cons 0 "POINT")
                 (cons 10 pt)
                 (cons 210 exv)))
)

; Draw line in the current UCS

(defun Line (pt1 pt2 / exv)   
 (setq pt1 (trans pt1 1 0)
       pt2 (trans pt2 1 0))
 (setq exv (trans (list 0 0 1) 1 0 T))
 (entmakex (list (cons 0 "LINE")
                 (cons 10 pt1)
                 (cons 11 pt2)
                 (cons 210 exv)))
)

; Draw circle in current UCS

(defun Circle (cen rad / exv)
 (setq exv (trans (list 0 0 1) 1 0 T)) 
 (setq cen (trans cen 1 exv))
 (entmakex (list (cons 0 "CIRCLE")
                 (cons 10 cen)
                 (cons 40 rad)
                 (cons 210 exv)))
)

; Draw arc in current UCS

(defun Arc (cen rad sAng eAng / exv xAng)  
 (setq xAng (angle '(0. 0. 0.) (trans (getvar "UCSXDIR") 0 (trans '(0. 0. 1.) 1 0 T) T)))
 (setq sAng (+ sAng xAng))
 (setq eAng (+ eAng xAng))
 (setq exv (trans (list 0 0 1) 1 0 T))
 (setq cen (trans cen 1 exv))
 (entmakex (list (cons 0 "ARC")
                 (cons 10  cen)
                 (cons 40  rad)
                 (cons 50 sAng)
                 (cons 51 eAng)
                 (cons 210 exv)))
)

Link to comment
Share on other sites

Hi,

 

(trans '(0. 0. 1.) 1 0 T) returns the extrusion direction vector (Z axis) of the current UCS.

This vector can be use to 'entmake' some 2d entities which requires coordinates to be specified in the entity OCS coordinates (as ARC, CIRCLE, LWPOLYLINE, TEXT, MTEXT, INSERT, ...).

This isn't needed for '3d' entities as POINT, LINE, and so on which require WCS coordinates.

Look at the DXF Reference topic in the developer's help.

Link to comment
Share on other sites

Hi gile, thanks for your comment. I just tried removing the 210 references in the point and line code and you're right. Without the 210 values, the point and line are drawn in the correct position. However, in the point case, the display of the cross, if that's the chosen style, will be in the WCS plane, rather than the UCS. This is just a matter of preference, but I think I prefer to see the orientation of the point reflect the UCS. There may be a performance hit by leaving the 210 value in, if you're generating a large number of points. I haven't tested that. In the line case, I wonder if having lines in the same plane with different extrusion vectors would have any implications with further processing, combinations with other entities, etc. I just don't know. Something to investigate.

Link to comment
Share on other sites

Hi Lee. Yes, a line doesn't define a plane, but I was thinking of drawing lines in the same plane in an arbitrary UCS at, say, Z=0. If we use the line command, those lines will have some mix of values for the extrusion vector, not (210 0 0 1), unless UCS=WCS. If we then use the entmakex (without defining the 210 value) we will have a line in the same plane, but with a different extrusion vector. Having thought about this a bit, I know this is not an unusual situation in my own models. I draw 3D wireframes more than anything else, and I jump around various UCS's and back to WCS a lot. I don't expect to run into trouble with mixed extrusion vectors with coplanar entities, but I just never thought about it before. It might be interesting to see what would happen if you tried to extrude a figure composed of mixed vectors.

 

Edit : Ignore that last sentence. At least in my Intellicad, it seems that an extruded figure must be a polyline.

Edited by CALCAD
Link to comment
Share on other sites

Another question. Here is the working code for the line entmake :

(with the simplification suggested by gile)

 

(defun line (pt1 pt2)  ; draw line in the current UCS 
 (setq pt1 (trans pt1 1 0) 
       pt2 (trans pt2 1 0)) 
 (entmakex (list (cons 0 "LINE") 
                 (cons 10 pt1) 
                 (cons 11 pt2))) 
) 

Then, here is the non-working code for xline, modeled after line:

 

(defun xLine (pt vec)  ; draw xline in current UCS - not working   
 (setq pt (trans pt 1 0))
 (setq vec (trans vec 1 0))
 (entmakex (list (cons 0 "XLINE") 
                 (cons 100 "AcDbEntity") 
                 (cons 100 "AcDbXline") 
                 (cons 10 pt) 
                 (cons 11 vec)))
)

So, the question is what is different between line and xline? Both simply require two points. OK, technically a point and a vector for xline. But if I carefully feed it a unit vector, it still doesn't work. I'm stumped. Thanks in advance for clues.

Link to comment
Share on other sites

Another question. Here is the working code for the line entmake :

(with the simplification suggested by gile)

 

(defun line (pt1 pt2) ; draw line in the current UCS 
(setq pt1 (trans pt1 1 0) 
pt2 (trans pt2 1 0)) 
(entmakex (list (cons 0 "LINE") 
(cons 10 pt1) 
(cons 11 pt2))) 
) 

Then, here is the non-working code for xline, modeled after line:

 

(defun xLine (pt vec) ; draw xline in current UCS - not working 
(setq pt (trans pt 1 0))
(setq vec (trans vec 1 0))
(entmakex (list (cons 0 "XLINE") 
(cons 100 "AcDbEntity") 
(cons 100 "AcDbXline") 
(cons 10 pt) 
(cons 11 vec)))
)

So, the question is what is different between line and xline? Both simply require two points. OK, technically a point and a vector for xline. But if I carefully feed it a unit vector, it still doesn't work. I'm stumped. Thanks in advance for clues.

 

I am not sure if this is of any help, But I randomly drew a line and an xline and returned the dxf values of each.

Line

(-1 . <Entity name: 7ef59ea0>)
(0 . "LINE")
(330 . <Entity name: 7ef59cf8>)
(5 . "8C")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "0")
(100 . "AcDbLine")
(10 -8.5108 12.4081 0.0)
(11 29.8602 12.4081 0.0)
(210 0.0 0.0 1.0)

 

XLINE

(-1 . <Entity name: 7ef59e90>)
(0 . "XLINE")
(330 . <Entity name: 7ef59cf8>)
(5 . "8A")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "0")
(100 . "AcDbXline")
(10 0.419659 4.18673 0.0)
(11 1.0 0.0 0.0)

 

Take note that the dxf code 210 is the extrusion factor in line, But this does not exist in xline.

Edited by The Buzzard
Link to comment
Share on other sites

Try this code written by MP

 
(setq pt      (getpoint "\nThrough: ")
     ang (getorient pt "\nTo: ")
) 
(entmakex (list '(0 . "XLINE")
               '(100 . "AcDbEntity")
               '(100 . "AcDbXline")
               (cons 10 pt)
               (cons 11 (polar '(0 0) ang 1))
         ) 
) 

 

~'J'~

Link to comment
Share on other sites

Here is the updated function list. Thanks to The Buzzard for noting that the extrusion vector is not part of the xline definition. That helped to narrow down the possibilities. If I find the time, will try to work on polyline and ellipse entmakes.

 

; Calcad's updated functions to draw entities by entmakex in any UCS - 8-08-10
; Modifications to original code by Lee Mac on Cadtutor forum.
; Thanks to all contributors on the Cadtutor forum.

; Draw point in the current UCS

(defun Point (pt / exv)  
 (setq pt (trans pt 1 0))
 (setq exv (trans (list 0 0 1) 1 0 T))
 (entmakex (list (cons 0 "POINT")
                 (cons 10 pt)
                 (cons 210 exv)))
)

; Note : the following simple version draws in the correct location,
;        but the point display orientation will not then align with the UCS.
(defun Point (pt)  
 (setq pt (trans pt 1 0))
 (entmakex (list (cons 0 "POINT")
                 (cons 10 pt)))
)


; Draw line in the current UCS

(defun line (pt1 pt2)
 (setq pt1 (trans pt1 1 0) 
       pt2 (trans pt2 1 0)) 
 (entmakex (list (cons 0 "LINE") 
                 (cons 10 pt1) 
                 (cons 11 pt2))) 
)

; Draw circle in current UCS

(defun Circle (cen rad / exv)
 (setq exv (trans (list 0 0 1) 1 0 T)) 
 (setq cen (trans cen 1 exv))
 (entmakex (list (cons 0 "CIRCLE")
                 (cons 10 cen)
                 (cons 40 rad)
                 (cons 210 exv)))
)

; Draw arc in current UCS

(defun Arc (cen rad sAng eAng / exv xAng)  
 (setq xAng (angle '(0. 0. 0.) (trans (getvar "UCSXDIR") 0 (trans '(0. 0. 1.) 1 0 T) T)))
 (setq sAng (+ sAng xAng))
 (setq eAng (+ eAng xAng))
 (setq exv (trans (list 0 0 1) 1 0 T))
 (setq cen (trans cen 1 exv))
 (entmakex (list (cons 0 "ARC")
                 (cons 10  cen)
                 (cons 40  rad)
                 (cons 50 sAng)
                 (cons 51 eAng)
                 (cons 210 exv)))
)

; Draw xline in current UCS

; If you know a point and angle as in :
; (setq pt      (getpoint "\nThrough: ")
;       ang (getorient pt "\nTo: ")
; )

;(Thanks to fixo and to MP for the original code)

(defun xline (pt ang)
(setq pt (trans pt 1 0)) 
(entmakex (list (cons 0 . "XLINE")
               (cons 100 . "AcDbEntity")
               (cons 100 . "AcDbXline")
               (cons 10 pt)
               (cons 11 (trans (polar '(0 0) ang 1) 1 0 T))))   
)

; Or, for two points :

(defun xLine (pt vec) 
 (setq pt (trans pt 1 0))
 (setq vec (trans vec 1 0 T))
 (entmakex (list (cons 0 "XLINE") 
                 (cons 100 "AcDbEntity") 
                 (cons 100 "AcDbXline") 
                 (cons 10 pt) 
                 (cons 11 vec)))
)

; Draw lwpolyline in current UCS

(defun LWPoly (lst cls / exv)  ; version for pre-visual lisp. DXF group 70 cls is flag
                                to indicate closure : 0 = open, 1 = closed 
 (setq exv (trans (list 0 0 1) 1 0 T)) 
 (entmakex (append (list (cons 0 "LWPOLYLINE") 
                         (cons 38 (caddr (trans (car lst) 1 exv))) 
                         (cons 100 "AcDbEntity") 
                         (cons 100 "AcDbPolyline") 
                         (cons 90 (length lst)) 
                         (cons 70 cls) 
                         (cons 210 exv)) 
                   (mapcar '(lambda (p) (cons 10 (trans p 1 exv))) lst))) 
) 

Link to comment
Share on other sites

Here is the updated function list. Thanks to The Buzzard for noting that the extrusion vector is not part of the xline definition. That helped to narrow down the possibilities. If I find the time, will try to work on polyline and ellipse entmakes.

 

; Calcad's updated functions to draw entities by entmakex in any UCS - 8-08-10
; Modifications to original code by Lee Mac on Cadtutor forum.
; Thanks to all contributors on the Cadtutor forum.

; Draw point in the current UCS

(defun Point (pt / exv) 
(setq pt (trans pt 1 0))
(setq exv (trans (list 0 0 1) 1 0 T))
(entmakex (list (cons 0 "POINT")
(cons 10 pt)
(cons 210 exv)))
)

; Note : the following simple version draws in the correct location,
; but the point display orientation will not then align with the UCS.
(defun Point (pt) 
(setq pt (trans pt 1 0))
(entmakex (list (cons 0 "POINT")
(cons 10 pt)))
)


; Draw line in the current UCS

(defun line (pt1 pt2)
(setq pt1 (trans pt1 1 0) 
pt2 (trans pt2 1 0)) 
(entmakex (list (cons 0 "LINE") 
(cons 10 pt1) 
(cons 11 pt2))) 
)

; Draw circle in current UCS

(defun Circle (cen rad / exv)
(setq exv (trans (list 0 0 1) 1 0 T)) 
(setq cen (trans cen 1 exv))
(entmakex (list (cons 0 "CIRCLE")
(cons 10 cen)
(cons 40 rad)
(cons 210 exv)))
)

; Draw arc in current UCS

(defun Arc (cen rad sAng eAng / exv xAng) 
(setq xAng (angle '(0. 0. 0.) (trans (getvar "UCSXDIR") 0 (trans '(0. 0. 1.) 1 0 T) T)))
(setq sAng (+ sAng xAng))
(setq eAng (+ eAng xAng))
(setq exv (trans (list 0 0 1) 1 0 T))
(setq cen (trans cen 1 exv))
(entmakex (list (cons 0 "ARC")
(cons 10 cen)
(cons 40 rad)
(cons 50 sAng)
(cons 51 eAng)
(cons 210 exv)))
)

; Draw xline in current UCS

; If you know a point and angle as in :
; (setq pt (getpoint "\nThrough: ")
; ang (getorient pt "\nTo: ")
; )

;(Thanks to fixo and to MP for the original code)

(defun xline (pt ang)
(setq pt (trans pt 1 0)) 
(entmakex (list (cons 0 . "XLINE")
(cons 100 . "AcDbEntity")
(cons 100 . "AcDbXline")
(cons 10 pt)
(cons 11 (trans (polar '(0 0) ang 1) 1 0 T)))) 
)

; Or, for two points :

(defun xLine (pt vec) 
(setq pt (trans pt 1 0))
(setq vec (trans vec 1 0 T))
(entmakex (list (cons 0 "XLINE") 
(cons 100 "AcDbEntity") 
(cons 100 "AcDbXline") 
(cons 10 pt) 
(cons 11 vec)))
)

; Draw lwpolyline in current UCS

(defun LWPoly (lst cls / exv) ; version for pre-visual lisp. DXF group 70 cls is flag
to indicate closure : 0 = open, 1 = closed 
(setq exv (trans (list 0 0 1) 1 0 T)) 
(entmakex (append (list (cons 0 "LWPOLYLINE") 
(cons 38 (caddr (trans (car lst) 1 exv))) 
(cons 100 "AcDbEntity") 
(cons 100 "AcDbPolyline") 
(cons 90 (length lst)) 
(cons 70 cls) 
(cons 210 exv)) 
(mapcar '(lambda (p) (cons 10 (trans p 1 exv))) lst))) 
) 

 

You welcome CALCAD, But I did not give you much there.

 

Here is a very good thread for entmake functions by Lee Mac. You will find functions for different entities you mentioned on post 1: http://www.cadtutor.net/forum/showthread.php?44768-Entmake-Functions&p=302880&viewfull=1#post302880

Link to comment
Share on other sites

In the line case, I wonder if having lines in the same plane with different extrusion vectors would have any implications with further processing, combinations with other entities, etc. I just don't know. Something to investigate.

 

 

 

 

One rather obscure issue which could potentially arise due to a line’s (or point's) uncoordinated Extrusion Vector: The UCS-Object command can give unexpected result. See these threads.

 

http://www.cadtutor.net/forum/showthread.php?14400

http://www.cadtutor.net/forum/showthread.php?49964

 

We had a recurring problem with a 3d to 2d workflow that had many of our 2d Drawing spontaneously creeping out of plane. The cause was the use of UCS-Object with lines that had extrusion direction not aligned to the World Z axis.

Link to comment
Share on other sites

Thanks SEANT,

I've not run into problems with lines and mixed extrusion vectors, but that doesn't mean I never will! As you point out in your links, trying to establish a UCS with a line only can yield strange results. Makes me wonder why it's allowed. Maybe it's necessary for some procedures. Anyway, for the slightly paranoid (like me), I recommend keeping the original longer form of the line entmake in the list of functions. I include it here for convenience :

 

; use this to maintain UCS extrusion vector
(defun line (pt1 pt2 / exv) 
 (setq pt1 (trans pt1 1 0) 
       pt2 (trans pt2 1 0)) 
 (setq exv (trans (list 0 0 1) 1 0 T)) 
 (entmakex (list (cons 0 "LINE") 
                 (cons 10 pt1) 
                 (cons 11 pt2) 
                 (cons 210 exv))) 
)

 

And thanks Buzzard for providing the link to Lee's entmake discussion. It was worth re-reading. Lee's entmakes are the foundation and inspiration for my recent efforts. I hope others find it useful.

Link to comment
Share on other sites

I believe the issue only crops up within a distinct 3d to 2d workflow. By this I mean a setup where 3d geometry is created by one drafter, then portions are re-aligned to the WCS for further processing by a 2d drafter. It would not likely manifest itself in a strict 2d CAD environment – nor, probably, an office where everyone is well versed in 3d.

Link to comment
Share on other sites

Here's another to add to the list.

 

; Draw polyline in current UCS

(defun Polyline (lst / exv)
 (setq exv (trans (list 0 0 1) 1 0 T))
 (entmakex (list (cons 0 "POLYLINE")
                 (cons 10 (trans (list 0 0 0) 1 exv))
                 (cons 210 exv)))
 (mapcar '(lambda (p)
               (entmake (list (cons 0 "VERTEX") 
                              (cons 10 (trans p 1 exv))))) lst)
 (entmakex (list (cons 0 "SEQEND")))
)

Link to comment
Share on other sites

Here is the last function that I wanted for the function list.

There are other entmakes in Lee's list that could (probably) be adapted, but I have no need for them.

If someone else needs one, just ask and I'll see what I can do.

 

; Draw ellipse in current UCS

; Note that the parameter 'majv' is a point relative to 'cen' in the current UCS

(defun ellipse (cen majv ratio / exv)
 (setq exv (trans (list 0 0 1) 1 0 T))
 (setq cen (trans cen 1 0))
 (setq majv (trans majv 1 0 T))
 (entmakex (list (cons 0 "ELLIPSE")
                 (cons 100 "AcDbEntity")
                 (cons 100 "AcDbEllipse")
                 (cons 10 cen)
                 (cons 11 majv)
                 (cons 40 ratio)
                 (cons 41 0)    
                 (cons 42 (* 2 pi))
                 (cons 210 exv)))
)

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