fuccaro
17th May 2003, 10:17 am
Some time ago I begun to write a Lisp for extruding a closed polyline on a helix path. As you probably noticed the AutoCAD EXTRUDE command will rotate the shape during the extrusion. My simple routine is ready from about 1 month but it has limited functionality. Trying to improve it I got a huge source file. Also the number of bugs is increasing and sometime the programs behavior is unexpected. I decided to make public the limited form of the program and I will walk in a direction or other depending of your feed-backs. Please consider the following sentences as the "user manual" for the routine.
-Restrictions regarding the SHAPE to extrude
The shape to extrude must be a closed polyline formed by line segments only (no arcs).
The program can extrude only convex shapes. For other shapes please use your modeling skills and add, substract etc. the solids based on convex shapes.
All corners must be distinct. If you draw for example a rectangle you may use it. Also you may use a triangle. But if you will edit the grips of the rectangle and move on of the corners over an other one, even if your rectangle looks like the triangle - you can not use it.
You can not use polylines with three or more collinear consecutive points. This case may appear if you draw a half of the profile and the other half is obtained by mirroring. If an extreme edge is perpendicular to the mirror line you will obtain a polyline with three collinear points.
If the polyline contains a lot of points you will slow-down the program.
-Restrictions regarding the NUMBER OF SEGMENTS.
The curved faces of the solid are approximated by plain segments. Using too few segments will result a discontinued solid. More segments means smoothed aspect. But also means dramatically increase of the model complexity. If the polyline to extrude is complex you should use no more than about 50 segments. Experiment with the best complexity of the model - it depends on your machine.
-Other things to keep in mind
I wrote no error handling routine.
Call the routine when you are in the same UCS as the shape was create.
The shape you draw is the frontal section of the final solid. The mechanical engineers know the difference between the normal and the frontal section of a gear profile.
If the axe is inside the polyline to extrude you will got a twisted solid.
Set the shading mode to wire frame to speed up the process - you will need that.
High speed machines and large memories are welcome.
Do not write to me if this routine will drive you crazy.
; SPIRAL EXTRUSION ;
; mfuccaro@hotmail.com ;
;;;;;;;;- 17.05.2003 -;;;;;
(defun c:spirex( / m3 m4 plist pts nwpt nwpts rad ang dist
i mm pln ax ang1 s ss h1 pt)
(defun m3(a b c / p1 p2 p3 m1 m2 m3)
(setq p1 (* (car a) (cadr b) (caddr c))
p2 (* (car b) (cadr c) (caddr a))
p3 (* (car c) (cadr a) (caddr b))
m1 (* (car c) (cadr b) (caddr a))
m2 (* (car a) (cadr c) (caddr b))
m3 (* (car b) (cadr a) (caddr c)))
(- (+ p1 p2 p3) (+ m1 m2 m3)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun m4(x a b c / arg1 arg2 arg3)
(setq arg1 (list (cadr a) (caddr a) 1)
arg2 (list (cadr b) (caddr b) 1)
arg3 (list (cadr c) (caddr c) 1)
p (* (car x) (m3 arg1 arg2 arg3))
arg1 (list (car a) (caddr a) 1)
arg2 (list (car b) (caddr b) 1)
arg3 (list (car c) (caddr c) 1)
p (- p (* (cadr x) (m3 arg1 arg2 arg3)))
arg1 (list (car a) (cadr a) 1)
arg2 (list (car b) (cadr b) 1)
arg3 (list (car c) (cadr c) 1)
p (+ p (* (caddr x) (m3 arg1 arg2 arg3)))
p (- p (m3 a b c))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq pln (car (entsel "\n Select shape to extrude"))
ax (getpoint " Point on the axis?")
ang1 (/ (* pi (getreal "\nRotation angle (degrees) ")) 180.0)
h1 (getdist " Height ")
s (max 5 (getint " Segments "))
ang1 (/ ang1 s)
h1 (/ h1 s)
ss (ssadd))
(setq plist (entget pln)
pts nil nwpts nil i 0 rad 0)
(repeat (length plist)
(if (= (car (nth i plist)) 10)
(setq pt (cdr (nth i plist))
pts (cons (list (car pt) (cadr pt) 0) pts)
dist (distance pt ax)
rad (max rad dist)
ang (+ ang1 (atan (- (cadr pt) (cadr ax)) (- (car pt) (car ax))))
nwpt (polar ax ang dist)
rad (max rad (distance ax nwpt))
nwpts (cons (list (car nwpt) (cadr nwpt) h1) nwpts)))
(setq i (1+ i)))
(setq rad (* 1.5 rad) old (getvar "osmode"))
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(command "._undo" "begin")
(command "._sphere" (list (car ax) (cadr ax) 0) rad)
(command "._zoom" "w" (list (+ (car ax) rad) (+ (cadr ax) rad))
(list (- (car ax) rad) (- (cadr ax) rad)))
(command "._plan" "")
(command "._slice" "l" "" (car pts) (cadr pts) (caddr pts) (car nwpts))
(command "._slice" "l" "" (car nwpts) (cadr nwpts) (caddr nwpts) (car pts))
(setq mm (1- (length pts)) i 0)
(repeat (1+ mm)
(setq j (1+ i))
(if (> j mm) (setq j 0))
(setq k (1- i))
(if (< k 0) (setq k mm))
(if (minusp (* (m4 (nth j nwpts) (nth i pts) (nth j pts) (nth i nwpts))
(m4 (nth k pts) (nth i pts) (nth j pts) (nth i nwpts))))
(progn
(command "._slice" "l" "" (nth i pts) (nth j pts) (nth j nwpts) (nth k pts))
(command "._slice" "l" "" (nth i nwpts) (nth j nwpts) (nth i pts) (nth k pts)))
(progn
(command "._slice" "l" "" (nth i pts) (nth j pts) (nth i nwpts) (nth k pts))
(command "._slice" "l" "" (nth i nwpts) (nth j nwpts) (nth j pts) (nth k pts))))
(setq i (1+ i)))
(setq ss (ssadd (entlast) ss))
(repeat (1- s)
(command "._copy" "l" "" (list 0 0 0) (list 0 0 h1))
(command "._rotate" "l" "" ax (/ (* ang1 180.0) PI))
(setq ss (ssadd (entlast) ss)))
(command "._union" ss "")
(setvar "osmode" old)
(command "._undo" "end")
(setvar "cmdecho" 1)
(princ)
)
(princ "\nSPIRAL EXTRUSION program loaded")
(princ "\ttype SPIREX at the command prompt")
(princ)
-Restrictions regarding the SHAPE to extrude
The shape to extrude must be a closed polyline formed by line segments only (no arcs).
The program can extrude only convex shapes. For other shapes please use your modeling skills and add, substract etc. the solids based on convex shapes.
All corners must be distinct. If you draw for example a rectangle you may use it. Also you may use a triangle. But if you will edit the grips of the rectangle and move on of the corners over an other one, even if your rectangle looks like the triangle - you can not use it.
You can not use polylines with three or more collinear consecutive points. This case may appear if you draw a half of the profile and the other half is obtained by mirroring. If an extreme edge is perpendicular to the mirror line you will obtain a polyline with three collinear points.
If the polyline contains a lot of points you will slow-down the program.
-Restrictions regarding the NUMBER OF SEGMENTS.
The curved faces of the solid are approximated by plain segments. Using too few segments will result a discontinued solid. More segments means smoothed aspect. But also means dramatically increase of the model complexity. If the polyline to extrude is complex you should use no more than about 50 segments. Experiment with the best complexity of the model - it depends on your machine.
-Other things to keep in mind
I wrote no error handling routine.
Call the routine when you are in the same UCS as the shape was create.
The shape you draw is the frontal section of the final solid. The mechanical engineers know the difference between the normal and the frontal section of a gear profile.
If the axe is inside the polyline to extrude you will got a twisted solid.
Set the shading mode to wire frame to speed up the process - you will need that.
High speed machines and large memories are welcome.
Do not write to me if this routine will drive you crazy.
; SPIRAL EXTRUSION ;
; mfuccaro@hotmail.com ;
;;;;;;;;- 17.05.2003 -;;;;;
(defun c:spirex( / m3 m4 plist pts nwpt nwpts rad ang dist
i mm pln ax ang1 s ss h1 pt)
(defun m3(a b c / p1 p2 p3 m1 m2 m3)
(setq p1 (* (car a) (cadr b) (caddr c))
p2 (* (car b) (cadr c) (caddr a))
p3 (* (car c) (cadr a) (caddr b))
m1 (* (car c) (cadr b) (caddr a))
m2 (* (car a) (cadr c) (caddr b))
m3 (* (car b) (cadr a) (caddr c)))
(- (+ p1 p2 p3) (+ m1 m2 m3)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun m4(x a b c / arg1 arg2 arg3)
(setq arg1 (list (cadr a) (caddr a) 1)
arg2 (list (cadr b) (caddr b) 1)
arg3 (list (cadr c) (caddr c) 1)
p (* (car x) (m3 arg1 arg2 arg3))
arg1 (list (car a) (caddr a) 1)
arg2 (list (car b) (caddr b) 1)
arg3 (list (car c) (caddr c) 1)
p (- p (* (cadr x) (m3 arg1 arg2 arg3)))
arg1 (list (car a) (cadr a) 1)
arg2 (list (car b) (cadr b) 1)
arg3 (list (car c) (cadr c) 1)
p (+ p (* (caddr x) (m3 arg1 arg2 arg3)))
p (- p (m3 a b c))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq pln (car (entsel "\n Select shape to extrude"))
ax (getpoint " Point on the axis?")
ang1 (/ (* pi (getreal "\nRotation angle (degrees) ")) 180.0)
h1 (getdist " Height ")
s (max 5 (getint " Segments "))
ang1 (/ ang1 s)
h1 (/ h1 s)
ss (ssadd))
(setq plist (entget pln)
pts nil nwpts nil i 0 rad 0)
(repeat (length plist)
(if (= (car (nth i plist)) 10)
(setq pt (cdr (nth i plist))
pts (cons (list (car pt) (cadr pt) 0) pts)
dist (distance pt ax)
rad (max rad dist)
ang (+ ang1 (atan (- (cadr pt) (cadr ax)) (- (car pt) (car ax))))
nwpt (polar ax ang dist)
rad (max rad (distance ax nwpt))
nwpts (cons (list (car nwpt) (cadr nwpt) h1) nwpts)))
(setq i (1+ i)))
(setq rad (* 1.5 rad) old (getvar "osmode"))
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(command "._undo" "begin")
(command "._sphere" (list (car ax) (cadr ax) 0) rad)
(command "._zoom" "w" (list (+ (car ax) rad) (+ (cadr ax) rad))
(list (- (car ax) rad) (- (cadr ax) rad)))
(command "._plan" "")
(command "._slice" "l" "" (car pts) (cadr pts) (caddr pts) (car nwpts))
(command "._slice" "l" "" (car nwpts) (cadr nwpts) (caddr nwpts) (car pts))
(setq mm (1- (length pts)) i 0)
(repeat (1+ mm)
(setq j (1+ i))
(if (> j mm) (setq j 0))
(setq k (1- i))
(if (< k 0) (setq k mm))
(if (minusp (* (m4 (nth j nwpts) (nth i pts) (nth j pts) (nth i nwpts))
(m4 (nth k pts) (nth i pts) (nth j pts) (nth i nwpts))))
(progn
(command "._slice" "l" "" (nth i pts) (nth j pts) (nth j nwpts) (nth k pts))
(command "._slice" "l" "" (nth i nwpts) (nth j nwpts) (nth i pts) (nth k pts)))
(progn
(command "._slice" "l" "" (nth i pts) (nth j pts) (nth i nwpts) (nth k pts))
(command "._slice" "l" "" (nth i nwpts) (nth j nwpts) (nth j pts) (nth k pts))))
(setq i (1+ i)))
(setq ss (ssadd (entlast) ss))
(repeat (1- s)
(command "._copy" "l" "" (list 0 0 0) (list 0 0 h1))
(command "._rotate" "l" "" ax (/ (* ang1 180.0) PI))
(setq ss (ssadd (entlast) ss)))
(command "._union" ss "")
(setvar "osmode" old)
(command "._undo" "end")
(setvar "cmdecho" 1)
(princ)
)
(princ "\nSPIRAL EXTRUSION program loaded")
(princ "\ttype SPIREX at the command prompt")
(princ)