;;; ROUGHEN.LSP version 2k.0, 31-May-1999 ;;; ;;; ROUGHEN.LSP: AutoLISP program to "roughen" a polyline. ;;; Application prefix for global symbols = Daed_ ;;; ;;;----------------------------------------------------------------------- ;;; copyright 1993-1999 by Mark Middlebrook ;;; Daedalus Consulting ;;; e-mail: markmiddlebrook@compuserve.com ;;; ;;; You are free to distribute ROUGHEN.LSP to others so long as you do not ;;; charge for it. ;;; ;;;----------------------------------------------------------------------- ;;;*Why Use ROUGHEN? ;;; Use ROUGHEN when you want to turn a polyline or line into an ;;; irregularly zigzaggy line. For example, you can use roughened lines ;;; to designate existing concrete surfaces that have been roughened ;;; for better adhesion with new concrete. ;;; ;;;----------------------------------------------------------------------- ;;;*How to Use ROUGHEN ;;; ;;; This version of ROUGHEN works with AutoCAD R12 through 2007. ;;; It roughens the newer AutoCAD R14 lwpolyline objects ("lightweight ;;; polylines"), as well as older "heavyweight" polyline objects. ;;; ;;; To run ROUGHEN, load it using AutoCAD's APPLOAD command, or type: ;;; (load "ROUGHEN") ;;; at the AutoCAD command prompt. After you've loaded ROUGHEN.LSP, type: ;;; ROUGHEN ;;; to run it. ROUGHEN will prompt you to select a line or polyline. ;;; After you select a line or polyline, ROUGHEN inserts a series of ;;; vertices in order to create an irregular, zigzaggy polyline. ;;; ;;; If you don't like the results, just type U to undo ROUGHEN's work. ;;; ;;; Tips: ;;; 1) You can use AutoCAD's Last selection option to select the ;;; last-drawn object for roughening (assuming that it's a ;;; line or polyline). ;;; 2) To change the roughness period (i.e., approximate length of the ;;; zigzag lines) and roughness amplitude (i.e., height of the zigzag ;;; lines, use the Options choice that's included in ROUGHEN's prompt. ;;; ;;;----------------------------------------------------------------------- ;;;*Known limitations ;;; 1) The entire line or polyline must be visible in order for ROUGHEN ;;; to work properly. ;;; 2) ROUGHEN turns arc segments into straight segments. ;;; ;;;======================================================================= ;;; PRIMARILY FOR ROUGH CONCRETE EDGES - STRUCTURALLY SPEAKING, OF COURSE. (defun ROUGHEN (/ olderr dwgscale basicziglen roughness ocmd oosmode en etype en1 expr lstverts vertnum vtx1 vtx2 seglen segang inclen zignum ziglen zigdist wanderdist wanderang newvtx ) ;;error handler (setq olderr *error*) (defun *error* (msg) (if (or (= msg "Function cancelled") (= msg "quit / exit abort") ) ;;if user cancelled or program aborted, exit quietly (princ) ;;otherwise report error message (princ (strcat "\nError: " msg)) ) (setvar "CMDECHO" ocmd) (setvar "OSMODE" oosmode) (setq *error* olderr) ;restore old error handler (setq olderr nil) (princ) ) ;; (daed_mgetreal prompt-string initgetbits default-real) ;; User input function for getting a real number ;; initgetbits = sum of 0 for none ;; 2 for disallow zero ;; 4 for disallow negative ;; (don't use the 1 bit; it's figured out automatically). ;; default-real = real number or nil. ;; returns real number. (defun daed_mgetreal (promptstr initbits defreal / answer) (setq promptstr (strcat promptstr (if defreal (strcat " <" (rtos defreal 2) ">: ") ": " ) ) ) (if defreal (initget initbits) (initget (1+ initbits)) ) (setq answer (getreal promptstr)) (if (null answer) (setq answer defreal) ) answer ) ;; (getinput) ;; Gets input from user: entity, Last, or Options (defun getinput (/ en) (prompt (strcat "\nDrawing scale = " (rtos daed_dwgscale 2 4) " Roughness period = " (rtos daed_basicziglen 2 4) " Roughness amplitude = " (rtos daed_roughness 2 4) ) ) (initget "Last Options") (setq en (entsel "\nSelect a polyline or line or [Options]: ")) ) ;;Set default length and roughness of "zigzags" here (if (null daed_dwgscale) (setq daed_dwgscale (if (zerop (getvar "DIMSCALE")) 1 (getvar "DIMSCALE") ) daed_basicziglen 0.05 ;larger is longer segment daed_roughness 0.015 ;larger is rougher amplitude ) ) (setq ocmd (getvar "CMDECHO")) (setvar "CMDECHO" 0) (setq oosmode (getvar "OSMODE")) (setvar "OSMODE" 0) ;;Allow user to change the roughening parameters (while (= (setq en (getinput)) "Options") (setq daed_dwgscale (daed_mgetreal "\nDrawing scale factor" 6 daed_dwgscale) daed_basicziglen (daed_mgetreal "\nRoughness period (larger numbers give fewer zigzags)" 6 daed_basicziglen ) daed_roughness (daed_mgetreal "\nRoughness amplitude (larger numbers give higher spikes)" 6 daed_roughness ) ) ) ;;User selected an entity, so proceed (if en (progn ;;Multiply roughening factors by drawing scale factor (setq basicziglen (* daed_basicziglen daed_dwgscale) roughness (* daed_roughness daed_dwgscale) ) (if (= en "Last") (setq en (entlast)) ;Last entity (setq en (car en)) ;selected entity ) (setq etype (cdr (assoc 0 (entget en))) lstverts nil ) (cond ;;Entity is a line, so convert it to a polyline ((equal etype "LINE") (command "._PEDIT" en "_Yes" "_eXit") (setq en (entlast) ;reset en etype (cdr (assoc 0 (entget en))) ) ) ) (cond ;;Entity is an lwpolyline ((equal etype "LWPOLYLINE") ;;Build list of vertices (mapcar '(lambda (expr) (if (= (car expr) 10) (setq lstverts (cons (cdr expr) lstverts)) ) ) (entget en) ) (setq lstverts (reverse lstverts)) ) ;;Entity is a polyline ((equal etype "POLYLINE") ;;Build list of vertices (setq en1 (entnext en)) ;first vertex (while (/= "SEQEND" (cdr (assoc 0 (entget en1)))) (setq lstverts (cons (cdr (assoc 10 (entget en1))) lstverts) en1 (entnext en1) ;next vertex ) ) (setq lstverts (reverse lstverts)) ) (T (prompt "\nObject is not a polyline or line.")) ) ;;There are vertices, so process the lwpolyline or polyline (if lstverts (progn (command "._PEDIT" en "_Edit") ;edit vertex (setq vertnum 1) (while (< vertnum (length lstverts)) (setq vtx1 (nth (1- vertnum) lstverts) vtx2 (nth vertnum lstverts) seglen (distance vtx1 vtx2) segang (angle vtx1 vtx2) zignum (fix (/ seglen basicziglen)) ;# of "zigzags"... zignum (max zignum 2) ; but not less than 2 ziglen (/ seglen zignum) ;zigzag length zigdist ziglen i 2 ) (repeat (1- zignum) (setq newvtx (polar vtx1 segang zigdist) ;vertex init. loc. newvtx (trans newvtx 0 1) wanderdist (* roughness (daed_randnum)) wanderang (if (= (rem i 2) 1) ;wander back & forth (+ segang (/ pi 4)) (- segang (/ pi 4)) ) ) (command "_Insert" newvtx ) ;;PEDIT behaves inconsistently with polylines vs. lwpolylines (if (equal etype "POLYLINE") (command "_Next") ) (command "_Move" (polar newvtx wanderang wanderdist) ) (setq zigdist (+ ziglen zigdist) i (1+ i) ) ) (command "_Next") (setq vertnum (1+ vertnum)) ) (command "_eXit" "_eXit") ;exit PEDIT (redraw en) ) ) ) (prompt "\nNo object selected.") ) (setvar "CMDECHO" ocmd) (setvar "OSMODE" oosmode) (setq *error* olderr) (princ) ) ;;;Random number generation function - based on the linear ;;; congruential method as presented in Doug Cooper's book ;;; Condensed Pascal, pp. 116-117. ;;; Returns a random number between 0 and 1. (defun daed_randnum (/ modulus multiplier increment random) (if (not daed_seed) (setq daed_seed (getvar "DATE")) ) (setq modulus 65536 multiplier 25173 increment 13849 daed_seed (rem (+ (* multiplier daed_seed) increment) modulus) random (/ daed_seed modulus) ) ) (princ)