Transcript
Page 1: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Introduction

ThistutorialisdesignedtodemonstrateseveralpowerfulcapabilitiesoftheAutoLISP®programmingenvironmentforAutoCAD®andintroducefeaturesoftheAutoLISPlanguagethatmaybenewtoyou.

Thepurposeofthetutorialistodrawagardenpathusinganautomateddrawingtoolthatminimizesdraftingtimeandshowsthepowerofparametricprogramming.Youwilllearntocreateadrawingroutinethatautomatesthegenerationofacomplexshape—thekindofdraftingoperationyoudonotwanttohavetodomanuallyoverandoveragain.

Topicsinthissection

WorkinginVisualLISPTutorialOverview

Pleasesendusyourcommentaboutthispage

Page 2: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Introduction>

WorkinginVisualLISP

ThistutorialassumesyouhavesomefamiliaritywithLISPorAutoLISP.ItalsoassumesyouunderstandbasicWindows®filemanagementtaskssuchascreatingdirectories,copyingfiles,andnavigatingthroughthefilesystemonyourharddiskornetwork.IfyouneedaprimeronusingAutoCAD,pleaseexploretheUser’sGuideformoreinformation.

Inthistutorial

TheVisualLISP®(VLISP)environmentisintroduced.Thisenvironmentprovidesyouwithediting,debugging,andothertoolsspecifictothecreationofAutoLISPapplications.

ActiveX®andReactorfunctionsofAutoLISParedemonstrated,aswellasseveralotherextensionstotheAutoLISPlanguageprovidedwithVLISP.

Therearethefollowingtwopossibleexecutioncontextsforthistutorial:

TheapplicationmayberunasinterpretedLISPinpiecemealfilesand/orfunctionsthatareloadedintoasingledocument,or

TheprogramcodecanbecompiledintoaVLXapplication,denotedbya*.vlxexecutable.AVLXoperatesfromaself-containednamespacethatcaninteractwiththeapplication-loadingdocument.

Pleasesendusyourcommentaboutthispage

Page 3: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Introduction>

TutorialOverview

YourgoalinthistutorialistodevelopanewcommandforAutoCADthatdrawsagardenpathandfillsitwithcirculartiles.Thetutorialisdividedintosevenlessons.Asyouprogressfromlessontolesson,youreceiveprogressivelylessdetailedinstructionsonhowtoperformindividualtasks.HelpisavailableintheVLISPdocumentationifyouhaveanyquestions.

Lessons4and5areatanintermediatelevelandgobeyondbasicAutoLISPconcepts.Lessons6and7containadvancedandfairlycomplexprogrammingtasksandaredesignedforexperiencedAutoLISPdevelopers.

IfyouchosethefullinstallationoptionwhenyouinstalledAutoCAD,thesourcecodefilesareinthefollowingdirectory:

<AutoCADdirectory>\Tutorial\VisualLISP\

ItisrecommendedyoudonotmodifythesamplesourcecodefilessuppliedwithAutoCAD.Ifsomethingisnotworkingcorrectlywithinyourprogram,youmaywanttocopythesuppliedsourcecodeintoyourworkingdirectory.Throughoutthetutorial,theworkingdirectoryisreferredtoas:

<AutoCADdirectory>\Tutorial\VisualLISP\MyPath

Ifyouchooseadifferentpathforyourworkingdirectory,substituteyourdirectorynameattheappropriatetimes.

Pleasesendusyourcommentaboutthispage

Page 4: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram

Inthisfirstlesson,you'llbeginbydefiningwhattheapplicationwilldo.UsingtheVisualLISP®(VLISP)developmentenvironment,you'llcreateaLISPfileandbeginwritingAutoLISP®codetosupportyourapplication.Intheprocess,you'llbegintodiscoverhowVLISPfacilitatesapplicationdevelopment.

Topicsinthissection

DefiningOverallProgramGoalsGettingStartedwithVisualLISPLookingatVisualLISPCodeFormattingAnalyzingtheCodeFillingtheGapsintheProgramLettingVisualLISPCheckYourCodeRunningtheProgramwithVisualLISPWrappingUpLesson1

Pleasesendusyourcommentaboutthispage

Page 5: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

DefiningOverallProgramGoals

DevelopinganAutoLISPprogrambeginswithanideaforautomatingsomeaspectofAutoCAD®.Itmaybeaneedtospeeduparepetitivedraftingfunction,ortosimplifyacomplexseriesofoperations.Forthetutorial,thegardenpathyouwantyourprogramtodrawisacomplexshapewithavariablenumberofcomponents,basedoninitialinputfromtheuser.Here'swhatitwilllooklike:

Yourprogrammustdothefollowingtodrawthegardenpath:

Givenastartpoint,anendpoint,andawidth,drawarectilinearboundary.Theboundarycanbeatany2Dorientation.Thereshouldbenolimitonhowlargeorsmallitcanbe.

Prompttheuserfortilesizeandtilespacingvalues.Thetilesaresimplecirclesandwillfilltheboundarybutmustnotoverlaporcrosstheboundary.

Placethetilesinalternatingrows.

Page 6: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Toseehowthingsshouldwork,youcanrunacompletedversionoftheapplicationthatissuppliedwithAutoCAD.

Torunthesuppliedexample

1. FromtheAutoCADToolsmenu,chooseLoadApplication.

2. Selectgardenpath.vlxfromtheTutorial\VisualLISPdirectory,andchooseLoad.

3. ChooseClose.

4. AttheCommandprompt,entergpath.

5. RespondtothefirsttwopromptsbypickingastartpointandanendpointintheAutoCADdrawingarea.

6. Enter2atthehalf-widthofPathprompt.

7. ChooseOKwhenpromptedbytheGardenPathTileSpecificationsdialogbox.

Pleasesendusyourcommentaboutthispage

Page 7: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

GettingStartedwithVisualLISP

Nowthatyou'veseenhowtheapplicationissupposedtowork,youcanbegindevelopingitwithVLISP.Butfirst,ithelpstodemonstratewhatcanhappenwhenVLISPiswaitingforcontroltoreturnfromAutoCAD.Youmayhavealreadyencounteredthis.

ToseeVisualLISPwaitforcontroltoreturnfromAutoCAD

1. FromtheAutoCADToolsmenu,chooseLoadApplication.

2. Selectgardenpath.vlxfromtheTutorial\VisualLISPdirectory,andchooseLoad.

3. ChooseClose.

4. AttheAutoCADCommandprompt,entervlisptostartVisualLISP.

5. SwitchbacktotheAutoCADwindow(eitherselectAutoCADfromthetaskbarorpressALT+TABandchooseAutoCAD),andentergpathattheAutoCADCommandprompt.

6. Beforerespondingtothepromptsfromgpath,switchbacktotheVLISPwindow.IntheVLISPwindow,themousepointerappearsasaVLISPsymbol,andyoucannotchooseanycommandsorentertextanywhereintheVLISPwindow.ThepointersymbolisareminderthatthereisanactivityyoumustcompleteinAutoCADbeforeresumingworkwithVLISP.RememberthiswheneveryouseetheVLISPpointer.

7. ReturntotheAutoCADwindowandrespondtoallthepromptsfromgpath.

Nowyouarereadytobeginbuildingthegardenpathapplication.

Page 8: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

TobeginapplicationdevelopmentwithVisualLISP

1. FromtheVLISPFilemenu,chooseNewFile.

2. Enterthefollowingcodeinthetexteditorwindow(itisthewindowtitled“<Untitled-0>”);youcanomitthecomments,ifyouwish:

;;;FunctionC:GPathisthemainprogramfunctionanddefinesthe

;;;AutoCADGPATHcommand.

(defunC:GPath()

;;Asktheuserforinput:firstforpathlocationand

;;direction,thenforpathparameters.Continueonlyifyouhave

;;validinput.

(if(gp:getPointInput);

(if(gp:getDialogInput)

(progn

;;Atthispoint,youhavevalidinputfromtheuser.

;;Drawtheoutline,storingtheresultingpolyline

;;"pointer"inthevariablecalledPolylineName.

(setqPolylineName(gp:drawOutline))

(princ"\nThegp:drawOutlinefunctionreturned<")

(princPolylineName)

(princ">")

(Alert"Congratulations-yourprogramiscomplete!")

)

(princ"\nFunctioncancelled.")

)

(princ"\nIncompleteinformationtodrawaboundary.")

)

(princ);exitquietly

)

;;;Displayamessagetolettheuserknowthecommandname.

(princ"\nTypegpathtodrawagardenpath.")

(princ)

3. ChooseFile SaveAsfromthemenu,andsavethecodeinthenewfileas<AutoCADdirectory>\Tutorial\VisualLISP\MyPath\gpmain.lsp.

4. Reviewyourwork.

Pleasesendusyourcommentaboutthispage

Page 9: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

LookingatVisualLISPCodeFormatting

VLISPrecognizesthevarioustypesofcharactersandwordsthatmakeupanAutoLISPprogramfileandhighlightsthecharactersindifferentcolors.Thismakesiteasierforyoutospotsomethingincorrectquickly.Forexample,ifyoumissaclosingquotationmarkfollowingatextstring,everythingyoutypecontinuestodisplayinmagenta,thecolordenotingstrings.Whenyouentertheclosingquotationmark,VLISPcorrectlycolorsthetextfollowingthestring,accordingtothelanguageelementitrepresents.

Asyouentertext,VLISPalsoformatsitbyaddingspacingandindentation.TogetVLISPtoformatcodeyoucopyintoitstexteditorfromanotherfile,chooseTools FormatCodeinEditorfromtheVLISPmenu.

Pleasesendusyourcommentaboutthispage

Page 10: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

AnalyzingtheCode

Thedefunfunctionstatementdefinesthenewfunction.NoticethemainfunctionisnamedC:GPath.TheC:prefixestablishesthatthisfunctioniscallablefromtheAutoCADcommandline.GPathisthenameusersentertolaunchtheapplicationfromtheAutoCADCommandprompt.Thefunctionsthatobtaininputfromusersarenamedgp:getPointInputandgp:getDialogInput.Thefunctionthatdrawsthegardenpathoutlineisgp:drawOutline.Thesenamesareprefixedwithgp:toindicatetheyarespecifictothegardenpathapplication.Thisisnotarequirement,butitisagoodnamingconventiontousetodistinguishapplication-specificfunctionsfromgeneralutilityfunctionsyoufrequentlyuse.

Inthemainfunction,princexpressionsdisplaytheresultsoftheprogramifitrunssuccessfully,orawarningmessageiftheprogramencountersanunexpectedevent.Forexample,aswillbeseeninLesson2,iftheuserpressesENTERinsteadofpickingapointonthescreen,thecalltogp:getPointInputendsprematurely,returninganilvaluetothemainfunction.Thiscausestheprogramtoissueaprincmessageof“Incompleteinformationtodrawaboundary.”

Thecalltoprincneartheendoftheprogramservesasaprompt.Uponapplicationload,thepromptinformsuserswhattheyneedtotypetoinitiatethedrawingofagardenpath.Thefinalprincwithoutastringargumentforcestheprogramtoexitquietly,meaningthevalueofthemainfunction'sfinalexpressionisnotreturned.Ifthefinalsuppressingprincwereomitted,thepromptwoulddisplaytwice.

Pleasesendusyourcommentaboutthispage

Page 11: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

FillingtheGapsintheProgram

Forthecodeinthisnewfiletoworkcorrectly,youmustwritethreemorefunctiondefinitions.Themaingardenpathcodecontainscallstothreecustomfunctions:

gp:getPointInput

gp:getUserInput

gp:drawOutline

Fornow,youwilljustwritestubbed-outfunctiondefinitions.Astubbed-outfunctionservesasaplaceholderforthecompletefunctionthatistofollow.Itallowsyoutotryoutpiecesofyourcodebeforeaddingallthedetailneededtocompletetheapplication.

Todefinestubbed-outfunctionsfortheapplication

1. PositionyourcursoratthetopoftheprogramcodeinthetexteditorwindowandpressENTERacoupleoftimestoaddblanklines.

2. Enterthefollowingcode,beginningwhereyouinsertedtheblanklines:

;;;Functiongp:getPointInputwillgetpathlocationandsize

(defungp:getPointInput()

(alert

"Functiongp:getPointInputwillgetuserdrawinginput"

)

;;Fornow,returnT,asifthefunctionworkedcorrectly.

T

)

;;;Functiongp:getDialogInputwillgetpathparameters

(defungp:getDialogInput()

(alert

"Functiongp:getDialogInputwillgetuserchoicesthroughadialog"

)

Page 12: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

;;Fornow,returnT,asifthefunctionworkedcorrectly.

T

)

;;;Functiongp:drawOutlinewilldrawthepathboundary

(defungp:drawOutline()

(alert

(strcat"Thisfunctionwilldrawtheoutlineofthepolyline"

"\nandreturnapolylineentityname/pointer."

)

)

;;Fornow,simplyreturnaquotedsymbol.Eventually,this

;;functionwillreturnanentitynameorpointer.

'SomeEname

)

RightbeforetheendofeachinputfunctionisalineofcodethatcontainsonlyaT.Thisisusedasareturnvaluetothecallingfunction.AllAutoLISPfunctionsreturnavaluetothefunctionthatcalledthem.TheletterTisthesymbolfor“true”inAutoLISP,andaddingitcausesthefunctiontoreturnatruevalue.Thewaygpmain.lspisstructured,eachinputfunctionitcallsmustreturnavalueotherthannil(whichindicates“novalue”)fortheprogramtoproceedtothenextstep.

AnAutoLISPfunctionwill,bydefault,returnthevalueofthelastexpressionevaluatedwithinit.Inthestubbed-outfunctions,theonlyexpressionisacalltothealertfunction.Butalertalwaysreturnsnil.Ifthisisleftasthelastexpressioningp:getPointInput,itwillalwaysreturnnil,andyouwillneverpassthroughtheiftothegp:getDialogInputfunction.

Forasimilarreason,theendofthegp:DrawOutlinefunctionreturnsaquotedsymbol('SomeEname)asaplaceholder.AquotedsymbolisaLISPconstructthatisnotevaluated.(IfyouarecuriousabouthowtheLISPlanguageworks,thereareanumberofgoodbooksavailable,mentionedattheendofthistutorial.)

Pleasesendusyourcommentaboutthispage

Page 13: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

LettingVisualLISPCheckYourCode

VLISPhasapowerfulfeatureforcheckingyourcodeforsyntacticalerrors.Usethistoolbeforetryingtoruntheprogram.Youcancatchcommontypingerrors,suchasmissingparenthesesormissingquotationmarks,andothersyntacticalproblems.

Tocheckthesyntaxofyourcode

1. Makesurethetexteditorwindowcontaininggpmain.lspistheactivewindow.(Clickinthetitlebarofthewindowtoactivateit.)

2. FromtheVLISPmenu,chooseTools CheckTextinEditor.

TheBuildOutputwindowisdisplayedwiththeresultsofthesyntaxcheck.IfVLISPdidnotdetectanyerrors,thewindowcontainstextsimilartothefollowing:

[CHECKINGTEXTGPMAIN.LSPloading...]

......

;Checkdone.

Ifyouhaveproblemsandneedhelp,refertothe“DevelopingProgramswithVisualLISP”sectionoftheAutoLISPDeveloper'sGuide.Seeifyoucandeterminewheretheproblemislocated.Ifyouarespendingtoomuchtimelocatingtheproblem,usethesamplegpmain.lspfileprovidedinthelesson1directorytocontinuewiththetutorial.

Tousethesuppliedgpmain.lspprogram(ifnecessary)

1. Closethetexteditorwindowcontainingthegpmain.lspcodeyouentered.

Page 14: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

2. ChooseFile OpenFilefromtheVLISPmenu,andopenthegpmain.lspfileinthe\Tutorial\VisualLISP\lesson1directory.

3. ChooseFile SaveAsandsavethefileinyour\Tutorial\VisualLISP\MyPathdirectoryasgpmain.lsp,replacingthecopyyoucreated.

Pleasesendusyourcommentaboutthispage

Page 15: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

RunningtheProgramwithVisualLISP

RunningAutoLISPprogramsinVLISPallowsyoutousethemanydebuggingfeaturesofVLISPtoinvestigateproblemsthatmayoccurinyourapplication.

Toloadandruntheprogram

1. Withthetexteditorwindowactive,chooseTools LoadTextinEditorfromtheVLISPmenu.

2. Atthe_$promptintheVLISPConsolewindow,enter(C:GPath).TheConsolewindowexpectscommandstobeenteredinAutoLISPsyntax,soallfunctionnamesmustbeenclosedinparentheses.

3. PressENTERorclickOKinresponsetothemessagewindows.Thefinalmessageshouldread“Congratulations-yourprogramiscomplete!”

Note IfAutoCADisminimizedwhenyourungpath,youwillnotseethepromptsuntilyourestoretheAutoCADwindow(usingeitherthetaskbarorALT+TAB).

Pleasesendusyourcommentaboutthispage

Page 16: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DesigningandBeginningtheProgram>

WrappingUpLesson1

Inthislesson,you

Definedprogramgoals.

Learnedthevalueofstubfunctions.

Learnedaboutnamingfunctionstoidentifythemasspecifictoyourapplicationorasgeneralfunctionstobeusedoverandover.

LearnedhowtouseVLISPtocheckyourcode.

LearnedhowtoloadandrunaprograminVLISP.

Youaredonewiththislesson.Saveyourprogramfileagaintobecertainyouhavethelatestrevisions.

Pleasesendusyourcommentaboutthispage

Page 17: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools

ThislessonteachesyouhowtouseseveralvaluableVisualLISP®debuggingtoolsthatspeedupthedevelopmentofAutoLISP®programs.Youwillalsolearnthedifferencebetweenlocalandglobalvariables,andwhentousethem.Yourprogramwillbecomemoreactive—promptinguserstoentersomeinformation.Theinformationwillbestoredinalistandyou'llbegintounderstandthepowerofusinglistswithinyourAutoLISPprograms.Afterall,LISPgotitsnamebecauseitisaLIStProcessinglanguage.

Topicsinthissection

DifferentiatingBetweenLocalandGlobalVariablesUsingAssociationListstoBundleDataExaminingProgramVariablesRevisingtheProgramCodeCommentingProgramCodeSettingaBreakpointandUsingMoreWatchesWrappingUpLesson2

Pleasesendusyourcommentaboutthispage

Page 18: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

DifferentiatingBetweenLocalandGlobalVariables

Thislessondiscussestheuseoflocalvariablesversusglobaldocumentvariables.Globalvariablesareaccessiblebyallfunctionsloadedwithinadocument(anAutoCAD®drawing).Thesevariablesmayretaintheirvalueaftertheprogramthatdefinedthemcompletes.Sometimes,thisiswhatyouwant.You'llseeanexampleofthislaterinthetutorial.

Localvariablesretaintheirvalueonlyaslongasthefunctionthatdefinedthemisrunning.Afterthefunctionfinishesrunning,thelocalvariablevaluesareautomaticallydiscarded,andthesystemreclaimsthememoryspacethevariableused.Thisisknownasautomaticgarbagecollection,andisafeatureofmostLISPdevelopmentenvironments,suchasVLISP.Localvariablesusememorymoreefficientlythanglobalvariables.

Anotherbigadvantageisthatlocalvariablesmakeiteasiertodebugandmaintainyourapplications.Withglobalvariables,youareneversurewhenorinwhichfunctionthevariable'svaluemightbemodified;withlocalvariablesyoudon'thaveasfartotrace.Youusuallyendupwithfewersideeffects(thatis,one

Page 19: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

partoftheprogramaffectingavariablefromanotherpartoftheprogram).

Becauseoftheadvantagescited,thistutorialuseslocalvariablesalmostexclusively.

Note IfyouhavebeenworkingwithAutoLISPforsometime,youmayhavedevelopedthepracticeofusingglobalvariablesduringdevelopmenttoexamineyourprogramwhileyouarebuildingit.Thispracticeisnolongernecessary,giventhepowerfuldebuggingtoolsofVLISP.

Topicsinthissection

UsingLocalVariablesintheProgramExaminingthegp:getPointInputFunction

Pleasesendusyourcommentaboutthispage

Page 20: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>DifferentiatingBetweenLocalandGlobalVariables>

UsingLocalVariablesintheProgram

Refertothegp:getPointInputfunctionyoucreatedinLesson1:

(defungp:getPointInput()

(alert

"Functiongp:getPointInputwillgetuserdrawinginput"

)

;;Fornow,returnT,asifthefunctionworkedcorrectly.

T

)

Sofar,thefunctiondoesnotdomuchwork.Youwillnowbegintobuildonitbyaddingfunctionstogetinputfromtheuser,whichwilldefinethestartpoint,endpoint,andwidthofthepath.

ItisagoodpracticewhencreatingAutoLISPprogramstoemulatethebehaviorofAutoCAD.Forthisreason,insteadofaskingtheusertoindicatethewidthbyselectingapointinthedrawinginrespecttothecenterlineofalinearshape,yourprogramshouldaskforaselectionofthehalf-width.

Oncethegp:getPointInputfunctioniscomplete,thevariables,aswellasthevaluesassignedtothem,willnolongerexist.Therefore,youwillstoreuser-suppliedvaluesinlocalvariables.Here'swhatthefunctionmightlooklike:

(defungp:getPointInput(/StartPtEndPtHalfWidth)

(if(setqStartPt(getpoint"\nStartpointofpath:"))

(if(setqEndPt(getpointStartPt"\nEndpointofpath:"))

(if(setqHalfWidth(getdistEndPt"\nhalf-widthofpath:"))

T

)

)

)

)

Thelocalvariablesaredeclaredfollowingtheslashcharacter,inthedefun

Page 21: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

statementthatbeginsthefunction.Thefirstcalltogetpointpromptstheusertoindicateastartpoint.Theendpointisthenacquiredinrelationtothechosenstartpoint.Whileselectingtheendpoint,theuserwillobservearubber-bandlineextendingfromthestartpoint.Similarly,whilesettingthehalf-widthvalue,theuserwillviewanotherrubber-bandline,thistimerepresentingdistance,emanatingfromtheendpoint.

Toseehowgp:getPointInputworks

1. Typethegp:getPointInputcodeintotheVLISPConsolewindow.

2. WiththeConsolewindowcursorfollowingthelastparenthesisoftheblockofcode(oronthenextlinebelowit),pressENTERandyouwillreplaceanypreviouslyloadedversionofthegp:getPointInputfunction.

3. ExecutethefunctionfromtheConsolewindowbyentering(gp:getPointInput)attheConsoleprompt.

4. Pickpointswhenprompted,andenterahalf-widthvalue.

Pleasesendusyourcommentaboutthispage

Page 22: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>DifferentiatingBetweenLocalandGlobalVariables>

Examiningthegp:getPointInputFunction

Whenyouranthegp:getPointInputfunction,controlwasautomaticallypassedfromVLISPtoAutoCAD.Yourespondedtothreeprompts,afterwhichcontrolwaspassedbackfromAutoCADtoVLISP,andaTsymboldisplayedintheConsolewindow.

Withintheprogram,here'swhathappens:

1. VLISPwaitsforyoutopickthefirstpoint.

2. Whenyoupickthefirstpoint,theprogramstoresthevalueofyourselection(alistcontainingthreecoordinatevalues—anX,Y,andZvalue)intotheStartPtvariable.

3. Thefirstiffunctionexaminestheresulttodeterminewhetheravalidvaluewasenteredornovaluewasentered.Whenyoupickastartpoint,controlispassedtothenextgetpointfunction.

4. Whenyoupickanendpoint,thepointvalueisstoredintheEndptvariable.

5. Theresultofthisstatementisexaminedbythenextifstatement,andcontrolispassedtothegetdistfunction.

6. Thegetdistfunctionactsinasimilarfashionwhenyoupickapointonthescreenorenteranumericvalue.TheresultofthegetdistfunctionisstoredintheHalfWidthvariable.

7. ProgramflowreachestheTnesteddeeplywithinthefunction.Nootherfunctionsfollowthis,sothefunctionends,andthevalueTisreturned.ThisistheTyouseeattheConsolewindow.

Youneedsomewaytoreturnvaluesfromonefunctiontoanother.Onewayto

Page 23: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

dothisistocreatealistofthevaluesretrievedfromgp:getPointInput,ashighlightedinthefollowingcode:

(defungp:getPointInput(/StartPtEndPtHalfWidth)

(if(setqStartPt(getpoint"\nStartpointofpath:"))

(if(setqEndPt(getpointStartPt"\nEndpointofpath:"))

(if(setqHalfWidth(getdistEndPt"\nhalf-widthofpath:"))

(listStartPtEndPtHalfWidth)

)

)

)

)

Copythisversionofgp:getPointInputintotheConsolewindowandpressENTER.Here'sanopportunitytotryanotherfeatureoftheConsolewindow.

TousetheConsolewindowhistoryfeaturetorungp:getPointInput

1. PressTAB.ThisinvokestheConsolehistorycommand,cyclingthroughanycommandspreviouslyenteredintheConsolewindow.Ifyougotoofar,pressSHIFT+TABtocycleintheotherdirection.

2. Whenyousee(gp:getPointInput)attheConsoleprompt,pressENTERtoexecutethefunctiononceagain.

3. Respondtothepromptsasbefore.

Thefunctionreturnsalistcontainingtwonestedlistsandareal(floatingpoint)value.Thereturnvalueslooklikethefollowing:

((4.462074.623180.0)(7.666884.623180.0)0.509124)

ThesevaluescorrespondtotheStartPt,EndPt,andHalfWidthvariables.

Pleasesendusyourcommentaboutthispage

Page 24: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

UsingAssociationListstoBundleData

Thepreviousexampleworks,butyoucandobetter.Inthenextexercise,youwillbuildanassociationlist,orassoclist(aftertheLISPfunctionthatdealswithassociationlists).Inanassociationlist,thevaluesyouareinterestedinareassociatedwithkeyvalues.Hereisasampleassociationlist:

((104.462074.623180.0)(117.666884.623180.0)(40.1.018248))

Inthesampleassociationlist,thekeyvaluesarethenumbers10,11,and40.Thesekeyvaluesserveasauniqueindexwithinthelist.ThisisthemechanismAutoCADusestoreturnentitydatatoAutoLISPifyouaccessanentityfromwithinyourprogram.Akeyvalueof10indicatesastartpoint,akeyvalueof11istypicallyanendpoint.

Whataretheadvantagesofanassociationlist?Foronething,unliketheregularlist,theorderofthevaluesreturneddoesnotmatter.Lookatthefirstlistagain:

((4.462074.623180.0)(7.666884.623180.0)0.509124)

Lookatthereturnvalues;itisnotapparentwhichsublististhestartpointandwhichistheendpoint.Furthermore,ifyoumodifythefunctioninthefuture,anyotherfunctionthatreliesondatareturnedinaspecificordermaybeadverselyaffected.

Usinganassociationlist,theorderofthevaluesdoesnotmatter.Iftheorderofanassociationlistchanges,youcanstilltellwhichvaluedefineswhat.Forexample,an11valueisstillanendpoint,regardlessofwhereitoccurswithintheoveralllist:

((117.666884.623180.0);orderoflist

(40.1.018248);hasbeen

(104.462074.623180.0));modified

Page 25: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Topicsinthissection

PuttingAssociationListstoUseStoringtheReturnValueofgp:getPointInputinaVariable

Pleasesendusyourcommentaboutthispage

Page 26: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>UsingAssociationListstoBundleData>

PuttingAssociationListstoUse

Whenyouuseassociationlists,youshoulddocumentwhatyourkeyvaluesrepresent.Forthegardenpath,thekeyvaluesof10,11,40,41,and50willmeanthefollowing:

10indicatesthe3Dcoordinateofthestartpointofthepath.

11indicatesthe3Dcoordinateoftheendpointofthepath.

40indicatesthewidth(notthehalf-width)ofthepath.

41indicatesthelengthofthepath,fromstarttoend.

50indicatestheprimaryvector(orangle)ofthepath.

Thefollowingisanupdatedversionofthegp:getPointInputfunction.Withinit,anAutoLISPfunctioncalledcons(shortforconstructalist)buildsthekeyedsubliststhatbelongtotheassociationlist.CopythisversiontotheConsolewindow,pressENTER,andrun(gp:getPointInput)again:

(defungp:getPointInput(/StartPtEndPtHalfWidth)

(if(setqStartPt(getpoint"\nStartpointofpath:"))

(if(setqEndPt(getpointStartPt"\nEndpointofpath:"))

(if(setqHalfWidth(getdistEndPt"\nhalf-widthofpath:"))

;;ifyou'vemadeitthisfar,buildtheassociationlist

;;asdocumentedabove.Thiswillbethereturnvalue

;;fromthefunction.

(list

(cons10StartPt)

(cons11EndPt)

(cons40(*HalfWidth2.0))

(cons50(angleStartPtEndPt))

(cons41(distanceStartPtEndPt))

)

)

)

)

Page 27: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

)

Noticethat,whenbuildingthelist,theprogramconvertsthehalf-widthspecifiedbytheuserintoafullwidthbymultiplyingitsvalueby2.

TheConsolewindowshowsoutputsimilartothefollowing:

_$(gp:getPointInput)((102.160981.601160.0)(1112.71267.119630.0)(40.0.592604)(50.0.481876)(41.11.9076))

_$

Pleasesendusyourcommentaboutthispage

Page 28: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>UsingAssociationListstoBundleData>

StoringtheReturnValueofgp:getPointInputinaVariable

Nowtrysomethingelse.Callthefunctionagain,butthistimestorethereturnvalueinavariablenamedgp_PathData.Todothis,enterthefollowingattheConsolewindowprompt:

(setqgp_PathData(gp:getPointInput))

Toviewthevalueofthevariableyoujustset,enteritsnameattheConsolewindowprompt:

_$gp_PathData

VLISPreturnsdatalikethefollowing:

((102.177421.157710.0)(1113.20577.004660.0)(40.1.12747)(50.0.487498)(41.12.4824))

Pleasesendusyourcommentaboutthispage

Page 29: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

ExaminingProgramVariables

VLISPprovidesyouwithanentiretoolkitofprogramminganddebuggingtools.OneofthemostvaluabletoolsisaWatch,whichletsyouexaminevariablesinmoredetailthanappearsintheVLISPConsolewindow.Youcanalsowatchlocalvariableswithinfunctionsasthefunctionexecutes.

Towatchthevalueofavariable

1. ChooseDebug AddWatchfromtheVLISPmenu.VLISPdisplaysadialogboxtitled“AddWatch.”

Enterthenameofthevariableyouwishtoexamine.Forthisexample,specifygp_PathData,thevariableyoujustsetfromtheConsolewindow.VLISPdisplaysaWatchwindow:

VLISPdisplaysthevalueofthevariableonasinglelinewithintheWatchwindow—thebasewindowshownintheillustration.Inthiscase,thevalueofthevariableisalonglist,andyoucannotseeitsentirevalue.YoucanresizetheWatchwindowbydraggingitsborder,butthereisabetteralternative.

2. Double-clickonthevariablenameintheWatchwindow.ThisopensanInspectwindow:

Page 30: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

TheInspectwindowindicatesthedatatypeofthevariableyouareinspecting(inthiscase,alist),andthevalueofthevariable.Forlists,Inspectdisplayseachlistitemonitsownline.

3. Double-clickonthelinewiththeassociationlistkey11.VLISPopensanotherInspectwindow:

4. Whenyouaredoneinspectingvariables,closealltheInspectwindowsbutkeeptheWatchwindowopen.

Pleasesendusyourcommentaboutthispage

Page 31: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

RevisingtheProgramCode

Nowthatyou'veseenhowtouseassociationlistsinAutoLISPcode,youcanusethismethodinwritingthecompletedversionofthegp:getPointInputfunction.Usingthefollowingcode,replaceormodifytheversionofgp:getPointInputyoupreviouslysavedingpmain.lsp.

Note Ifyouneedorwanttotypethecodeintogpmain.lsp,ratherthancopyitfromanotherfile,youcansavetimebyleavingoutthecomments(alllinesthatbeginwithsemicolons).Butdon'tgetusedtotheideaofwritingcodewithoutcomments!

;;;--------------------------------------------------------------;

;;;Function:gp:getPointInput;

;;;--------------------------------------------------------------;

;;;Description:Thisfunctionaskstheusertoselectthree;

;;;pointsinadrawing,whichwilldeterminethe;

;;;pathlocation,direction,andsize.;

;;;--------------------------------------------------------------;

;;;Iftheuserrespondstothegetfunctionswithvaliddata,;

;;;usestartPtandendPttodeterminetheposition,length,;

;;;andangleatwhichthepathisdrawn.;

;;;--------------------------------------------------------------;

;;;Thereturnvalueofthisfunctionisalistconsistingof:;

;;;(10.StartingPoint);;Listof3reals(apoint)denoting;

;;;;;startingpointofgardenpath.;

;;;(11.EndingPoint);;Listof3reals(apoint)denoting;

;;;;;endingpointofgardenpath.;

;;;(40.Width);;Realnumberdenotingboundary;

;;;;;width.;

;;;(41.Length);;Realnumberdenotingboundary;

;;;;;length.;

;;;(50.PathAngle);;Realnumberdenotingtheangle;

;;;;;ofthepath,inradians.;

;;;--------------------------------------------------------------;

(defungp:getPointInput(/StartPtEndPtHalfWidth)

(if(setqStartPt(getpoint"\nStartpointofpath:"))

(if(setqEndPt(getpointStartPt"\nEndpointofpath:"))

Page 32: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(if(setqHalfWidth(getdistEndPt"\nhalf-widthofpath:"))

;;ifyou'vemadeitthisfar,buildtheassociationlist

;;asdocumentedabove.Thiswillbethereturnvalue

;;fromthefunction.

(list

(cons10StartPt)

(cons11EndPt)

(cons40(*HalfWidth2.0))

(cons50(angleStartPtEndPt))

(cons41(distanceStartPtEndPt))

)))))

Next,youneedtoupdatethemainfunction,C:GPath,ingpmain.lsp.Modifyittolooklikethefollowingcode:

(defunC:GPath(/gp_PathData)

;;Asktheuserforinput:firstforpathlocationand

;;direction,thenforpathparameters.Continueonlyifyou

;;havevalidinput.Storethedataingp_PathData.

(if(setqgp_PathData(gp:getPointInput))

(if(gp:getDialogInput)

(progn

;;Atthispoint,youhavevalidinputfromtheuser.

;;Drawtheoutline,storingtheresultingpolyline

;;pointerinthevariablecalledPolylineName.

(setqPolylineName(gp:drawOutline))

(princ"\nThegp:drawOutlinefunctionreturned<")

(princPolylineName)

(princ">")

(Alert"Congratulations-yourprogramiscomplete!")

);_endofprogn

(princ"\nFunctioncancelled.")

);_endofif

(princ"\nIncompleteinformationtodrawaboundary.")

);_endofif

(princ) ;exitquietly

);_endofdefun

Ifyouarecopyingandpastingthecode,addthefollowingcommentsasaheaderprecedingC:GPath:

;;;**************************************************************;

;;;Function:C:GPathTheMainGardenPathFunction;

;;;--------------------------------------------------------------;

;;;Description:Thisisthemaingardenpathfunction.Itisa;

;;;C:function,meaningthatitisturnedintoan;

;;;AutoCADcommandcalledGPATH.Thisfunction;

;;;determinestheoverallflowofthegardenpath;

Page 33: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

;;;program.;

;;;**************************************************************;

;;;Thegp_PathDatavariableisanassociationlistoftheform:;

;;;(10.StartingPoint)-Listof3reals(apoint)denoting;

;;;startingpointofthegardenpath.;

;;;(11.EndingPoint)-Listof3reals(apoint)denoting;

;;;endpointofthegardenpath.;

;;;(40.Width)-Realnumberdenotingboundary;

;;;width.;

;;;(41.Length)-Realnumberdenotingboundary;

;;;length.;

;;;(50.PathAngle)-Realnumberdenotingtheangleof;

;;;thepath,inradians.;

;;;(42.TileSize)-Realnumberdenotingthesize;

;;;(radius)ofthegardenpathtiles.;

;;;(43.TileOffset)-Spacingoftiles,bordertoborder.;

;;;(3.ObjectCreationStyle);

;;;-Objectcreationstyleindicateshow;

;;;thetilesaretobedrawn.The;

;;;expectedvalueisastringandone;

;;;oneofthreevalues(stringcase;

;;;isunimportant):;

;;;"ActiveX";

;;;"Entmake";

;;;"Command";

;;;(4.PolylineBorderStyle);

;;;-Polylineborderstyledetermines;

;;;thepolylinetypetobeusedfor;

;;;pathboundary.Theexpectedvalue;

;;;oneofthefollowing(stringcaseis;

;;;unimportant):;

;;;"Pline";

;;;"Light";

;;;**************************************************************;

Totestthecoderevisions

1. Savetheupdatedfile.

2. UsetheCheckfeaturetosearchforanysyntacticalerrors.

3. Formatthecode,tomakeitmorereadable.

4. Loadthecode,sothatVLISPredefinestheearlierversionsofthefunctions.

5. Toruntheprogram,enter(c:gpath)attheConsoleprompt.

Page 34: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Iftheprogramdoesnotrunsuccessfully,tryfixingitandrunningitagain.Repeatuntilyouaretoofrustratedtocontinue.Ifallelsefails,youcancopythecorrectcodefromtheTutorial\VisualLISP\Lesson2directory.

Pleasesendusyourcommentaboutthispage

Page 35: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

CommentingProgramCode

VLISPtreatsanyAutoLISPstatementbeginningwithasemicolonasacomment.Thelasttwocodeexamplescontainedalotofcomments.AcommentinanAutoLISPprogramissomethingyouwriteforyourself,notfortheprogram.Commentingcodeisoneofthebestprogrammingpracticesyoucanestablishforyourself.Whywritecomments?

Toexplainthecodetoyourselfwhenyouareeditingtheprogramninemonthsinthefuture,addingallthosefeaturesyourusershavebeenaskingyouabout.Memoryfades,andthemostapparentsequenceoffunctionscaneasilyturnintoanunrecognizabletangleofparentheses.

Toexplainthecodetootherswhoinherittheresponsibilityofupdatingtheprogram.Readingsomeoneelse'scodeisanextremelyfrustratingexperience,especiallyifthecodecontainsveryfewcomments.

VLISPcontainssomeutilitiesthathelpyouasyoucommentyourcode.Noticesomecommentsintheexamplesbeginwiththreesemicolons(;;;),sometimestwo(;;),andsometimesjustone(;).Referto“ApplyingVisualLISPCommentStyles”intheAutoLISPDeveloper'sGuidetoseehowVLISPtreatsthedifferentcomments.

Tosavespace,theremainingcodeexamplesinthistutorialdonotincludeallthecommentsinthesamplesourcefiles.Itisassumedyouhavealreadyestablishedthebeneficialhabitofextensivecommentingandwilldosowithoutanyprompting.

Pleasesendusyourcommentaboutthispage

Page 36: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

SettingaBreakpointandUsingMoreWatches

Abreakpointisasymbol(point)youplaceinsourcecodetoindicatewhereyouwantaprogramtostopexecutingtemporarily.Whenyourunyourcode,VLISPproceedsnormallyuntilitencountersabreakpoint.Atthatpoint,VLISPsuspendsexecutionandwaitsforyoutotellitwhattodo.Ithasn'thaltedtheprogramforgood—ithasplaceditinastateofsuspendedanimation.

Whileyourprogramissuspended,youcan

Stepthroughyourcode,functionbyfunction,orexpressionbyexpression.

Resumenormalexecutionofyourprogramatanypoint.

Alterthevalueofvariablesdynamically,andchangetheresultsoftheprogrambeingexecuted.

AddvariablestotheWatchwindow.

Topicsinthissection

UsingtheDebugToolbarSteppingThroughCodeWatchingVariablesAsYouStepThroughaProgramSteppingOutofthegp:getPointInputFunctionandintoC:Gpmain

Pleasesendusyourcommentaboutthispage

Page 37: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>SettingaBreakpointandUsingMoreWatches>

UsingtheDebugToolbar

TheDebugtoolbarcontainsseveraltoolsyouwillemployasyouworkthroughthissection.Bydefault,thistoolbarisattachedtotheViewandToolstoolbars,andappearsasasingleVLISPtoolbar.

TheDebugtoolbaristheleft-mostsetoficons.Mostoftheitemsonthetoolbarareinactiveuntilyourunyourprogramindebuggingmode(thatis,withoneormorebreakpointsdefined).

Ifyouhaven'tdonesoalready,detachtheDebugtoolbarfromitspositionatthetopofthescreen.Todothis,grabanddragitbythetwoverticalgripsattheleftofthetoolbar.YoucandetachanyoftheVLISPtoolbarsandpositionthemonyourscreenwheretheyaremosteffectiveforyourstyleofwork.

TheDebugtoolbarisdividedintothreemaingroupsofbuttons,eachconsistingofthreebuttons.Whenyourunaprogramindebuggingmode,thetoolbarlookslikethefollowing:

Thefirstthreebuttonsallowyoutostepthroughyourprogramcode.

ThenextthreebuttonsdeterminehowVLISPshouldproceedwheneverithasstoppedatabreakpointoranerror.

Thenextthreebuttonssetorremoveabreakpoint,addaWatch,andjumptothepositionwithinyoursourcecodewherethelastbreakoccurred.

ThelastbuttonontheDebugtoolbarisaStepIndicator.Itdoesnotexecuteanyfunctionbutprovidesavisualindicationofwhereyourcursorispositionedasyoustepthroughyourcode.Whenyouarenotrunningindebuggingmode,this

Page 38: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

buttonappearsblank.

Tosetabreakpoint

1. IntheVLISPeditorwindowcontaininggpmain.lsp,positionyourcursorjustinfrontoftheopeningparenthesisofthesetqfunctionofthefollowinglineofcode,withinthegp:getPointInputfunction:

(setqHalfWidth(getdistEndPt"\nhalf-widthofpath:"))

2. Clickthemouseonce.Thepositionisillustratedinthefollowingscreensnapshot:

3. Withthetextinsertionpointset,choosetheToggleBreakpointbuttonontheDebugtoolbar.

TheToggleBreakpointbuttonactsasatoggle,alternatingbetweenonandoffstates.Ifthereisnobreakpointatthecursorposition,itsetsone;ifthereisalreadyabreakpointthere,itremovesit.

4. ChoosetheLoadActiveEditWindowbuttonontheToolstoolbartoloadthefile.

Page 39: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

5. Runthe(C:GPath)functionfromtheVLISPConsoleprompt.VLISPexecutestheprogramnormallyuptothebreakpoint.Inthiscase,itwillpromptyouforthefirsttwopoints—thestartpointandendpointofthepath.

6. Specifythestartpointandendpointwhenprompted.Afteryouspecifythepoints,VLISPsuspendsexecutionoftheprogramandreturnsfocustothetexteditorwindow,highlightingthelineofcodeatthebreakpointposition:

Thereareacoupleofthingstonotice:

Thecursorislocatedrightatthebreakpoint.Thismaybedifficulttonotice,soVLISPprovidesanotherclue.

IntheDebugtoolbar,theStepIndicatoricondisplaysaredI-beamcursorinfrontofapairofparentheses.ThisindicatestheVLISPdebuggerisstoppedbeforetheexpression.

Page 40: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 41: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>SettingaBreakpointandUsingMoreWatches>

SteppingThroughCode

Therearethreebuttonsyoucanusetostepthroughyourcode.Thesearethethreeleft-mosticonsontheDebugtoolbar.Insequence,theyrepresentthefollowingactions:

Stepintothehighlightedexpression.

Stepovertotheendofthehighlightedexpression.

Stepouttotheendofthefunctionwhereyouarecurrentlystopped.

Beforeyoumakeaselection,takeanotherlookatthestatusofthehighlightedcode,thecursorposition,andtheStepIndicatorbutton.Insummary:anexpressionishighlighted,consistingofagetdistfunctionnestedwithinasetqfunction,andthecursorispositionedattheverybeginningofthehighlightedblock.

Tostepthroughthecodefromthebreakpoint

1. ChoosetheStepOverbutton.

AfteryouchoosetheStepOverbutton,controlpassestoAutoCADandyouarepromptedtospecifythewidthofthepath.

2. Replytotheprompt.Afteryouspecifythewidth,controlpassesbacktoVLISP.Noticewhereyourcursorisandwhatthestepindicatorbuttonshows.VLISPevaluatestheentirehighlightedexpression,thenstopsattheendoftheexpression.

3. ChoosetheStepOverbuttonagain.VLISPjumpstothebeginningofthe

Page 42: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

nextblockofcode,andhighlightstheentireblock.

4. ChoosetheStepInto(notStepOver)button.

Note Duringthisexercise,ifyoumakeanincorrectselectionandskipasteportwo,youcanrestarttheexerciseveryeasily.First,choosetheResetbuttonfromtheDebugtoolbar.ThisterminatestheexecutionofanyVLISPcode,andresetstheVLISPsystemtothetoplevel.Next,startoveratstep1.

Nowthefirstconsfunctionishighlighted,andVLISPisstoppedrightbeforethefunction(noticetheStepIndicatorbutton).

Pleasesendusyourcommentaboutthispage

Page 43: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>SettingaBreakpointandUsingMoreWatches>

WatchingVariablesAsYouStepThroughaProgram

Whileyoustepthroughyourprogram,youcanaddvariablestotheWatchwindowandchangetheirvalues.

IfyoudonotseetheWatchwindow,simplychoosetheWatchWindowbuttononthetoolbartobringitback.

IfyourWatchwindowstillscontainsthevariablegp_PathData,choosetheClearWindowbuttondisplayedatthetopoftheWatchwindow.

ToaddvariablestotheWatchwindow

1. Double-clickonanyoccurrenceofStartPtintheVLISPtexteditorwindow.Thisisthenameofthevariablewhosevalueyouwanttotrack.

2. ChoosetheAddWatchbuttonintheWatchwindow,orright-clickandchooseAddWatch.

3. RepeatthisprocessforthevariablesEndPtandHalfWidth.YourWatchwindowshouldresemblethefollowing:

Ifyouaredebuggingaprogramthatisn'tworkingcorrectly,usebreakpointsincombinationwithwatchestomakesureyourvariablescontainthevaluesyouexpect.

Page 44: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Ifavariabledoesnotcontainthevalueyouthinkitshould,youcanchangethevalueandseehowitaffectstheprogram.Forexample,saythatyouexpectthehalfwidthvaluetobeawholenumber.Butbecauseyouweren'tcarefulaboutpickingthepointsduringtheinputselections,youendedupwithavaluelike1.94818.

Tochangethevalueofavariablewhiletheprogramisrunning

1. EnterthefollowingattheConsoleprompt:

(setqhalfwidth2.0)

NotethatthevalueintheWatchwindowchanges.Butcanyoubesurethenewvaluewillbeusedwhenthewidthsublist(40.width)iscreatedintheassociationlist?AddonemoreexpressiontotheWatchwindowtotestthis.

2. ChooseDebug WatchLastEvaluationfromtheVLISPmenu.Thisaddsavariablenamed*Last-Value*toyourWatchwindow.*Last-Value*isaglobalvariableinwhichVLISPautomaticallystoresthevalueofthelastexpressionevaluated.

3. Stepthroughtheprogram(choosingeithertheStepIntoorStepOverbutton)untiltheexpressionresponsibleforbuildingthewidthsublistisevaluated.Thecodeforthisactionis:

(cons40(*HalfWidth2.0))

IfyouoverrodethevalueofHalfWidthasspecified,theevaluationofthisexpressionshouldreturn(40.4.0)intheWatchwindow.

Pleasesendusyourcommentaboutthispage

Page 45: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>SettingaBreakpointandUsingMoreWatches>

SteppingOutofthegp:getPointInputFunctionandintoC:Gpmain

Thereisonemorepointtoillustrate:whathappenstothevalueofthelocalvariablesingp:getPointInputafteryouexitthefunction.

Toexitgp:getPointInputandreturncontroltoc:gpath

1. ChoosetheStepOutbutton.

VLISPstepstotheveryendofthegp:getPointInputfunctionandstopsjustbeforeexiting.

2. ChoosetheStepIntobutton.

Controlreturnstoc:gpmain,thefunctionthatcalledgp:getPointInput.

ExaminethevaluesofthevariablesintheWatchwindow.Becausetheyarevariableslocaltothegp:getPointInputfunction,endptandStartPtarenil.VLISPautomaticallyreclaimedthememoryoccupiedbythesevariables.Normally,thethirdlocalfunctionvariableHalfWidthalsocontainsavalueofnil,butduetodebuggingactivity,itwasoverriddengloballyintheConsolewindowandstillpossessesthevalue2.0intheWatchwindow.Alsotheglobal*Last-Value*variabledisplaystheassociationlistconstructedbygp:getPointInput.

Yourfirstdebuggingsessioniscomplete.Butdon'tforgetyourprogramisstillinsuspendedanimation.

Page 46: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Tocompletethislesson

1. ChoosetheContinuebuttonontheDebugtoolbar.Respondtotheprompts.Thisrunstheprogramtocompletion.

2. ChooseDebug ClearAllBreakpointsfromtheVLISPmenu.Respond“yes”totheprompt.Thisremovesallthebreakpointswithinyourcode.Remember:youcanremoveindividualbreakpointsbypositioningthecursoratthebreakpointandchoosingtheToggleBreakpointbutton.

Pleasesendusyourcommentaboutthispage

Page 47: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

UsingVisualLISPDebuggingTools>

WrappingUpLesson2

Inthislesson,you

Learnedaboutlocalandglobalvariables.

Setandremovedbreakpointsinaprogram.

Steppedthroughaprogramwhileitwasexecuting.

Watchedanddynamicallychangedthevalueofprogramvariablesduringexecution.

Sawhowlocalvariablesareresettonilafterthefunctionthatdefinedthemcompletesitsrun.

ThetoolsyoulearnedinthislessonwillbepartofyourdailyworkifyouintendtodevelopAutoLISPapplicationswithVLISP.

Pleasesendusyourcommentaboutthispage

Page 48: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary

Inthislesson,youwillexpandyourprogramsoitactuallydrawssomethingwithinAutoCAD—thepolylineoutlineofthegardenpath.Todrawtheborder,youmustcreatesomeutilityfunctionsthatarenotspecifictoasingleapplicationbutaregeneralinnatureandmayberecycledforlateruse.Youwillalsolearnaboutwritingfunctionsthatacceptarguments—datathatispassedtothefunctionfromtheoutside—andwhytheuseofargumentsisapowerfulprogrammingconcept.Bytheendofthelesson,youwilldrawanAutoCADshapeparametrically,whichmeansdynamicallydrawingashapebasedontheuniquedataparametersprovidedbytheuser.

Topicsinthissection

PlanningReusableUtilityFunctionsDrawingAutoCADEntitiesEnablingtheBoundaryOutlineDrawingFunctionWrappingUpLesson3

Pleasesendusyourcommentaboutthispage

Page 49: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>

PlanningReusableUtilityFunctions

Utilityfunctionsperformtaskscommontomanyapplicationsyouwillbewriting.Thesefunctionsformatoolkityoucanuseoverandoveragain.

Whenyoucreateafunctionaspartofatoolkit,spendsometimedocumentingitthoroughly.Inyourcomments,alsonotethefeaturesyouwouldliketoaddtothefunctioninthefuture,shouldtimepermit.

Topicsinthissection

ConvertingDegreestoRadiansConverting3DPointsto2DPoints

Pleasesendusyourcommentaboutthispage

Page 50: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>PlanningReusableUtilityFunctions>

ConvertingDegreestoRadians

Youwillnowcreateafunctiontopreventyoufromrepetitivelytypinganequation.Itlookslikethis:

(defunDegrees->Radians(numberOfDegrees)

(*pi(/numberOfDegrees180.0)))

ThisfunctioniscalledDegrees->Radians.Thefunctionnameindicatesitspurpose.

Whydoyouneedafunctiontoconvertangularmeasurements?Behindthescenes,AutoCAD®usesradianangularmeasurementtokeeptrackofangles,whereasmostpeoplethinkintermsofdegrees.Thisfunctioninyourtoolkitallowsyoutothinkindegrees,andletsAutoLISP®convertthosenumberstoradians.

Totesttheutilityfunction

1. EnterthefollowingattheVLISPConsoleprompt:

(defunDegrees->Radians(numberOfDegrees)

(*pi(/numberOfDegrees180.0)))

2. EnterthefollowingattheVLISPConsoleprompt:

(degrees->radians180)

Thefunctionreturnsthenumber3.14159.Accordingtohowthisfunctionworks,180degreesisequivalentto3.14159radians.

Tousethisfunctionwithinyourprogram,simplycopythefunctiondefinitionfromtheConsolewindowintoyourgpmain.lspfile.Youcanpasteitanywhereinthefile,aslongasyoudonotpasteitintothemiddleofanexistingfunction.

Page 51: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Tocleanupyourwork,selectthetextyoujustpastedin,thenchoosetheFormatSelectionbutton;VLISPwillproperlyindentandformatthecode.

Next,addsomecommentsdescribingthefunction.Whenyouhavefullydocumentedthefunction,yourcodeshouldlooksomethinglikethis:

;;;--------------------------------------------------------------;

;;;Function:Degrees->Radians;

;;;--------------------------------------------------------------;

;;;Description:Thisfunctionconvertsanumberrepresentingan;

;;;angularmeasurementindegrees,intoitsradian;

;;;equivalent.Thereisnoerrorcheckingonthe;

;;;numberOfDegreesparameter--itisalways;

;;;expectedtobeavalidnumber.;

;;;--------------------------------------------------------------;

(defunDegrees->Radians(numberOfDegrees)

(*pi(/numberOfDegrees180.0))

)

Pleasesendusyourcommentaboutthispage

Page 52: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>PlanningReusableUtilityFunctions>

Converting3DPointsto2DPoints

Anotherusefulfunctioninthegardenpathprogramconverts3Dpointsto2Dpoints.AutoCADusuallyworkswith3Dcoordinates,butsomeentities,suchaslightweightpolylines,arealwaysmeanttobe2D.Thepointsreturnedbythegetpointfunctionare3D,soyouneedtocreateafunctiontoconvertthem.

Toconverta3Dpointtoa2Dpoint

1. EnterthefollowingattheConsolewindowprompt:

(defun3dPoint->2dPoint(3dpt)(list(car3dpt)(cadr3dpt)))

2. TestthefunctionbyenteringthefollowingattheConsoleprompt:

(3dpoint->2dpoint(list10200))

Thisworks,butthereisanotherconsiderationforthegardenpathapplication.Althoughitoftendoesn'tmatterwhetheranumberisanintegerorarealinLISPfunctions,thisisn'tthecasewithActiveXfunctions,whichyou'lluselaterinthislesson.ActiveXfunctionsrequirerealnumbers.Youcaneasilymodifythefunctiontoensureitreturnsrealsinsteadofintegers.

3. EnterthefollowingcodeattheConsoleprompt:

(defun3dPoint->2dPoint(3dpt)(list(float(car3dpt))

(float(cadr3dpt))))

4. Runthefunctionagain:

(3dpoint->2dpoint(list10200))

Noticethereturnvaluesarenowreals(indicatedbythedecimalvalues).

Page 53: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

5. Testthefunctionagain,thistimeusingthegetpointfunction.EnterthefollowingattheConsoleprompt:

(setqmyPoint(getpoint))

6. PickapointintheAutoCADdrawingarea.Thegetpointfunctionreturnsa3Dpoint.

7. EnterthefollowingattheConsoleprompt:

(3dPoint->2DpointmyPoint)

Notethe2Dpointreturned.Nowaddthefunctiontothegpmain.lspfile,justasyoudidwithDegrees->Radians.Thenewcodeshouldlooklikethefollowing:

;;;--------------------------------------------------------------;

;;;Function:3dPoint->2dPoint;

;;;--------------------------------------------------------------;

;;;Description:Thisfunctiontakesoneparameterrepresentinga;

;;;3Dpoint(listofthreeintegersorreals),and;

;;;convertsitintoa2Dpoint(listoftworeals).;

;;;Thereisnoerrorcheckingonthe3Dpoint;

;;;parameter--itisassumedtobeavalidpoint.;

;;;--------------------------------------------------------------;

;;;Todo:Addsomekindofparametercheckingsothatthis;

;;;functionwon'tcrashaprogramifitispasseda;

;;;nullvalue,orsomeotherkindofdatatypethana;

;;;3Dpoint.;

;;;--------------------------------------------------------------;

(defun3dPoint->2dPoint(3dpt)

(list(float(car3dpt))(float(cadr3dpt)))

)

Notethatthefunctionheadingincludesacommentaboutsomeworkyoushoulddoonthisfunctioninthefuture.Ifyouwanttoearnsomeextracredit,thinkabouthowyouwouldgoaboutfoolproofingthisfunctionsothatinvaliddatadoesnotmakeitcrash.Hint:numberpandlistpfunctions…

(listp'(110))=>T

(numberp3.4)=>T

Page 54: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 55: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>

DrawingAutoCADEntities

MostAutoLISPprogramsdrawentitiesusingoneofseveralmethods:

ActiveXfunctions

Theentmakefunction

Thecommandfunction

ThislessonfocusesonentitycreationbyActiveX®.InLesson5,youwillimplementtheentmakeandAutoCADcommandalternatives.

Topicsinthissection

CreatingEntitiesUsingActiveXFunctionsUsingentmaketoBuildEntitiesUsingtheAutoCADCommandLine

Pleasesendusyourcommentaboutthispage

Page 56: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>DrawingAutoCADEntities>

CreatingEntitiesUsingActiveXFunctions

ThenewestwayofcreatingentitiesisbyusingtheActiveXfunctionswithinVLISP.ActiveXhasseveraladvantagesoverentmakeandcommand.

ActiveXfunctionsarefaster.

ActiveXfunctionnamesindicatetheactiontheyperform,resultingineasierreadability,maintenance,andbug-fixing.

YouwillseeanexampleofanActiveXfunctionlaterinthislesson.

Pleasesendusyourcommentaboutthispage

Page 57: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>DrawingAutoCADEntities>

UsingentmaketoBuildEntities

Theentmakefunctionallowsyoutobuildanentitybygatheringvaluesforthingssuchascoordinatelocationandorientation,layer,andcolorintoanassociationlist,thenaskingAutoCADtobuildtheentityforyou.Theassociationlistyoubuildfortheentmakefunctionlooksverymuchliketheassociationlistyougetbackwhenyoucalltheentgetfunction.Thedifferenceisthatentgetreturnsinformationaboutanentity,whileentmakebuildsanewentityfromrawdata.

Pleasesendusyourcommentaboutthispage

Page 58: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>DrawingAutoCADEntities>

UsingtheAutoCADCommandLine

WhenAutoLISPfirstappearedinAutoCAD,theonlyavailablemeansforentitycreationwasthecommandfunction.ThisallowsanAutoLISPprogrammertocodejustaboutanycommandthatcanbeexecutedfromtheAutoCADCommandprompt.Thisisreliable,butitisnotasfastasActiveXmethodsanddoesnotprovidetheflexibilityofentmake.

Pleasesendusyourcommentaboutthispage

Page 59: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>

EnablingtheBoundaryOutlineDrawingFunction

Afterthelastlesson,thegp:drawOutlinefunctionlookedlikethefollowing:

;;;--------------------------------------------------------------;

;;;Function:gp:drawOutline;

;;;--------------------------------------------------------------;

;;;Description:Thisfunctiondrawstheoutlineofthe;

;;;gardenpath.;

;;;--------------------------------------------------------------;

(defungp:drawOutline()

(alert

(strcat"Thisfunctionwilldrawtheoutlineofthepolyline"

"\nandreturnapolylineentityname/pointer."

)

)

;;Fornow,simplyreturnaquotedsymbol.Eventually,this

;;functionwillreturnanentitynameorpointer.

'SomeEname

)

Asitexists,thecodedoesnotdomuch.However,usingtheassociationlistinformationstoredinthevariablegp_PathData,youhaveenoughinformationtocalculatethepointsforthepathboundary.Younowhavetodeterminehowtopasstheinformationinthatvariabletogp:drawOutline.

Remembergp_PathDataisalocalvariabledefinedwithintheC:GPathfunction.InAutoLISP,localvariablesdeclaredinonefunctionarevisibletoanyfunctioncalledfromthatfunction(refertoDifferentiatingBetweenLocalandGlobalVariablesforclarification).Thegp:drawOutlinefunctioniscalledfromwithinC:GPath.Youcanrefertothegp_PathDatavariableingp:drawOutline,butthisisnotagoodprogrammingpractice.

Why?Whenthetwofunctionsusingthesamevariablearedefinedinthesamefile,asintheexamplesshownsofar,itisnottoodifficulttofigureoutwherethe

Page 60: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

variableisdefinedandwhatitisusedfor.Butifthefunctionsaredefinedindifferentfiles—asisoftenthecase—youwouldhavetosearchthroughbothfilestofigureoutwhatgp_PathDatarepresents.

Topicsinthissection

PassingParameterstoFunctionsWorkingwithanAssociationListUsingAnglesandSettingUpPointsUnderstandingtheActiveXCodeingp:drawOutlineEnsuringThatActiveXIsLoadedObtainingaPointertoModelSpaceConstructinganArrayofPolylinePointsConstructingaVariantfromaListofPointsPuttingItAllTogether

Pleasesendusyourcommentaboutthispage

Page 61: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

PassingParameterstoFunctions

Abetterwaytoconveyinformationfromonefunctiontoanotheristopassparameterstothecalledfunction.Designthefunctionsoitexpectstoreceiveanumberofvalues.RemembertheDegrees->Radiansfunction?ThisfunctionispassedaparameternamednumberOfDegrees:

(defunDegrees->Radians(numberOfDegrees)

(*pi(/numberOfDegrees180.0)))

Whenyoucallthefunction,itexpectsyoutopassitanumber.ThenumberwithinDegrees->RadiansisdeclaredastheparameternamednumberOfDegrees.Forexample:

_$(degrees->radians90)1.5708

Inthiscase,thenumber90isassignedtotheparameternumberOfDegrees.

Youcanalsopassavariabletoafunction.Forexample,youmighthaveavariablecalledaDegreeValuethatcontainsthenumber90.ThefollowingcommandssetaDegreeValueandpassthevariabletoDegrees->Radians:

_$(setqaDegreeValue90)90

_$(degrees->radiansaDegreeValue)1.5708

Pleasesendusyourcommentaboutthispage

Page 62: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

WorkingwithanAssociationList

Youcanpasstheassociationlistinthegp_PathDatavariabletothegp:drawOutlinefunctionbyinvokingthefunctionasfollows:

(gp:drawOutlinegp_PathData)

Simpleenough,butyoualsoneedtofigureouthowtoprocesstheinformationstoredintheassociationlist.TheVLISPInspectfeaturecanhelpyoudeterminewhattodo.

TousetheVLISPInspectfeaturetoanalyzeyourassociationlist

1. Loadthecodethatisinthetexteditorwindow.

2. EnterthefollowingexpressionattheConsoleprompt:

(setqBoundaryData(gp:getPointInput))

VLISPwillstoretheinformationyouprovideinavariablenamedBoundaryData.

3. Respondtothepromptsforstartpoint,endpoint,andhalf-width.

4. SelecttheBoundaryDatavariablenameintheConsolewindowbydouble-clickingit.

5. ChooseView InspectfromtheVLISPmenu.

VLISPdisplaysawindowlikethefollowing:

Page 63: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

TheInspectwindowshowsyoueachsublistwithintheBoundaryDatavariable.

6. EnterthefollowingattheVLISPConsoleprompt:

(assoc50BoundaryData)

Theassocfunctionreturnstheentryintheassociationlistthatisidentifiedbythespecifiedkey.Inthisexample,thespecifiedkeyis50;thisisassociatedwiththeangleofthegardenpath(seePuttingAssociationListstoUseforalistofthekey-valuepairsdefinedforthisapplication).

7. EnterthefollowingattheVLISPConsoleprompt:

(cdr(assoc50BoundaryData))

Thecdrfunctionreturnsthesecondelement,andanyremainingelementsafterthat,fromalist.Inthisexample,cdrretrievestheanglevalue,whichisthesecondandlastelementintheentryreturnedbytheassocfunction.Bythispoint,youshouldhavenotroubleunderstandingthefollowingcodefragment:

(setqPathAngle(cdr(assoc50BoundaryData))

Width(cdr(assoc40BoundaryData))

HalfWidth(/Width2.00)

StartPt(cdr(assoc10BoundaryData))

PathLength(cdr(assoc41BoundaryData))

Pleasesendusyourcommentaboutthispage

Page 64: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

UsingAnglesandSettingUpPoints

Therearestillacoupleofissuesremaining.First,youneedtofigureouthowtodrawthepathatanyangletheuserspecifies.Fromthegp:getPointInputfunction,youcaneasilyestablishtheprimaryangleofthepath.Todrawit,youneedacoupleofadditionalvectorsperpendiculartotheprimaryangle.

ThisiswheretheDegrees->Radiansfunctionisuseful.ThefollowingcodefragmentdemonstrateshowyoucansetupyourtwoperpendicularvectorsusingthePathAnglevariableasanargumentpassedtotheDegrees->Radiansfunction:

(setqangp90(+PathAngle(Degrees->Radians90))

angm90(-PathAngle(Degrees->Radians90)))

Withthedatayounowhaveinhand,youcanestablishthefourcornerpointsofthepathusingpolarfunction:

Page 65: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setqp1(polarStartPtangm90HalfWidth)

p2(polarp1PathAnglePathLength)

p3(polarp2angp90Width)

p4(polarp3(+PathAngle(Degrees->Radians180))

Thepolarfunctionreturnsa3Dpointataspecifiedangleanddistancefromapoint.Forinstance,polarlocatesp2byprojectingp1adistanceofPathLengthalongavectororientedatanangleofPathAngle,counter-clockwisefromthex-axis.

Pleasesendusyourcommentaboutthispage

Page 66: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

UnderstandingtheActiveXCodeingp:drawOutline

Thegp:drawOutlinefunctionissuesActiveXcallstodisplaythepath'spolylineborderinAutoCAD.ThefollowingcodefragmentusesActiveXtodrawtheborder:

;;AddpolylinetothemodelspaceusingActiveXautomation.

(setqpline(vla-addLightweightPolyline

*ModelSpace* ;GlobalDefinitionforModelSpace

VLADataPts ;verticesofpathboundary

);_endofvla-addLightweightPolyline

);_endofsetq

(vla-put-closedplineT)

Howdoyoumakesenseofthiscode?AnessentialresourceistheActiveXandVBAReference,whichdescribesthemethodsandpropertiesaccessibletoActiveXclientssuchasthisgardenpathapplication.The“WorkingwithActiveX”sectionoftheAutoLISPDeveloper'sGuideexplainshowtotranslatetheVBA™syntaxintheActiveXandVBAReferenceintoActiveXcallsinAutoLISPsyntax.

Forthemoment,though,youcangainarudimentaryunderstandingbyscrutinizingthepatternofthetwovla-callsintheprecedingexample.ThenamesofallAutoLISPActiveXfunctionsthatworkonAutoCADobjectsareprefixedwithvla-.Forexample,addLightweightPolylineisthenameofanActiveXmethod,andvla-addLightweightPolylineistheAutoLISPfunctionthatinvokesthismethod.Thevla-put-closedcallupdatestheclosedpropertyoftheplineobject,thepolylinedrawnbyvla-addLightweightPolyline.

TheAutomationobjectsthatfactorintoAutoLISPActiveXcallsabidebyafewstandardrules:

Thefirstargumenttoavla-put,vla-get,orvla-methodcallistheobjectbeingmodifiedorqueried,forexample,*ModelSpace*in

Page 67: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

thefirstfunctioncallandplineinthesecondcall.

Thereturnvalueofavla-methodcallisaVLA-object,whichcanbeusedinsubsequentcalls.Forexample,vla-addLightweightPolylineyieldsareturnobject,pline,thatisalteredinthenextActiveXcall.

TheActiveXobjectmodelisstructuredhierarchically.Objectsaretraversedfromtheapplicationobjectatthetopmostleveldowntoindividualdrawingprimitives,suchaspolylineandcircleobjects.Thus,thegp:drawOutlinefunctionisnotyetcomplete,becausethe*ModelSpace*automationobjectmustfirstbeaccessedthroughtherootapplicationobject.

Pleasesendusyourcommentaboutthispage

Page 68: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

EnsuringThatActiveXIsLoaded

ActiveXfunctionalityisnotautomaticallyenabledwhenyoustartAutoCADorVLISP,soyourprogramsmustensurethatActiveXisloaded.Thefollowingfunctioncallaccomplishesthis:

(vl-load-com)

IfActiveXsupportisnotyetavailable,executingvl-load-cominitializestheAutoLISPActiveXenvironment.IfActiveXisalreadyloaded,vl-load-comdoesnothing.

Pleasesendusyourcommentaboutthispage

Page 69: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

ObtainingaPointertoModelSpace

WhenyouaddentitiesthroughActiveXfunctions,youneedtoidentifythemodelspaceorpaperspaceinwhichtheentityistobeinserted.(InActiveXterminology,entitiesareobjects,butthistutorialwillcontinueusingthetermentity.)TotellAutoCADwhichspacethenewentitiesshouldoccupy,youneedtoobtainapointertothatspace.Unfortunately,obtainingapointertomodelspaceisnotasimple,single-shotfunction.Thefollowingcodefragmentshowshowtheoperationneedstobesetup:

(vla-get-ModelSpace(vla-get-ActiveDocument

(vlax-get-Acad-Object)))

Workingfromtheinsideout,thevlax-get-Acad-ObjectfunctionretrievesapointertoAutoCAD.Thispointerispassedtothevla-get-ActiveDocumentfunction,whichretrievesapointertotheactivedrawing(document)withinAutoCAD.TheActiveDocumentpointeristhenpassedtothevla-get-ModelSpacefunctionthatretrievesapointertothemodelspaceofthecurrentdrawing.

Thisisnotthekindofexpressionyouwanttotypeoverandover.Forexample,lookathowmuchmorecomplicatedthecodeforaddingapolylineusingActiveXappearswhentheentiremodelspaceexpressionisused:

(setqpline(vla-addLightweightPolyline

(vla-get-ModelSpace

(vla-get-ActiveDocument

(vlax-get-Acad-Object)

)

)

VLADataPts)

)

(vla-put-closedplineT)

Thefunctionisdefinitelylessunderstandable.Notonlythat,butwithinevery

Page 70: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

expressionwithinyourprogramwhereanentityiscreated,yourepeatthesamesetofnestedfunctions.Thisdemonstratesoneofthefewexcellentusesforglobalvariables.Thegardenpathapplicationcanaddalotofentitiestomodelspace(thinkofallthetilesinthepath),so,setupaglobalvariabletostorethepointertothemodelspace,asinthefollowingcode:

(setq*ModelSpace*(vla-get-ModelSpace(vla-get-ActiveDocument

(vlax-get-Acad-Object))))

Youcanusethevariable*ModelSpace*anytimeyoucallanActiveXentitycreationfunction.Theonlytrickythingwiththisschemeisthe*ModelSpace*variablemustbereadytogobeforeyoustartdrawing.Forthisreason,thesetqestablishingthisvariablewillbecalledatthetimetheapplicationisloaded,immediatelyafterthecalltovl-load-com.Thesecallswillbeplacedbeforeanydefunintheprogramfile.Asaresult,theyareexecutedassoonasthefileisloaded.

Pleasesendusyourcommentaboutthispage

Page 71: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

ConstructinganArrayofPolylinePoints

Thelastissuetodealwithishowtotransformtheindividualpointvariables—p1,p2,p3,andp4—intotheformatrequiredforthevla-addLightweightpolylinefunction.First,getsomehelponthetopic.

Toobtaininformationonafunction

1. ChoosetheHelpbuttonontheVLISPtoolbar.

2. Entervla-addLightweightpolylineintheEnterItemNamedialogbox,andchooseOK.(TheHelpsystemisnotcasesensitive,sodonotworryabouthowyoucapitalizethefunctionname.)

HelpstatesthatAddLightWeightPolylinerequiresyoutospecifythepolylineverticesasanarrayofdoublesintheformofavariant.HereishowHelpdescribesthisparameter:

Thearrayof2DWCScoordinatesspecifyingtheverticesofthepolyline.Atleasttwopoints(fourelements)arerequiredforconstructingalightweightpolyline.Thearraysizemustbeamultipleof2.

AvariantisanActiveXconstructthatservesasacontainerforvarioustypesofdata.Strings,integers,andarrayscanallberepresentedbyvariants.Thevariantstoresdataalongwiththeinformationidentifyingthedata.

Sofar,youhavefourpoints,eachintheformat(x,y,z).Thechallengeistoconvertthesefourpointsintoalistofthefollowingform:

(x1y1x2y2x3y3x4y4)

Theappendfunctiontakesmultiplelistsandconcatenatesthem.TocreatealistofthefourpointsintheproperformatfortheActiveXfunction,youcanusethefollowingexpression:

Page 72: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setqpolypoints(append(3dPoint->2dPointp1)

(3dPoint->2dPointp2)

(3dPoint->2dPointp3)

(3dPoint->2dPointp4)))

Writingthe3dPoint->2dPointfunctionfourtimesisabitcumbersome.Youcanreducethecodefurtherbyusingthemapcarandapplyfunctions.Whenselected,mapcarexecutesafunctiononindividualelementsinoneormorelists,andapplypassesalistofargumentstothespecifiedfunction.Theresultingcodelookslikethefollowing:

(setqpolypoints(apply'append(mapcar'3dPoint->2dPoint

(listp1p2p3p4))))

Beforethecalltomapcar,thelistofpointsisinthisform:

((x1y1z1)(x2y2z2)(x3y3z3)(x4y4z4))

Aftermapcaryouhavealistofpointsinthefollowingform:

((x1y1)(x2y2)(x3y3)(x4y4))

Andfinally,afterapplyingtheappendfunctiononthelistreturnedfrommapcar,youendupwiththefollowing:

(x1y1x2y2x3y3x4y4)

Pleasesendusyourcommentaboutthispage

Page 73: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

ConstructingaVariantfromaListofPoints

Sofar,thedatainthepolypointsvariableisinalistformatsuitableformanyAutoLISPcalls.However,thedataistobesuppliedasaninputparametertoanActiveXcallthatexpectsavariantarrayofdoubles.Youcanuseanotherutilityfunctiontomaketherequiredconversionfromlisttovariant:

(defungp:list->variantArray(ptsList/arraySpacesArray)

;allocatespaceforanarrayof2dpointsstoredasdoubles

(setqarraySpace(vlax-make-safearray

vlax-vbdouble;elementtype

(cons0

(-(lengthptsList)1)

);arraydimension

)

)

(setqsArray(vlax-safearray-fillarraySpaceptsList))

;returnarrayvariant

(vlax-make-variantsArray)

)

Thefollowingactionstakeplaceingp:list->variantArray:

Thevlax-make-safearrayfunctioniscalledtoallocateanarrayofdoubles(vlax-vbdouble).Thevlax-make-safearrayfunctionalsorequiresyoutospecifythelowerandupperindexboundariesofthearray.Ingp:list->variantArray,thecalltovlax-make-safearrayspecifiesastartindexof0andsetstheupperlimittoonelessthanthenumberofelementspassedtoit(ptsList).

Thevlax-safearray-fillfunctioniscalledtopopulatethearraywiththeelementsinthepointlist.

Thevlax-make-variantiscalledtoconvertthesafearrayintoavariant.Asthelastfunctioncallingp:list->variantArray,the

Page 74: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

returnvalueispassedtothecallingfunction.

Thefollowingisanexampleofafunctioncallthatinvokesgp:list->variantArraytoconvertalisttoavariantarrayofdoubles:

;dataconversionfromlisttovariant

(setqVLADataPts(gp:list->variantArraypolypoints))

Pleasesendusyourcommentaboutthispage

Page 75: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>EnablingtheBoundaryOutlineDrawingFunction>

PuttingItAllTogether

Younowhaveallthecodeyouneedtodrawtheoutlineofthegardenpath.

Toupdateyourcode

1. Replaceyouroldcodeforthegp:drawOutlinefunctionwiththefollowing:

;;;---------------------------------------------------------------

;;;Function:gp:drawOutline

;;;---------------------------------------------------------------

;;;Description:Thisfunctionwilldrawtheoutlineofthegarden

;;;path.

;;;---------------------------------------------------------------

;;;Note:Noerrorcheckingorvalidationisperformedonthe

;;;BoundaryDataparameter.Thesequenceofitemswithinthis

;;;parameterdoesnotmatter,butitisassumedthatallsublists

;;;arepresentandcontainvaliddata.

;;;--------------------------------------------------------------

(defungp:drawOutline(BoundaryData/VLADataPtsPathAngle

WidthHalfWidthStartPtPathLength

angm90angp90p1p2

p3p4polypointspline

)

;;extractthevaluesfromthelistBoundaryData

(setqPathAngle(cdr(assoc50BoundaryData))

Width(cdr(assoc40BoundaryData))

HalfWidth(/Width2.00)

StartPt(cdr(assoc10BoundaryData))

PathLength(cdr(assoc41BoundaryData))

angp90(+PathAngle(Degrees->Radians90))

angm90(-PathAngle(Degrees->Radians90))

p1(polarStartPtangm90HalfWidth)

p2(polarp1PathAnglePathLength)

p3(polarp2angp90Width)

p4(polarp3(+PathAngle(Degrees->Radians180))PathLength)

polypoints(apply'append

Page 76: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(mapcar'3dPoint->2dPoint(listp1p2p3p4))

)

)

;;*****dataconversion*****

;;Notice,polypointsisinAutoLISPformat,consistingofalist

;;ofthe4cornerpointsforthegardenpath.

;;Thevariableneedstobeconvertedtoaformofinputparameter

;;acceptabletoActiveXcalls.

(setqVLADataPts(gp:list->variantArraypolypoints))

;;AddpolylinetothemodelspaceusingActiveXautomation.

(setq pline(vla-addLightweightPolyline

*ModelSpace*;GlobalDefinitionforModelSpace

VLADataPts

);_endofvla-addLightweightPolyline

);_endofsetq

(vla-put-closedplineT)

;;ReturntheActiveXobjectnamefortheoutlinepolyline

;;Thereturnvalueshouldlooksomethinglikethis:

;;#<VLA-OBJECTIAcadLWPolyline02351a34>

pline

);_endofdefun

Notethatgp:drawOutlinenowreturnsthevariablepline,notthequotedsymbol'SomeEnameusedinthestubbed-outversionofthefunction.

2. FormatthecodeyoujustenteredbyselectingitandchoosingtheFormatSelectionbuttonontheVLISPtoolbar.

3. EnableActiveXandaddtheglobalvariableassignmentforthepointertomodelspace,asdescribedearlier.Scrolltothetopofthetexteditorwindowandaddthefollowingcodebeforethefirstdefun:

;;;--------------------------------------------------------------

;;;FirststepistoloadActiveXfunctionality.IfActiveXsupport

;;;alreadyexistsindocument(canoccurwhenBonustoolshavebeen

;;;loadedintoAutoCAD),nothinghappens.Otherwise,ActiveX

;;;supportisloaded.

;;;---------------------------------------------------------------

(vl-load-com)

;;;InLesson4,thefollowingcommentandcodeismovedtoutils.lsp

;;;---------------------------------------------------------------

;;;ForActiveXfunctions,weneedtodefineaglobalvariablethat

;;;"points"totheModelSpaceportionoftheactivedrawing.This

;;;variable,named*ModelSpace*willbecreatedatloadtime.

;;;---------------------------------------------------------------

(setq*ModelSpace*

(vla-get-ModelSpace

Page 77: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(vla-get-ActiveDocument(vlax-get-acad-object))

);_endofvla-get-ModelSpace

);_endofsetq

Notehowtheabovecodelivesoutsideofanydefun.Becauseofthis,VLISPautomaticallyexecutesthecodeatthetimeyouloadthefile.

4. LookforthefollowinglineintheC:GPathfunction:

(setqPolylineName(gp:drawOutline))

Changeittothefollowing:

(setqPolylineName(gp:drawOutlinegp_PathData))

Thegp:drawOutlinefunctionisnowexpectingaparameter—thelistcontainingthepolylineboundarydata—andthischangefulfillsthatrequirement.

5. Addthegp:list->variantArrayfunctionshowninConstructingaVariantfromaListofPointstotheendofgpmain.lsp.Tryloadingandrunningtherevisedprogram.VLISPtakescontrolawayfromAutoCADbeforeyouseetheendresult,soswitchbacktotheAutoCADwindowaftercontrolreturnstoVLISP.Iftheprogramrancorrectly,youshouldseeaborderforthegardenpath.Ifyoufinderrors,debugthecodeandtryagain.

Pleasesendusyourcommentaboutthispage

Page 78: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingthePathBoundary>

WrappingUpLesson3

Inthislesson,you

Wroteutilityfunctionsthatcanbereusedinotherapplications.

Addedentitycreationlogictoyourprogram.

LearnedhowtouseActiveXfunctions.

Learnedhowtoworkwithassociationlists.

Enabledyourprogramtodrawagardenpathborder.

Ifyou'reconfusedaboutanythingfromthislesson,itisrecommendedyougothroughitonceagainbeforemovingontoLesson4.(Ifyoudecidetodoso,copythecompletedcodefromyourLesson2directorysothatyoustartthelessonfromthecorrectplace.)Andifallelsefails,youcanalwayscopythecodefromtheTutorial\VisualLISP\Lesson3directory.

Pleasesendusyourcommentaboutthispage

Page 79: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface

Inthislesson,youwillaccomplishtwomajortasks:creatingaVisualLISP®projectandaddingadialog-basedinterfacetoyourapplication.Intheprocess,youwillsplitthesingleAutoLISP®fileyouworkedwithsofar(gpmain.lsp)intoseveralsmallerfiles,reinforcingtheconceptofcodemodularity.

Fromthislessonon,thetutorialprovidesmoregeneraldescriptionsofthetasksyouneedtoperform,unlessnewtopicsarecovered.Also,thecodefragmentswillbeminimallydocumentedtosavespace.

Topicsinthissection

ModularizingYourCodeUsingVisualLISPProjectsAddingtheDialogBoxInterfaceInteractingwiththeDialogBoxfromAutoLISPCodeProvidingaChoiceofBoundaryLineTypeCleaningUpRunningtheApplicationWrappingUpLesson4

Pleasesendusyourcommentaboutthispage

Page 80: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

ModularizingYourCode

AsaresultoftheworkyoudidinLesson3,yourgpmain.lspfilewasgettingratherlarge.ThisisnotaproblemforVLISP,butitiseasiertomaintainthecodeifyousplitthingsupintofilescontaininglogicallyrelatedfunctions.It'salsoeasiertodebugyourcode.Forexample,ifyouhaveasinglefilewith150functions,asinglemissingparenthesiscanbedifficulttofind.

Inthetutorial,thefileswillbeorganizedasfollows:

Tutorialfileorganization

Filename Contents

gp-io.lsp Allinputandoutput(I/O)functions)suchasgettinguserinput.AlsocontainstheAutoLISPcoderequiredforthedialogboxinterfaceyouwillbeadding.

utils.lsp Includesallgenericfunctionsthatcanbeusedagainonotherprojects.Alsocontainsload-timeinitializations.

gpdraw.lsp Alldrawingroutines—thecodethatactuallycreatestheAutoCADentities.

gpmain.lsp ThebasicC:GPathfunction.

Page 81: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Tosplitgpmain.lspintofourfiles

1. Createanewfile,thencutandpastethefollowingfunctionsfromgpmain.lspintothenewfile:

gp:getPointInput

gp:getDialogInput

Savethenewfileinyourworkingdirectoryasgp-io.lsp.

2. Createanewfile,thencutandpastethefollowingfunctionsfromgpmain.lspintothenewfile:

Degrees->Radians

3Dpoint->2Dpoint

gp:list->variantArray

Also,atthebeginningofthefile,insertthelinesofcodetoestablishActiveXfunctionality(vl-load-com)andcommitglobalvariableassignment(*ModelSpace*).Savethefileasutils.lsp.

3. Createanewfile,thencutandpastethefollowingfunctionfromgpmain.lspintothenewfile:

gp:drawOutline

Savethisfileasgpdraw.lsp.

4. Afterstrippingthecodeoutofgpmain.lsp,saveitandcheckit.Onlytheoriginalfunction,C:GPath,shouldremaininthefile.

YourVLISPdesktopisstartingtogetcrowded.YoucanminimizeanywindowwithinVLISPanditstaysaccessible.ChoosetheSelectWindowbuttononthetoolbartochooseawindowfromalist,orchooseWindowfromtheVLISPmenuandselectawindowtoview.

Pleasesendusyourcommentaboutthispage

Page 82: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

UsingVisualLISPProjects

TheVLISPprojectfeatureprovidesaconvenientwaytomanagethefilesthatmakeupyourapplication.Andwiththeprojectfeature,youcanopenasingleprojectfileinsteadofindividuallyopeningeveryLISPfileintheapplication.Oncetheprojectisopen,gettingtoitsconstituentfilesisadouble-clickaway.

TocreateaVLISPproject

1. ChooseProject NewProjectfromtheVLISPmenu.

2. SavethefileinyourLesson4directory,usingthenamegpath.prj.Afteryousavethefile,VLISPdisplaystheProjectPropertiesdialogbox.

3. Choosethe[Un]SelectAllbuttonontheleftintheProjectPropertiesdialogbox.

4. Choosethebuttoncontaininganarrowpointingtotheright.Thisaddsalltheselectedfilestoyourproject.

IntheProjectPropertiesdialogbox,thelistboxontheleftshowsallLISPfilesthatresideinthesamedirectoryasyourprojectfileandarenotincludedinthatproject.Thelistboxontherightlistsallthefilesthatmakeuptheproject.Whenyouaddtheselectedfilestotheproject,thosefilenamesmovefromtheleftboxtotherightbox.

5. Inthelistboxontherightsideofthedialogbox,selectgpmain,thenchoosetheBottombutton.Thismovesthefiletothebottomofthelist.VLISPloadsprojectfilesintheordertheyarelisted.Becausethepromptthattellsusersthenameofthecommandislocatedattheendofthegpmain.lspfile,youneedtomovethisfiletothebottomofthelist.

Page 83: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Loadingthisfilelastresultsinthepromptdisplayedtousers.Theutils.lspfileshouldbeloadedfirstbecauseitcontainsinitializationcodefortheapplication.Therefore,selectutilsinthedialog'slistboxandchoosetheTopbutton.

6. ChooseOK.

VLISPaddsasmallprojectwindowtoyourVLISPdesktop.Thewindowliststhefilesinyourproject.Double-clickonanyfiletoopenthefileintheVLISPtexteditor(ifitisnotalreadyopen)andmakeittheactiveeditorwindow.

Pleasesendusyourcommentaboutthispage

Page 84: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

AddingtheDialogBoxInterface

Thenextpartofthislessonconcernsaddingadialogboxinterfacetothegardenpathapplication.Todothis,youwillbeworkingwithanotherlanguage,dialogcontrollanguage(DCL).

Currently,yourgpathfunctiononlyacceptsinputonthecommandline.Youincludedastubbed-outfunction(gp:getDialogInput)withtheintentionofaddingadialogboxinterface.Nowisthetimetoaddtheinterface.

Therearetwostepsincreatingafunctionaldialoginterface:

Definetheappearanceandcontentsofthedialogboxes.

Addprogramcodetocontroldialogbehavior.

Thedescriptionandformatofadialogboxisdefinedina.dclfile.IntheAutoLISPDeveloper'sGuide,DCLisdescribedinchapter11,“DesigningDialogBoxes”chapter12,“ManagingDialogBoxes”,andchapter13,“ProgrammableDialogBoxReference”.

Programcodethatinitializesdefaultsettingsandrespondstouserinteractionwillbeaddedtogp:getDialogInput.

Topicsinthissection

DefiningtheDialogBoxwithDCLSavingaDCLFilePreviewingaDialogBox

Pleasesendusyourcommentaboutthispage

Page 85: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>AddingtheDialogBoxInterface>

DefiningtheDialogBoxwithDCL

Beginbytakingalookatthedialogboxyouneedtocreate.

Thedialogboxcontainsthefollowingelements:

Twosetsofradiobuttons.Onesetofbuttonsdeterminesthepolylinestyleoftheboundary,andtheothersetofbuttonsspecifiesthetileentitycreationmethod(ActiveX,entmake,orcommand).Onlyoneradiobuttoninasetcanbeselectedatonetime.

Editboxesforspecifyingtheradiusoftilesandthespacingbetweentiles.

AstandardsetofOKandCancelbuttons.

DialogboxcomponentsarereferredtoastilesinDCL.WritingthecompletecontentsofadialogboxDCLfilemayseemoverwhelming.Thetrickistosketchoutwhatyouwant,breakitdownintosections,thenwriteeachsection.

Page 86: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Todefinethedialogbox

1. OpenanewfileintheVLISPtexteditorwindow.

2. Enterthefollowingstatementinthenewfile:

label="GardenPathTileSpecifications";

ThisDCLstatementdefinesthetitleofthedialogboxwindow.

3. Definetheradiobuttonsforspecifyingpolylinetypebyaddingthefollowingcode:

:boxed_radio_column{//definestheradiobuttonareas

label="OutlinePolylineType";

:radio_button{//definesthelightweightradiobutton

label="&Lightweight";

key="gp_lw";

value="1";

}

:radio_button{//definestheold-stylepolylineradiobutton

label="&Old-style";

key="gp_hw";

}

}

Theboxed_radio_columnDCLdirectivedefinesaboxboundaryandallowsyoutospecifyalabelforthesetofbuttons.Withintheboundary,youspecifytheradiobuttonsyouneedbyaddingradio_buttondirectives.Eachradiobuttonrequiresalabelandakey.ThekeyisthenamebywhichyourAutoLISPcodecanrefertothebutton.Noticethattheradiobuttonlabeled“lightweight”isgivenavalueof1.Avalueof1(astring,notaninteger)assignedtoabuttonmakesitthedefaultchoiceinarowofbuttons.Inotherwords,whenyoufirstdisplaythedialog,thisbuttonwillbeselected.AlsonoticethatinDCLfiles,double-slashcharacters,notsemicolonsasinAutoLISP,indicateacomment.

4. Definetheradiocolumnfortheselectionoftheentitycreationstylebyaddingthefollowingcode:

:boxed_radio_column{//definestheradiobuttonareas

label="TileCreationMethod";

Page 87: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

:radio_button{//definestheActiveXradiobutton

label="&ActiveXAutomation";

key="gp_actx";

value="1";

}

:radio_button{//definesthe(entmake)radiobutton

label="&Entmake";

key="gp_emake";

}

:radio_button{//definesthe(command)radiobutton

label="&Command";

key="gp_cmd";

}

}

5. Addthefollowingcodetodefinetheeditboxtilesthatallowuserstoenterthenumbersspecifyingtilesizeandspacing:

:edit_box{//definestheRadiusofTileeditbox

label="&Radiusoftile";

key="gp_trad";

edit_width=6;

}

:edit_box{//definestheSpacingBetweenTileseditbox

label="S&pacingbetweentiles";

key="gp_spac";

edit_width=6;

}

Noticethatthisdefinitiondoesnotsetanyinitialvaluesfortheeditboxes.YouwillsetdefaultvaluesforeacheditboxinyourAutoLISPprogram.

6. AddthefollowingcodefortheOKandCancelbuttons:

:row{//definestheOK/Cancelbuttonrow

:spacer{width=1;}

:button{//definestheOKbutton

label="OK";

is_default=true;

key="accept";

width=8;

fixed_width=true;

}

:button{//definestheCancelbutton

label="Cancel";

is_cancel=true;

key="cancel";

Page 88: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

width=8;

fixed_width=true;

}

:spacer{width=1;}

}

Bothbuttonsaredefinedwithinarow,sotheylineuphorizontally.

7. ScrolltothebeginningofthetexteditorwindowandinsertthefollowingstatementasthefirstlineinyourDCL:

gp_mainDialog:dialog{

8. Thedialogdirectiverequiresaclosingbrace,soscrolltotheendofthefileandaddthebraceasthelastlineofDCLcode:

}

Pleasesendusyourcommentaboutthispage

Page 89: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>AddingtheDialogBoxInterface>

SavingaDCLFile

BeforesavingthefilecontainingyourDCL,considerthefactthatAutoCAD®

mustbeabletolocateyourDCLfileduringruntime.Forthisreason,thefilemustbeplacedinoneoftheAutoCADSupportFileSearchPathlocations.(Ifyouareunsureabouttheselocations,chooseTools OptionsfromtheAutoCADmenuandexaminetheSupportFileSearchPathlocationsundertheFilestab.)

Fornow,youcansavethefileintheAutoCADSupportdirectory.

TosaveyourDCLfile

1. ChooseFile SaveAsfromtheVLISPmenu.

2. IntheSaveAsTypefieldoftheSaveAsdialogbox,chooseDCLSourceFilesfromthepull-downmenu.

3. ChangetheSaveInpathto<AutoCADdirectory>\Support.

4. Enterthefilenamegpdialog.dcl.

5. ChooseSave.

NoticeVLISPchangesthesyntaxcoloringschemeafteryousavethefile.VLISPisdesignedtorecognizeDCLfilesandhighlightthedifferenttypesofsyntacticalelements.

Pleasesendusyourcommentaboutthispage

Page 90: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>AddingtheDialogBoxInterface>

PreviewingaDialogBox

VLISPprovidesapreviewfeatureforcheckingtheresultsofyourDCLcoding.

TopreviewadialogboxdefinedwithDCL

1. ChooseTools InterfaceTools PreviewDCLinEditorfromtheVLISPmenu.

2. ChooseOKwhenpromptedtospecifyadialogname.Inthiscase,yourDCLfiledefinesjustasingledialogbox,sothereisnochoicetobemade.Asyoucreatelargerandmorerobustapplications,however,youmayendupwithDCLfilescontainingmultipledialogboxes.Thisiswhereyoucanselectwhichonetopreview.

3. Ifthedialogboxdisplayssuccessfully,chooseanybuttontoendthedialog.

VLISPpassescontroltoAutoCADtodisplaythedialogbox.IfAutoCADfindssyntacticalerrors,itdisplaysoneormoremessagewindowsidentifyingtheerrors.

IfAutoCADdetectsDCLerrorsandyouareunabletofigureouthowtofixthem,copythegpdialog.dclfileinyourTutorial\VisualLISP\Lesson4directoryandsaveitintheSupportdirectory.

Pleasesendusyourcommentaboutthispage

Page 91: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

InteractingwiththeDialogBoxfromAutoLISPCode

YounowneedtoprogramyourAutoLISPfunctiontointeractwiththedialogbox.Thestubbed-outfunction,gp:getDialogInput,iswherethisactivitywilltakeplace.Thisfunctionnowlivesinthegp-io.lspfile,whichyouearlierextractedfromgpmain.lsp.

Developingadialogboxinterfacecanbeconfusingthefirstfewtimesyoudoit.Itinvolvesplanningaheadandaskingyourselfsuchquestionsas:

Doesthedialogboxneedtobesetupwithdefaultvalues?

Whathappenswhentheuserchoosesabuttonorentersavalue?

WhathappenswhentheuserchoosesCancel?

Ifthedialog(.dcl)fileismissing,whatneedstooccur?

Topicsinthissection

SettingUpDialogValuesLoadingtheDialogFileLoadingaSpecificDialogintoMemoryInitializingtheDefaultDialogValuesAssigningActionstoTilesStartingtheDialogUnloadingtheDialogDeterminingWhattoDoNextPuttingtheCodeTogetherUpdatingaStubbed-OutFunction

Page 92: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 93: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

SettingUpDialogValues

Whenyourunthecompletegardenpathapplication,noticethatthedialogboxalwaysstartsupwithActiveXasthedefaultobjectcreationmethodandLightweightasthepolylinestyle.Somethingmoreinterestingoccurswiththedefaulttilesize—thevalueschangedependingonthewidthofthepath.Thefollowingcodefragmentshowshowtosetupthedefaultvaluestobedisplayedinthedialogbox:

(setqobjectCreateMethod"ACTIVEX"

plineStyle"LIGHT"

tilerad(/pathWidth15.0)

tilespace(/tilerad5.0)

dialogLoadedT

dialogShowT

);_endofsetq

Forthemoment,don'tworryaboutwhatpurposethedialogLoadedanddialogShowvariablesserve.Thisbecomesapparentinthenexttwosections.

Pleasesendusyourcommentaboutthispage

Page 94: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

LoadingtheDialogFile

YourprogramfirstneedstoloadtheDCLfileusingtheload_dialogfunction.ThisfunctionsearchesfordialogfilesaccordingtotheAutoCADsupportfilesearchpath,unlessyouspecifyafullpathname.

Foreveryload_dialogfunctionthereshouldbeacorrespondingunload_dialogfunctionlaterinthecode.Youwillseethisinamoment.Fornow,takealookathowyouneedtoloadinyourdialog:

;;Loadthedialogbox.Setuperrorcheckingtomakesure

;;thedialogfileisloadedbeforecontinuing

(if(=-1(setqdcl_id(load_dialog"gpdialog.dcl")))

(progn

;;There'saproblem-displayamessageandsetthe

;;dialogLoadedflagtonil

(princ"\nCannotloadgpdialog.dcl")

(setqdialogLoadednil)

);_endofprogn

);_endofif

ThedialogLoadedvariableindicatesifthedialogloadedsuccessfully.Inthecodewhereyousetuptheinitialvaluesforthedialogbox,yousetdialogLoadedtoaninitialvalueofT.Asyoucanseeinthecodefragmentabove,dialogLoadedissettonilifthereisaproblemwiththeload.

Pleasesendusyourcommentaboutthispage

Page 95: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

LoadingaSpecificDialogintoMemory

ItwasnotedearlierthatasingleDCLfilemaycontainmultipledialogboxdefinitions.Thenextstepinusingadialogistospecifywhichdialogboxdefinitiontodisplay.Thefollowingcodedemonstratesthis:

(if(anddialogLoaded

(not(new_dialog"gp_mainDialog"dcl_id))

);_endofand

(progn

;;There'saproblem...

(princ"\nCannotshowdialoggp_mainDialog")

(setqdialogShownil)

);_endofprogn

);_endofif

Noticehowtheandfunctionisusedtotestifthedialogwasloadedandifthecalltonew_dialogwassuccessful.Iftherearemultipleexpressionsevaluatedwithinanandfunctioncall,evaluationofsubsequentexpressionsisterminatedwiththefirstexpressionthatevaluatestonil.Inthiscase,ifthedialogLoadedflagisnil(meaningtheloadfunctionintheprevioussectionfailed),VLISPdoesnotattempttoperformthenew_dialogfunction.

NoticethatthecodealsoaccountsforthepossibilitythatsomethingmightnotbeworkingproperlywiththeDCLfile,andsetsthedialogShowvariabletonilifthatisthecase.

Thenew_dialogfunctionsimplyloadsthedialogintomemory—itdoesnotdisplayit.Thestart_dialogfunctiondisplaysthedialogbox.Alldialogboxinitialization,suchassettingtilevalues,creatingimagesorlistsforlistboxes,andassociatingactionswithspecifictilesmusttakeplaceafterthenew_dialogcallandbeforethestart_dialogcall.

Page 96: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 97: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

InitializingtheDefaultDialogValues

Ifeverythingworkedsuccessfullyinloadingthedialog,youarereadytostartsettingupthevaluesthatwillbedisplayedtousers.AsuccessfulloadisindicatediftheflagvariablesdialogLoadedanddialogShowarebothT(true).

Nowsettheinitialvaluesforthetileradiusandspacing.Theset_tilefunctionassignsavaluetoatile.Aneditboxdealswithstringsratherthannumbers,soyouneedtousethertos(convertRealTOString)functiontoconvertyourtilesizevariablevaluesintostringsindecimalformatwithaprecisionoftwodigits.Thefollowingcodehandlesthisconversion:

(if(anddialogLoadeddialogShow)

(progn

;;Settheinitialstateofthetiles

(set_tile"gp_trad"(rtostileRad22))

(set_tile"gp_spac"(rtostileSpace22))

Pleasesendusyourcommentaboutthispage

Page 98: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

AssigningActionstoTiles

ADCLdefinitiondoesnothingmorethandefinealifelessdialogbox.YouconnectthislifelessdialogboxtoyourdynamicAutoLISPcodewiththeaction_tilefunction,asdemonstratedbythefollowingcode:

;;Assignactions(thefunctionstobeinvoked)todialogbuttons

(action_tile

"gp_lw"

"(setqplineStyle\"Light\")"

)

(action_tile

"gp_hw"

"(setqplineStyle\"Pline\")"

)

(action_tile

"gp_actx"

"(setqobjectCreateMethod\"ActiveX\")"

)

(action_tile

"gp_emake"

"(setqobjectCreateMethod\"Entmake\")"

)

(action_tile

"gp_cmd"

"(setqobjectCreateMethod\"Command\")"

)

(action_tile"cancel""(done_dialog)(setqUserClicknil)")

(action_tile

"accept"

(strcat"(progn(setqtileRad(atof(get_tile\"gp_trad\")))"

"(setqtileSpace(atof(get_tile\"gp_spac\")))"

"(done_dialog)(setqUserClickT))"

)

)

NoticeallthequotesaroundtheAutoLISPcode.WhenyouwriteanAutoLISPaction_tilefunction,yourcodeisessentiallytellingatile,“here,remember

Page 99: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

thisstring,thenpassitbacktomewhentheuserselectsyou.”Thestring(anythingwithindouble-quotationmarks)isdormantuntiltheuserselectsthetile.Atthattime,thetilepassesthestringtoAutoCAD,whichconvertsthestringintofunctioningAutoLISPcodeandexecutesthecode.

Forexample,considerthefollowingaction_tileexpression,whichisconnectedtothelightweightpolylineradiobutton:

(action_tile

"gp_lw"

"(setqplineStyle\"Light\")"

)

Thecodeassignsthestring"(setqplineStyle\"Light\")"totheradiobutton.Whenauserpicksthebutton,thestringispassedbacktoAutoCADandtransformeddirectlyintothefollowingAutoLISPexpression:

(setqplineStyle"Light")

Lookatonemorecodefragment.Thefollowingistheaction_tileexpressionassignedtotheOKbutton:

(action_tile

"accept"

(strcat"(progn(setqtileRad(atof(get_tile\"gp_trad\")))"

"(setqtileSpace(atof(get_tile\"gp_spac\")))"

"(done_dialog)(setqUserClickT))"

)

WhenauserchoosestheOKbutton,thelengthystringassignedtothebuttonispassedtoAutoCADandturnedintothefollowingAutoLISPcode:

(progn

(setqtileRad(atof(get_tile"gp_trad")))

(setqtileSpace(atof(get_tile"gp_spac")))

(done_dialog)

(setqUserClickT)

)

Thiscodedoesseveralthings:Itretrievesthecurrentvaluesfromthetileswhosekeyvaluesaregp_trad(thetileradius)andgp_spac(thetilespacingvalue).Thenatofconvertsthenumberstringintoarealnumber.Thedialogisterminatedwiththedone_dialogfunction,andavalueofT,ortrue,is

Page 100: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

assignedtothevariableUserClick.

You'redoneassigningactionstothebuttons.Thenextthingtodoistoputitallinmotion.

Pleasesendusyourcommentaboutthispage

Page 101: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

StartingtheDialog

Thestart_dialogfunctiondisplaysadialogboxandacceptsuserinput.Thestart_dialogfunctionrequiresnoarguments.

(start_dialog)

Controlpassestouserswhenyouissuestart_dialog.Userscanmakechoiceswithinthedialogbox,untiltheychoosetheOKorCancelbuttons.

Pleasesendusyourcommentaboutthispage

Page 102: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

UnloadingtheDialog

WhenauserchoosestheOKorCancelbutton,youneedtounloadthedialog.Likestart_dialog,unload_dialogisanothersimplefunction.

(unload_dialogdcl_id)

Pleasesendusyourcommentaboutthispage

Page 103: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

DeterminingWhattoDoNext

IftheuserchoseOK,youmustbuildalistcontainingthevaluessetbytheuser'sinteractionwiththedialog.Thislistiswhatgp:getDialogInputwillreturntoitscallingfunction.IftheuserchoseCancel,thefunctionreturnsnil:

(ifUserClick;UserclickedOk

;;Buildtheresultingdata

(progn

(setqResult(list

(cons42tileRad)

(cons43TileSpace)

(cons3objectCreateMethod)

(cons4plineStyle)

)

)

)

)

Pleasesendusyourcommentaboutthispage

Page 104: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

PuttingtheCodeTogether

Withtheexamplesabove,andafewadditionallines,youhavethecodeneededtocompletethegp:getDialogInputfunction.

Toputgp:getDialogInputtogether

1. Openyourcopyofgp-io.lspinaVLISPtexteditorwindow.

2. Deletethecodeingp:getDialogInput(thedefungp:getDialogInputstatementandeverythingafterit).

3. Enterthefollowingdefunstatementasthefirstlineofcodeinthegp:getDialogInputfunction:

(defungp:getDialogInput(pathWidth/dcl_idobjectCreateMethod

plineStyletileradtilespaceresultUserClick

dialogLoadeddialogShow)

Thefunctionexpectsasingleargument(pathwidth),andestablishesanumberoflocalvariables.

4. Followingthecodeyouaddedinstep3,enterthesamplecodefromeachofthefollowingsections:

SettingUpDialogValues

LoadingtheDialogFile

LoadingaSpecificDialogintoMemory

InitializingtheDefaultDialogValues

AssigningActionstoTilesNote EnterjustthefirstcodeexamplefromAssigningActionstoTiles

Page 105: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

notthefragmentsintheexplanationsthatfollow.Thosefragmentsjustrepeatpiecesoftheexample.

StartingtheDialog

UnloadingtheDialog

DeterminingWhattoDoNext

5. Afterthelastlineofcode,addthefollowing:

)

)

Result;

);_endofdefun

6. FormatthecodeyouenteredbychoosingTools FormatCodeinEditorfromtheVLISPmenu.

Pleasesendusyourcommentaboutthispage

Page 106: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>InteractingwiththeDialogBoxfromAutoLISPCode>

UpdatingaStubbed-OutFunction

Youhavenowrevisedthegp:getDialogInputfunction.Wheneveryoumodifyastubbed-outfunction,youshouldalwayscheckacoupleofthings:

Hasthedefunstatementchanged?Thatis,doesthefunctionstilltakethesamenumberofarguments?

Doesthefunctionreturnsomethingdifferent?

Inthecaseofgp:getDialogInput,theanswertobothquestionsisyes.Thefunctionnowacceptstheparameterofthepathwidth(tosetthedefaulttilesizeandspacing).AndinsteadofreturningT,whichisthevaluethestubbed-outversionofthefunctionreturned,gp:getDialogInputnowreturnsanassociationlistcontainingfournewvalues.

Bothchangesaffectthecodethatcallsthefunctionandthecodethathandlesthereturnvaluesfromthefunctions.ReplaceyourpreviousversionoftheC:GPathfunctioningpmain.lspwiththefollowingcode:

(defunC:GPath(/gp_PathDatagp_dialogResults)

;;Asktheuserforinput:firstforpathlocationand

;;direction,thenforpathparameters.Continueonlyifyou

;;havevalidinput.Storethedataingp_PathData.

(if(setqgp_PathData(gp:getPointInput))

(if(setqgp_dialogResults(gp:getDialogInput(cdr(assoc40

gp_PathData))))

(progn

;;Nowtaketheresultsofgp:getPointInputandappendthis

;;totheaddedinformationsuppliedbygp:getDialogInput.

(setqgp_PathData(appendgp_PathDatagp_DialogResults))

;;Atthispoint,youhavealltheinputfromtheuser.

;;Drawtheoutline,storingtheresultingpolyline

;;"pointer"inthevariablecalledPolylineName.

(setqPolylineName(gp:drawOutlinegp_PathData))

);_endofprogn

Page 107: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(princ"\nFunctioncancelled.")

);_endofif

(princ"\nIncompleteinformationtodrawaboundary.")

);_endofif

(princ);exitquietly

);_endofdefun

TakealookattheboldfacelinesintherevisionofthemainC:GPathfunction.Therearetwoessentialchangestomaketheprogramworkcorrectly:

Whenthegp:getDialogInputfunctionisinvoked,thepathwidthispassedtoit.Thisisdonebyextractingthevalueassociatedwiththekey40indexofthegp_PathDataassociationlist.

Theassociationlistreturnedbygp:getPointInputisassignedtoavariablecalledgp_dialogResults.Ifthisvariablehasavalue,itscontentneedstobeappendedtotheassociationlistvaluesalreadystoredingp_PathData.

Thereareadditionalchangesinthecoderesultingfromthereplacementofplaceholdersinthestubbed-outversion.Theeasiestthingtodoiscopythiscodefromtheonlinetutorialandpasteitintoyourfile.

Pleasesendusyourcommentaboutthispage

Page 108: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

ProvidingaChoiceofBoundaryLineType

Onerequirementspecifiedforthegardenpathapplicationwastoallowuserstodrawtheboundaryoutlineaseitheralightweightpolylineoranold-stylepolyline.Thefirstversionofgp:drawOutlineyouwrotealwaysusedalightweightpolylinetodrawtheboundary.Nowthatthedialogboxinterfaceisreadytogo,youcanbuildintheoptionfordrawinganold-stylepolylineaswell.Toaccomplishthis,gp:drawOutlinemustdeterminewhatkindofpolylinetodraw,andthenitmustdrawit.

Thenecessarychangestogp:drawOutlineareincludedinthefollowingcodefragment.Makethemodificationfromthegpdraw.lspfileindicatedinbold:

(setqPathAngle(cdr(assoc50BoundaryData))

Width(cdr(assoc40BoundaryData))

HalfWidth(/Width2.00)

StartPt(cdr(assoc10BoundaryData))

PathLength(cdr(assoc41BoundaryData))

angp90(+PathAngle(Degrees->Radians90))

angm90(-PathAngle(Degrees->Radians90))

p1(polarStartPtangm90HalfWidth)

p2(polarp1PathAnglePathLength)

p3(polarp2angp90Width)

p4(polarp3(+PathAngle(Degrees->Radians180))

PathLength)

poly2Dpoints(apply'append

(mapcar'3dPoint->2dPoint(listp1p2p3p4))

)

poly3Dpoints(mapcar'float(appendp1p2p3p4))

;;getthepolylinestyle

plineStyle(strcase(cdr(assoc4BoundaryData)))

);_endofsetq

;;AddpolylinetothemodelspaceusingActiveXautomation

(setqpline(if(=plineStyle"LIGHT")

;;createalightweightpolyline

(vla-addLightweightPolyline

*ModelSpace*;GlobalDefinitionforModelSpace

(gp:list->variantArraypoly2Dpoints);dataconversion

Page 109: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

);_endofvla-addLightweightPolyline

;;orcreateanold-stylepolyline

(vla-addPolyline

*ModelSpace*

(gp:list->variantArraypoly3Dpoints);dataconversion

);_endofvla-addPolyline

);_endofif

);_endofsetq

Typingthechangesintoyourcodecanbeverytricky,asyounotonlyneedtoaddcodebutalsotodeletesomeexistinglinesandrearrangeothers.Itisrecommendedyoucopytheentiresetqstatementfromtheonlinetutorialandpasteitintoyourcode.

Pleasesendusyourcommentaboutthispage

Page 110: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

CleaningUp

Ifyouhavenotdonesoalready,deletethefollowingcodefromtheC:GPathfunctioningpmain.lsp:

(princ"\nThegp:drawOutlinefunctionreturned<")

(princPolylineName)

(princ">")

(Alert"Congratulations-yourprogramiscomplete!")

Youhadbeenusingthiscodeasaplaceholder,butnowthatgp:drawOutlineisfunctioning,younolongerneedit.

Pleasesendusyourcommentaboutthispage

Page 111: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

RunningtheApplication

Beforerunningyourprogram,saveallthefilesyouchanged,ifyouhavenotalreadydoneso.YoucanchooseFile SaveAllfromtheVLISPmenu,orusetheALT+SHIFT+Skeyboardshortcuttosaveallyouropenfiles.

ThenextthingyoumustdoisreloadallthefilesinVLISP.

Toloadandrunallthefilesinyourapplication

1. Iftheprojectfileyoucreatedearlierinthislessonisnotalreadyopen,chooseProject OpenProjectfromtheVLISPmenu,thenentertheprojectfilenamegpath;donotincludethe.prjextension.IfVLISPdoesnotfindtheprojectfile,choosetheBrowsebuttonandchoosethefilefromtheOpenProjectdialogbox.ClickOpen.

2. ChoosetheLoadSourceFilesbuttonintheprojectwindow.

3. Enterthe(C:GPath)commandattheVLISPConsoleprompttoruntheprogram.Ifyouhavesomedebuggingtodo,tryusingthetoolsyoulearnedinLessons2and3.Andremember,ifallelsefails,youcanalwayscopythecodefromtheTutorial\VisualLISP\Lesson4directory.

Also,trydrawingthepathusingbothlightweightandold-stylepolylines.Afterdrawingthepaths,usetheAutoCADlistcommandtodeterminewhetherornotyourprogramisdrawingthecorrectentitytypes.

Pleasesendusyourcommentaboutthispage

Page 112: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

CreatingaProjectandAddingtheInterface>

WrappingUpLesson4

Inthislesson,you

Modularizedyourcodebydividingitamongfourfiles.

OrganizedyourcodemodulesinaVLISPproject.

Learnedtodefineadialogboxwithdialogcontrollanguage(DCL).

AddedAutoLISPcodetosetupandhandleinputinthedialogbox.

Modifiedyourcodetoprovideuserswithachoiceofboundarylinetype.

Nowyouhaveaprogramthatdrawsagardenpathboundary.Inthenextlesson,youwilladdthetilestothegardenpath.Intheprocess,youwillbeintroducedtomoreVLISPprogramdevelopmenttools.

Pleasesendusyourcommentaboutthispage

Page 113: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles

Bytheendofthislesson,yourapplicationwillmeetthebasicrequirementsstatedinLesson1.Youwilladdthefunctionalityfordrawingtileswithintheboundaryofthegardenpathandprovidethisfunctionusingseveraldifferentmethodsofentitycreation.Youwillalsolearnsomekeyboardshortcutsandneweditingtools.

Topicsinthissection

IntroducingMoreVisualLISPEditingToolsAddingTilestotheGardenPathTestingtheCodeWrappingUpLesson5

Pleasesendusyourcommentaboutthispage

Page 114: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>

IntroducingMoreVisualLISPEditingTools

Openyourcopyofgpdraw.lspinaVisualLISP®texteditorwindow,ifthefileisnotalreadyopen.ThereareacoupleofthingsaboutthiscodethataretypicalofmuchofthecodeyouwillbedevelopingwithVLISP.First,therearemanyparenthesesandparentheseswithinparentheses.Second,therearemanyfunctioncalls,andsomeofthosefunctionshaveverylongnames(vla-addLightweightPolyline,forexample).VLISPprovidessomeeditingtoolstohelpyoudealwiththesecommonfeaturesofAutoLISP®code.

Topicsinthissection

MatchingParenthesesCompletingaWordAutomaticallyCompletingaWordbyAproposGettingHelpwithaFunction

Pleasesendusyourcommentaboutthispage

Page 115: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>IntroducingMoreVisualLISPEditingTools>

MatchingParentheses

VLISPprovidesaparenthesismatchingfeaturetohelpyoufindthecloseparenthesisthatcorrespondstoanopenparenthesis.

Tomatchanopenparenthesiswithitscorrespondingcloseparenthesis

1. Placeyourcursorinfrontoftheopeningparenthesisthatprecedesthesetqfunctioncall.

2. PressCTRL+SHIFT+].(Double-clickingalsodoesthetrick.)

VLISPfindstheclosingparenthesisthatmatchestheoneyouchose,andselectsallthecodeinbetween.Notonlydoesthisensureyoutypedinthecorrectnumberofparentheses,italsomakesiteasytocopyorcuttheselectedtext.ThismighthavecomeinhandywhenyouupdatedthiscallattheendofLesson4.

Whyelsemightyouwanttodothis?YoucancopysomecodetotheVLISPConsolewindow,pasteitthere,andtryitout.Ormaybeyouhavefiguredouthowtoreplace50linesofcodewiththreereallymarvelouslinesofmuchbettercode.Youcanquicklyselecttheoldcodeusingtheparenthesesmatchingtool,theneliminateitwithasinglekeystroke.ItisalotquickertoletVLISPfindanentireblockthanforyoutohuntdowneverylastclosingparenthesis.

Thereisacorrespondingkeycommandformatchingandselectingbackward.Totrythis,putyourcursorafteraclosingparenthesis,theneitherdouble-clickorpressCTRL+SHIFT+[.VLISPsearchesforthecorrespondingopeningparenthesis,andselectsitalongwiththeenclosedcode.

BothcommandsarealsoavailablebychoosingEdit ParenthesesMatchingfromtheVLISPmenu.

Pleasesendusyourcommentaboutthispage

Page 116: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>IntroducingMoreVisualLISPEditingTools>

CompletingaWordAutomatically

Imagineyouareaddingsomenewfunctionalitytoyourprogramusingthefollowingcode:

ObjectCreationStyle(strcase(cdr(assoc3BoundaryData)))

(if(equalObjectCreationStyle"COMMAND")

(progn

(setqfirstCenterPt(polarrowCenterPt(Degrees->Radians45)distanceOnPath))

(gp:Create_activeX_Circle)

)

)

(Don'tworryaboutwhatthiscodeactuallydoes,ifanything.Itisonlyanexamplethatincludesseverallongvariableandfunctionnames.)

VLISPcansaveyousomekeystrokesbycompletingwordsforyou.

TousetheVisualLISPCompleteWordbyMatchfeature

1. Scrolltothebottomofthegpdraw.lspfileandenterthefollowingcode:

ObjectCreationStyle(strcase(cdr(assoc3BoundaryData)))

(if(equalOb

2. PressCTRL+SPACEBAR.VLISPjustsavedyouseventeenkeystrokesasitsearchedwithinthecurrentfileandfoundtheclosestmatchtothelasttwolettersyoutyped.

3. Completethelineofcodesothatitlookslikethefollowing:

(if(equalObjectCreationStyle"COMMAND")

4. Addthefollowinglines:

(progn

Page 117: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setqfirstCenterPt(p

5. PressCTRL+SPACEBAR.VLISPmatchesthemostrecent“p”word,whichhappenstobeprogn.However,thewordyouneedispolar.IfyoukeeppressingCTRL+SPACEBAR,VLISPcyclesthroughallthepossiblematchesinyourcode.Eventually,itwillcomearoundtopolar.

6. Deleteallthecodeyoujustentered;itwasfordemonstrationpurposesonly.TheCompleteWordbyMatchfeatureisalsoavailablefromtheVLISPSearchmenu.

Pleasesendusyourcommentaboutthispage

Page 118: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>IntroducingMoreVisualLISPEditingTools>

CompletingaWordbyApropos

IfyouhaveworkedwithAutoLISPbefore,youmayhavehadtotypeinanexpressionsimilartotheoneshownbelow:

(setqmyEnt(ssnamemySelectionSetssIndex))

Often,itisconfusingtokeeptrackofalltheselectionsetfunctions:ssname,ssget,sslength,andsoon.VLISPcanhelp,usingitsCompleteWordbyAproposfeature.

TousetheVisualLISPCompleteWordbyAproprosfeature

1. Scrolltothebottomofthegpdraw.lspfileandenterthefollowingonablankline:

(setqmyEnt(ent

2. PressCTRL+SHIFT+SPACEBAR.VLISPdisplaysalistofallAutoLISPsymbolsthatbeginwiththelettersent.Usethecursorkeys(theupanddownarrowkeys)tomovethroughthelist.SelectENTGET,thenpressENTER.VLISPreplacestheentyoutypedwithENTGET.

3. Deletethecode.

Pleasesendusyourcommentaboutthispage

Page 119: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>IntroducingMoreVisualLISPEditingTools>

GettingHelpwithaFunction

Thecodethataddsalightweightpolylinetothedrawingcallsafunctionnamedvla-addLightweightPolyline.Notonlyisthatalengthytermtowrite,butthereareseveralfunctionswhosenamesbeginwithvla-addthatyouwillusetocreateentities.Ratherthanconsultingamanualtolookupthefunctionnameeverytimeyoucreateaprogram,letVLISPhelp.

Togethelpwithusingafunction

1. Enterthefollowingonablankline:

(vla-add

2. PressCTRL+SHIFT+SPACEBAR.

3. Scrollthroughthelistuntilyoufindvla-addLightweightPolyline.

4. Double-clickonvla-addLightweightPolyline.VLISPdisplaystheSymbolServicedialogboxfortheselectedfunction.

5. ChoosetheHelpbuttonintheSymbolServicedialogbox.(ForActiveX®functions,youwillbedirectedtotheActiveXandVBAReference.)

6. Deletethechangesyoumadetogpdraw.lsp;thesewerefordemonstrationpurposesonly.Also,closetheSymbolServiceandAproposwindows.

Pleasesendusyourcommentaboutthispage

Page 120: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic
Page 121: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>

AddingTilestotheGardenPath

Younowhaveapathboundaryandarereadytofillitwithtiles.Youwillneedtoapplysomelogicandworkthroughalittlegeometry.

Topicsinthissection

ApplyingSomeLogicApplyingSomeGeometryDrawingtheRowsDrawingtheTilesinaRowLookingattheCode

Pleasesendusyourcommentaboutthispage

Page 122: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>AddingTilestotheGardenPath>

ApplyingSomeLogic

Onethingyouneedtodoisdeterminehowtospaceoutthetilesanddrawthem.Ifthiswereasimplerectilineargridoftiles,youcouldusetheAutoCAD®

ARRAYcommandtofillinthetiles.Butforthegardenpath,youneedtohaveeachrowoftilesoffsetfromthepreviousrow.

Thisrow-offsetpatternisarepeatingpattern.Thinkofhowyoumightgoaboutlayingthetilesifyouwerebuildingtheactualpath.Youwouldprobablybeinclinedtostartatoneendandjustkeeplayingdownrowsuntiltherewasn'tanymorespaceleft.

Hereisthelogicinpseudo-code:

Atthestartingpointofthepath

Figureouttheinitialrowoffsetfromcenter(eithercenteredon

thepathoroffsetbyone"tilespace").

Whilethespaceoftheboundaryfilledislessthanthespaceto

fill,

Drawarowoftiles.

Page 123: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Resetthenextstartpoint(incrementedbyone"tilespace").

Addthedistancefilledbythenewrowtotheamountofspace

filled.

Toggletheoffset(ifitiscentered,setitupoff-center,or

viceversa).

Gobacktothestartoftheloop.

Pleasesendusyourcommentaboutthispage

Page 124: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>AddingTilestotheGardenPath>

ApplyingSomeGeometry

Thereareonlyafewdimensionsyouneedtoknowtodrawthegardenpath.Thehalf-widthiseasy:itisjusthalfthewidthofthepath.Youalreadydefinedthecodetoobtainthiswidthfromusersandsaveditinanassociationlist.

Tilespacingisalsoeasy;itistwicetheradius(thatis,thediameter)plusthespacebetweenthetiles.Thedimensionsarealsoobtainedfromusers.

Rowspacingisalittletrickier,unlessyouarereallysharpwithtrigonometry.Hereistheformula:

RowSpacing=(TileDiameter+SpacebetweenTiles)*(thesine

of60degrees)

Pleasesendusyourcommentaboutthispage

Page 125: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>AddingTilestotheGardenPath>

DrawingtheRows

Seeifyoucanmakesenseofthefollowingfunction.Compareittothepseudo-codeandtrytocatchthegeometriccalculationsjustdescribed.TheremaybeafewAutoLISPfunctionsthatarenewtoyou.Ifyouneedhelpwiththesefunctions,refertotheAutoLISPReference.Fornow,justreadthecode;donotwriteanything.

(defungp:Calculate-and-Draw-Tiles(BoundaryData/PathLength

TileSpaceTileRadiusSpaceFilledSpaceToFill

RowSpacingoffsetFromCenter

rowStartPointpathWidthpathAngle

ObjectCreationStyleTileList)

(setqPathLength(cdr(assoc41BoundaryData))

TileSpace(cdr(assoc43BoundaryData))

TileRadius(cdr(assoc42BoundaryData))

SpaceToFill(-PathLengthTileRadius)

RowSpacing(*(+TileSpace(*TileRadius2.0))

(sin(Degrees->Radians60))

);_endof*

SpaceFilledRowSpacing

offsetFromCenter0.0

offsetDistance(/(+(*TileRadius2.0)TileSpace)2.0)

rowStartPoint(cdr(assoc10BoundaryData))

pathWidth(cdr(assoc40BoundaryData))

pathAngle(cdr(assoc50BoundaryData))

ObjectCreationStyle(strcase(cdr(assoc3BoundaryData)))

);_endofsetq

;;Compensateforthefirstcalltogp:calculate-Draw-tileRow

;;intheloopbelow.

(setqrowStartPoint

(polarrowStartPoint

(+pathAnglepi)

(/TileRadius2.0)

);_endofpolar

);_endofsetq

;;Draweachrowoftiles.

(while(<=SpaceFilledSpaceToFill)

;;Getthelistoftilescreated,addingthemtoourlist.

Page 126: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setqtileList(appendtileList

(gp:calculate-Draw-TileRow

(setqrowStartPoint

(polarrowStartPoint

pathAngle

RowSpacing

);_endofpolar

);_endofsetq

TileRadius

TileSpace

pathWidth

pathAngle

offsetFromCenter

ObjectCreationStyle

);_endofgp:calculate-Draw-TileRow

);_endofappend

;;Calculatethedistancealongthepathforthenextrow.

SpaceFilled(+SpaceFilledRowSpacing)

;;Alternatebetweenazeroandapositiveoffset

;;(causesalternaterowstobeindented).

offsetFromCenter

(if(=offsetFromCenter0.0)

offsetDistance

0.0

);_endofif

);_endofsetq

);_endofwhile

;;Returnthelistoftilescreated.

tileList

);_endofdefun

Acoupleofsectionsfromthecodemayneedalittleextraexplanation.

Thefollowingcodefragmentoccursrightbeforethewhileloopbegins:

;;Compensatefortheveryfirststartpoint!!

(setqrowStartPoint(polarrowStartPoint

(+pathAnglepi)(/TileRadius2.0)))

Therearethreepiecestothepuzzleoffiguringoutthelogicbehindthisalgorithm:

TherowStartPointvariablestartsitslifewithinthegp:Calculate-and-Draw-Tilesfunctionbybeingassignedthepointtheuserselectedasthestartpointofthepath.

Theveryfirstargumentpassedtothegp:calculate-Draw-TileRowfunctiondoesthefollowing:

Page 127: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setqrowStartPoint(polarrowStartPoint

pathAngleRowSpacing))

Anotherwayofstatingthisis:Atthetimethegp:calculate-Draw-TileRowfunctioniscalled,therowStartPointvariableissettooneRowSpacingdistancebeyondthecurrentrowStartPoint.

TherowStartPointargumentisusedwithingp:calculate-Draw-TileRowasthestartingpointforthecentersofthecirclesintherow.

TocompensatefortheinitialforwardshiftingoftherowStartPointduringthedrawingofthefirstrow(thatis,thefirstcyclethroughthewhileloop),youwillwanttoshiftrowStartPointslightlyintheoppositedirection.Theaimistoavoidtheappearanceofalargemarginofemptyspacebetweenthepathboundaryandthefirstrow.HalftheTileRadiusisasufficientamountbywhichtomovethepoint.ThiscanbeachievedbyusingpolartoprojectrowStartPointalongavectororiented180degreesfromthePathAngle.Ifyouthinkaboutit,thisplacesthepointtemporarilyoutsidethepathboundary.

Thenextfragment(modifiedforreadability)maybealittlepuzzling:

(setqtileList(appendtileList

(gp:calculate-Draw-TileRow

(setqrowStartPoint

(polarrowStartPointpathAngleRowSpacing)

);_endofsetq

TileRadiusTileSpacepathWidthpathAngle

offsetFromCenterObjectCreationStyle

)))

Inessence,thereissetqwrappedaroundanappendwrappedaroundthecalltogp:calculate-Draw-TileRow.

Thegp:calculate-Draw-TileRowfunctionwillreturntheObjectIDsforeachtiledrawn.(TheObjectIDpointstothetileobjectinthedrawing.)Youaredrawingthetilesrowbyrow,sothefunctionreturnstheObjectIDsofonerowatatime.TheappendfunctionaddsthenewObjectIDstoanyexistingObjectIDsstoredintileList.

Neartheendofthefunction,youcanfindthefollowingcodefragment:

(setqoffsetFromCenter

Page 128: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(if(=offsetFromCenter0.0)

offsetDistance

0.0

)

)

Thisistheoffsettoggle,whichdetermineswhethertherowbeingdrawnshouldbeginwithacirclecenteredonthepathoroffsetfromthepath.Thepseudo-codeforthisalgorithmfollows:

Settheoffsetamounttothefollowing:

Iftheoffsetiscurrentlyzero,setittotheoffsetdistance;

Otherwise,setitbacktozero.

Pleasesendusyourcommentaboutthispage

Page 129: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>AddingTilestotheGardenPath>

DrawingtheTilesinaRow

Nowthatyouhavethelogicfordrawingthepath,thenextstepistofigureouthowtodrawthetilesineachrow.Inthefollowingdiagram,therearetwocasesshown:arowwheretheoffsetfromthecenterofthepathisequalto0.0,andacasewheretheoffsetisnotequaltozero.Takealookatthediagram,thenreadthepseudo-codethatfollows.

SetupvariablesforStartPoint,angp90,angm90,andsoon.

SetthevariableFirstCenterPointtotheStartPoint+offsetamount

(whichmaybe0.0).

SettheinitialvalueofTileCenterPttoFirstCenterPoint.

(Comment:Beginbydrawingthecirclesintheangp90direction.)

WhilethedistancefromtheStartPointtotheTileCenterPtislessthantheHalfWidth:

Drawacircle(addingtotheaccumulatinglistofcircles).

SetTileCenterPttothenexttilespaceincrementintheangp90

direction.

EndWhile

ResettheTileCenterPointtotheFirstCenterPoint+thetilespaceincrementatangm90.

WhilethedistancefromtheStartPointtotheTileCenterPtislessthantheHalfWidth:

Drawacircle(addingtotheaccumulatinglistofcircles).

SetTileCenterPttothenexttilespaceincrementintheangm90

direction.

EndWhile

Returnthelistofcircles.

Page 130: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 131: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>AddingTilestotheGardenPath>

LookingattheCode

Nowlookatthecodeforthegp:calculate-Draw-TileRowfunction:

(defungp:calculate-Draw-TileRow(startPointTileRadius

TileSpacepathWidthpathAngleoffsetFromCenter

ObjectCreationStyle/HalfWidthTileDiameter

ObjectCreationFunctionangp90angm90

firstCenterPtTileCenterPtTileList)

(setqHalfWidth(-(/pathWidth2.00)TileRadius)

Tilespacing(+(*TileRadius2.0)TileSpace)

TileDiameter(*TileRadius2.0)

angp90(+PathAngle(Degrees->Radians90))

angm90(-PathAngle(Degrees->Radians90))

firstCenterPt(polarstartPointangp90offsetFromCenter)

tileCenterPtfirstCenterPt

ObjectCreationStyle(strcaseObjectCreationStyle)

ObjectCreationFunction

(cond

((equalObjectCreationStyle"ACTIVEX")

gp:Create_activeX_Circle

)

((equalObjectCreationStyle"ENTMAKE")

gp:Create_entmake_Circle

)

((equalObjectCreationStyle"COMMAND")

gp:Create_command_Circle

)

(T

(alert(strcat"ObjectCreationStyleinfunction

gp:calculate-Draw-TileRow"

"\nisinvalid.Contactdeveloperforassistance."

"\nObjectCreationStylesettoACTIVEX"

)

)

setqObjectCreationStyle"ACTIVEX")

)

)

)

;;Drawthecirclestotheleftofthecenter.

Page 132: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(while(<(distancestartPointtileCenterPt)HalfWidth)

;;Addeachtiletothelisttoreturn.

(setqtileList

(cons

(ObjectCreationFunctiontileCenterPtTileRadius)

tileList

)

)

;;Calculatethecenterpointforthenexttile.

(setqtileCenterPt

(polartileCenterPtangp90TileSpacing)

)

);_endofwhile

;;Drawthecirclestotherightofthecenter.

(setqtileCenterPt

(polarfirstCenterPtangm90TileSpacing))

(while(<(distancestartPointtileCenterPt)HalfWidth)

;;Addeachtiletothelisttoreturn.

(setqtileList

(cons

(ObjectCreationFunctiontileCenterPtTileRadius)

tileList

)

)

;;Calculatethecenterpointforthenexttile.

(setqtileCenterPt(polartileCenterPtangm90TileSpacing))

);_endofwhile

;;Returnthelistoftiles.

tileList

);_endofdefun

TheAutoLISPcodelogicfollowsthepseudo-code,withthefollowingaddition:

(setqObjectCreationFunction

(cond

((equalObjectCreationStyle"ACTIVEX")

gp:Create_activeX_Circle

)

((equalObjectCreationStyle"ENTMAKE")

gp:Create_entmake_Circle

)

((equalObjectCreationStyle"COMMAND")

gp:Create_command_Circle

)

(T

(alert

(strcat

"ObjectCreationStyleinfunctiongp:calculate-Draw-TileRow"

"\nisinvalid.Contactthedeveloperforassistance."

Page 133: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

"\nObjectCreationStylesettoACTIVEX"

);_endofstrcat

);_endofalert

(setqObjectCreationStyle"ACTIVEX")

)

);_endofcond

);_endofsetq

Rememberthespecificationtoallowuserstodrawthetiles(circles)usingeitherActiveX,theentmakefunction,orthecommandfunction?TheObjectCreationFunctionvariableisassignedoneofthreefunctions,dependingontheObjectCreationStyleparameter(passedfromC:GPathandthroughgp:Calculate-and-Draw-Tiles).Herearethethreefunctionsastheywillbedefinedingpdraw.lsp:

(defungp:Create_activeX_Circle(centerradius)

(vla-addCircle*ModelSpace*

(vlax-3d-pointcenter);converttoActiveX-compatible3Dpoint

radius

)

);_endofdefun

(defungp:Create_entmake_Circle(centerradius)

(entmake

(list(cons0"CIRCLE")(cons10center)(cons40radius))

)

(vlax-ename->vla-object(entlast))

)

(defungp:Create_command_Circle(centerradius)

(command"_CIRCLE"centerradius)

(vlax-ename->vla-object(entlast))

)

ThefirstfunctiondrawsacircleusinganActiveXfunctionandreturnsanActiveXobject.

Thesecondfunctiondrawsacircleusingentmake.ItreturnsanentitynameconvertedintoanActiveXobject.

Thethirdfunctiondrawsacircleusingcommand.ItalsoreturnsanentitynameconvertedintoanActiveXobject.

Pleasesendusyourcommentaboutthispage

Page 134: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>

TestingtheCode

Ifyou'vemadeitthisfar,youhaveearnedashortcut.

Totestthecode

1. ClosealltheactivewindowswithinVLISP,includinganyopenprojectwindows.

2. CopytheentirecontentsoftheTutorial\VisualLISP\Lesson5directorytoyourMyPathtutorialdirectory.

3. Opentheprojectfilegpath5.prjusingSelectProject OpenProjectfromtheVLISPmenubar.

4. Loadtheprojectsourcefiles.

5. Activate(switchto)theAutoCAD®windowandissuethegpathcommandtoruntheprogram.

6. Rungpathtodrawthegardenpaththreetimes,eachtimeusingadifferententitycreationmethod.Doyounoticeadifferenceinthespeedwithwhichthepathisdrawnwitheachmethod?

Pleasesendusyourcommentaboutthispage

Page 135: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

DrawingtheTiles>

WrappingUpLesson5

YoustartedthislessonbylearningVLISPeditingfeaturesthathelpedyou

Matchtheparenthesesinyourcode.

Findandcompleteafunctionname.

ObtaininformationinHelpforafunction.

Youfinishedthelessonbybuildingcodethatdrawsthetilesinthegardenpath.Younowhaveaprogramthatmeetstherequirementsestablishedattheverybeginningofthistutorial.

Atthispoint,youprobablyhaveacquiredenoughexperiencewithVLISPtoventureoffonyourown.Butifyouareuptoit,therearetwomorelessonsinthistutorialthatdemonstratetheuseofreactorfunctionsandotheradvancedfeaturesoftheVLISPenvironment.

Pleasesendusyourcommentaboutthispage

Page 136: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors

Inthislesson,youwilllearnaboutreactorsandhowtoattachthemtodrawingeventsandentities.ReactorsallowyourapplicationtobenotifiedbyAutoCAD®

whenparticulareventsoccur.Forexample,ifausermovesanentitythatyourapplicationhasattachedareactorto,yourapplicationwillreceivenotificationthattheentityhasmoved.Youcanprogramthistotriggeradditionaloperations,suchasmovingotherentitiesassociatedwiththeonetheusermoved,orperhapsupdatingatexttagthatrecordsrevisioninformationonthealtereddrawingfeature.Ineffect,itislikesettingupyourapplicationwithapagerandtellingAutoCADtobeeptheapplicationwhensomethinghappens.

Topicsinthissection

ReactorBasicsDesigningReactorsfortheGardenPathTestDrivingYourReactorsWrappingUpLesson6

Pleasesendusyourcommentaboutthispage

Page 137: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>

ReactorBasics

Areactorisanobjectyouattachtothedrawingeditor,ortospecificentitieswithinadrawing.Extendingthemetaphorofthepager,thereactorobjectisanautomaticdialerthatknowshowtocallyourpagerwhensomethingsignificanthappens.ThepagerwithinyourapplicationisanAutoLISP®functioncalledbythereactor;suchafunctionisknownasacallbackfunction.

Note ThecomplexityoftheapplicationcodeandthelevelofexpertiserequiredforthesefinaltwolessonsismuchhigherthanLessons1through5.Thereisagreatdealofinformationpresented,butitisnotallexplainedatthesamelevelofdetailasinthepreviouslessons.Ifyouareabeginner,don'tworryifyoudon'tgetitthefirsttime.ConsiderthisjustafirsttasteofsomeoftheverypowerfulbutmoretechnicallydifficultfeaturesofVisualLISP®.

Topicsinthissection

ReactorTypes

Pleasesendusyourcommentaboutthispage

Page 138: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>ReactorBasics>

ReactorTypes

TherearemanytypesofAutoCAD®reactors.EachreactortyperespondstooneormoreAutoCADevents.Reactorsaregroupedintothefollowingcategories:

EditorReactors

NotifyyourapplicationeachtimeanAutoCADcommandisinvoked.

LinkerReactors

NotifyyourapplicationeverytimeanObjectARX®applicationisloadedorunloaded.

DatabaseReactors

Correspondtospecificentitiesorobjectswithinadrawingdatabase.

DocumentReactors

NotifyyourapplicationinMDImodeofachangetothecurrentdrawingdocument,suchasopeningofanewdrawingdocument,activatingadifferentdocumentwindow,andchangingadocument'slockstatus.

ObjectReactors

Notifyyoueachtimeaspecificobjectischanged,copied,ordeleted.

Withtheexceptionofeditorreactors,thereisonetypeofreactorforeachreactorcategory.Editorreactorsencompassabroadclassofreactors:forexample,DXF™reactorsthatnotifyanapplicationwhenaDXFfileisimportedorexported,andMousereactorsthatnotifyofmouseeventssuchasdouble-clicks.

Withinthereactorcategories,therearemanyspecificeventstowhichyoucanattachareactor.AutoCADallowsuserstoperformmanydifferentkindsofactions,anditisuptoyoutodeterminetheactionsthatyouareinterestedin.Onceyouhavedonethis,youcanattachyourreactor“auto-dialer”totheevent,

Page 139: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

thenwritethecallbackfunctionthatistriggeredwhentheeventoccurs.

Pleasesendusyourcommentaboutthispage

Page 140: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>

DesigningReactorsfortheGardenPath

Toimplementreactorfunctionalityinthegardenpathapplication,startbyhandlingjustafewevents,ratherthantryingtocoverallpossibleuseractions.

Topicsinthissection

SelectingReactorEventsfortheGardenPathPlanningtheCallbackFunctionsPlanningforMultipleReactorsAttachingtheReactorsStoringDatawithaReactorUpdatingtheC:GPathFunctionAddingReactorCallbackFunctionsCleaningUpAfterYourReactors

Pleasesendusyourcommentaboutthispage

Page 141: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

SelectingReactorEventsfortheGardenPath

Forthetutorial,setthefollowinggoals:

Whenacornerpoint(vertex)ofthegardenpathboundaryisrepositioned,redrawthepathsothattheoutlineremainsrectilinear.Inaddition,redrawthetilesbasedonthenewsizeandshape.

Whenthegardenpathboundaryiserased,erasethetilesaswell.

Pleasesendusyourcommentaboutthispage

Page 142: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

PlanningtheCallbackFunctions

Foreachreactorevent,youmustplanthefunctionthatwillbeinvokedwhentheeventoccurs.Thefollowingpseudo-codeoutlinesthelogicalsequenceofeventsthatshouldoccurwhenusersdragoneofthepolylineverticestoanewlocation:

Defungp:outline-changed

Erasethetiles.

Determinehowtheboundarychanged.

Straightenuptheboundary.

Redrawnewtiles.

Endfunction

Thereisacomplication,though.Whentheuserbeginsdraggingtheoutlineofapolylinevertex,AutoCADnotifiesyourapplicationbyissuinga:vlr-modifiedevent.However,atthispointtheuserhasjustbegundraggingoneofthepolylinevertices.Ifyouimmediatelyinvokethegp:outline-changedfunction,youwillinterrupttheactionthattheuserisinthemidstof.Youwouldnotknowwherethenewvertexlocationwillbe,becausetheuserhasnotyetselecteditsposition.Andfinally,AutoCADwillnotallowyourfunctiontomodifythepolylineobjectwhiletheuserisstilldraggingit.AutoCADhasthepolylineobjectopenformodification,andleavesitopenuntiltheuserfinishesrepositioningtheobject.

Youneedtochangeyourapproach.Hereistheupdatedlogic:

Whentheuserbeginsrepositioningapolylinevertex,

Invokethegp:outline-changedfunction

Defungp:outline-changed

Setaglobalvariablethatstoresapointertothepolyline

beingmodifiedbytheuser

Endfunction

Whenthecommandcompletes,

Invokethegp:command-endedfunction

Defungp:command-ended

Erasethetiles

Page 143: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Getinformationonthepreviouspolylinevertexlocations

Getinformationonthenewpolylinevertexlocations

Redefinethepolyline(straightenitup)

Redrawthetiles

Endfunction

Whenausercompletesmodifyingapathoutline,AutoCADnotifiesyourapplicationbyissuinga:vlr-commandEndedevent,ifyouhaveestablishedaneditorreactor.

Theuseofaglobalvariabletoidentifythepolylinetheuserchangedisnecessarybecausethereisnocontinuitybetweenthegp:outline-changedandgp:command-endedfunctions.Inyourapplication,bothfunctionsareinvokedandexecutedindependentlyofoneanother.Theglobalvariablestoresimportantinformationsetupinonefunctionandaccessedintheother.

Nowconsiderwhattodoiftheusererasesthegardenpathboundary.Theultimateobjectiveistoeraseallthetiles.Thefollowingpseudo-codeoutlinesthelogic:

Whentheuserbeginstoerasetheboundary,

Invokethegp:outline-erasedfunction

Defungp:outline-erased

Setaglobalvariablethatstoresapointertothereactor

attachedtothepolylinecurrentlybeingerased

Endfunction

Whentheeraseiscompleted,

Invokethegp:command-endedfunction

Defungp:command-ended

Erasethetilesthatbelongedtothenow-deletedpolyline

Endfunction

Pleasesendusyourcommentaboutthispage

Page 144: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

PlanningforMultipleReactors

Usersmayhaveseveralgardenpathsonthescreen,andmaybeerasingmorethanone.Youneedtoplanforthispossibility.

Thereactorassociatedwithanentityisanobjectreactor.Ifthereareseveralentitiesinthedrawing,theremayalsobeseveralobjectreactors,oneforeachentity.Aspecificeditingevent,suchastheerasecommand,cantriggermanycallbacks,dependingonhowmanyoftheselectedentitieshavereactorsattached.Editorreactors,ontheotherhand,aresingularinnature.Yourapplicationshouldonlyattachasingle:vlr-commandEndedeventreactor.

Theeventsequenceforbothmodifications—changingavertexlocationanderasingapolyline—endsupwithactionsthatneedtobeperformedwithinthegp:command-endedfunction.Determinewhichsetofactionstoperformforeachcondition.Thefollowingpseudo-codeoutlinesthelogic:

Defungp:command-ended(2ndversion)

Retrievethepointertothepolyline(fromaglobalvariable)

Conditional:

Ifthepolylinehasbeenmodifiedthen:

Erasethetiles

Getinformationonthepreviouspolylinevertexlocations

Getinformationonthenewpolylinevertexlocations

Redefinethepolyline(straightenitup)

Redrawthetiles

Endconditionalexpression

Ifthepolylinehasbeenerasedthen:

Erasethetiles

Endconditionalexpression

EndConditional

Endfunction

Pleasesendusyourcommentaboutthispage

Page 145: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

AttachingtheReactors

Thenextstepinplanningareactor-basedapplicationistodeterminehowandwhentoattachreactors.Youneedtoattachtwoobjectreactorsforthepolylineborderofanygardenpath(onetorespondtoamodificationevent,theothertorespondtoerasure),andoneeditorreactortoalertyourapplicationwhenuserscompletetheirmodificationtothepolyline.Objectreactorsareattachedtoentities,whileeditorreactorsareregisteredwithAutoCAD.

Thereisanotherconsiderationtoaccountfor.Torecalculatethepolylineoutline—returnittoarectilinearshape—aftertheusermodifiesit,youmustknowwhatthevertexconfigurationwasbeforethemodification.Thisinformationcannotbedeterminedoncethepolylinehasbeenmodified.Bythattimeyoucanonlyretrieveinformationonwhatthenewconfigurationis.Sohowdoyousolvethis?Youcouldkeepthisinformationinaglobalvariable,butthereisamajorproblemwiththatidea.Userscandrawasmanygardenpathsastheywant,andeverynewpathwouldrequireanewglobalvariable.

Pleasesendusyourcommentaboutthispage

Page 146: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

StoringDatawithaReactor

YoucansolvetheproblemofsavingtheoriginalconfigurationbytakingadvantageofanotherfeatureofVLISPreactors—theabilitytostoredatawithinareactor.Whentheuserfirstdrawsapathboundary,youattachareactortotheboundary,alongwiththedatayouneedtosave.Thisentailsmodifyingyourmainprogramfunction,C:GPath,asfollows:

DefunC:GPath

Doeverythingthatisalreadydoneinthegardenpath

(anddon'tbreakanything)

Attachanobjectreactortothepolylineusingtheseparameters:

Apointertothepolylinejustdrawn,

Alistofdatathatyouwantthereactortorecord,

Alistofthespecificpolylineobjecteventstobetracked,

alongwiththeLISPcallbackfunctionstobeinvoked

Endoftheobjectreactorsetup

Attacheditorreactortothedrawingeditorusingthe

followingparameters:

Anydatayouwantattachedtothereactor(inthiscase,none)

Alistofthespecificeditorreactoreventstobetracked,

alongwiththeLISPcallbackfunctionstobeinvoked

Endoftheeditorreactorsetup

Endfunction

Pleasesendusyourcommentaboutthispage

Page 147: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

UpdatingtheC:GPathFunction

UpdatetheC:GPathfunctionbyaddingreactorcreationlogic.

ToaddreactorcreationlogictoC:GPath

1. Replaceyourversionofgpmain.lspwiththeupdatedversionshownbelow.Copythiscodefromthe<AutoCADdirectory>\Tutorial\VisualLISP\Lesson6directory:

(defunC:GPath(/

gp_PathData

gp_dialogResults

PolylineName

tileList

)

(setvar"OSMODE"0);;Turnoffobjectsnaps

;|

;;Lesson6addsastubbed-outcommandreactortoAutoCAD

;;However,itwouldbeundesirabletoreacttoevery

;;drawingofacircleshouldtheCOMMANDtilecreation

;;methodbechosenbytheuser.So,disablethe

;;*commandReactor*incaseitexists.

|;

(if*commandReactor*

(progn

(setq*commandReactor*nil)

(vlr-remove-all:VLR-Command-Reactor)

)

)

;;Asktheuserforinput:firstforpathlocationand

;;direction,thenforpathparameters.Continueonlyifyou

;;havevalidinput.Storethedataingp_PathData.

(if(setqgp_PathData(gp:getPointInput))

(if(setqgp_dialogResults

(gp:getDialogInput

(cdr(assoc40gp_PathData))

);_endofgp:getDialogInput

Page 148: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

);_endofsetq

(progn

;;Nowtaketheresultsofgp:getPointInputandappendthisto

;;theaddedinformationsuppliedbygp:getDialogInput

(setqgp_PathData(appendgp_PathDatagp_DialogResults))

;;Atthispoint,youhavealltheinputfromtheuser

;;Drawtheoutline,storingtheresultingpolyline"pointer"

;;inthevariablecalledPolylineName

(setqPolylineName(gp:drawOutlinegp_PathData))

;;Next,itistimetodrawthetileswithintheboundary.

;;Thegp_tileListcontainsalistoftheobjectpointersfor

;;thetiles.Bycountingupthenumberofpoints(usingthe

;;lengthfunction),wecanprintouttheresultsofhowmany

;;tilesweredrawn.

(princ"\nThepathrequired")

(princ

(length

(setqtileList(gp:Calculate-and-Draw-Tilesgp_PathData))

);_endoflength

);_endofprinc

(princ"tiles.")

;;Addthelistofpointerstothetiles(returnedby

;;gp:Calculate-and-Draw-Tiles)togp_PathData.Thiswill

;;bestoredinthereactordataforthereactorattached

;;totheboundarypolyline.Withthisdata,thepolyline

;;"knows"whattiles(circles)belongtoit.

(setqgp_PathData

(append(list(cons100tileList))

;allthetiles

gp_PathData

);_endofappend

);_endofsetq

;;Beforeweattachreactordatatoanobject,let'slookat

;;thefunctionvlr-object-reactor

;;vlr-object-reactorhasthefollowingarguments:

;;(vlr-object-reactorowner'sdatacallbacks)

;;ThecallbacksArgumentisalistcomprised

;;'(event_name.callback_function)

;;

;;Forthisexercisewewilluseallarguments

;;associatedwithvlr-object-reactor

;;Thesereactorfunctionswillexecuteonlyif

;;thepolylineinPolylineNameismodifiedorerased

(vlr-object-reactor

;;Thefirstargumentforvlr-object-reactoris

;;the"Owner'sList"argument.Thisiswhereto

;;placetheobjecttobeassociatedwiththe

;;reactor.Inthiscase,itisthevlaObject

;;storedinPolylineName.

(listPolylineName)

Page 149: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

;;Thesecondargumentcontainsthedataforthepath

gp_PathData

;;Thethirdargumentisthelistofspecificreactor

;;typesthatweareinterestedinusing

'

(

;;reactorthatiscalleduponmodificationoftheobject

(:vlr-modified.gp:outline-changed)

;;reactorthatiscalleduponerasureoftheobject

(:vlr-erased.gp:outline-erased)

)

);_endofvlr-object-reactor

;;Next,registeracommandreactortoadjustthepolyline

;;whenthechangingcommandisfinished

(if(not*commandReactor*)

(setq*commandReactor*

(VLR-Command-Reactor

nil;Nodataisassociatedwiththecommandreactor

'(

(:vlr-commandWillStart.gp:command-will-start)

(:vlr-commandEnded.gp:command-ended)

)

);_endofvlr-command-reactor

)

)

;;Thefollowingcoderemovesallreactorswhenthedrawingis

;;closed.Thisisextremelyimportant!!!!!!!!!

;;Withoutthisnotification,AutoCADmaycrashuponexiting!

(if(not*DrawingReactor*)

(setq*DrawingReactor*

(VLR-DWG-Reactor

nil;Nodataisassociatedwiththedrawingreactor

'((:vlr-beginClose.gp:clean-all-reactors)

)

);_endofvlr-DWG-reactor

)

)

);_endofprogn

(princ"\nFunctioncancelled.")

);_endofif

(princ"\nIncompleteinformationtodrawaboundary.")

);_endofif

(princ);exitquietly

);_endofdefun

;;;Displayamessagetolettheuserknowthecommandname.

(princ"\nTypeGPATHtodrawagardenpath.")

(princ)

2. Reviewthecodemodificationsandcommentsdescribingwhateachnew

Page 150: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

statementdoes.Thistutorialshowsallmodifiedcodeinboldface.

Pleasesendusyourcommentaboutthispage

Page 151: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

AddingReactorCallbackFunctions

Thereactorcallbackfunctionsaddasubstantialamountofcodetoyourapplication.ThiscodeisprovidedforyouintheLesson6directory.

Toaddthereactorcallbackfunctionstoyourprogram

1. Copythegpreact.lspfilefromtheTutorial\VisualLISP\Lesson6directorytoyourMyPathworkingdirectory.

2. OpentheGPathproject(ifitisnotalreadyopen),andchoosetheProjectPropertiesbuttoninthegpathprojectwindow.

3. Addthegpreact.lspfiletoyourproject.

4. Thegpreact.lspfilecanresideanywhereintheorderoffilesbetweenutils.lsp,whichmustremainfirst,andgpmain.lsp,whichshouldremainasthelastfile.Moveanyfiles,ifnecessary,thenchooseOK.

5. Openthegpreact.lspfilebydouble-clickingonthefilenamewithinthegpathprojectwindow.

Readthroughthecommentsinthefiletohelpyouunderstandwhatitisdoing.Notethatallthecallbackfunctionsarestubbedout;theonlyfunctionalitytheyperformistodisplayalertmessageswhentheyarefired.

Thelastfunctioninthefileissoimportantitdeservesaheadingofitsown.

Pleasesendusyourcommentaboutthispage

Page 152: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>DesigningReactorsfortheGardenPath>

CleaningUpAfterYourReactors

Reactorsareindeedveryactive.Whenyoudesignanapplicationthatreliesonthem,youcouldverywellspendagreatdealoftimecrashingyourprogramandpossiblycrashingAutoCADaswell.Ithelpstohaveatoolavailabletoremoveallthereactorsyouhaveadded,ifnecessary.

Thegpreact.lspfileincludesafunctiongp:clean-all-reactorsthatdoesn'tdomuchonitsown.Instead,itmakesacalltotheCleanReactorsfunction.Addthisfunctiontoyourutils.lspfilebycopyingthefollowingcodetotheendofthefile:

;;;--------------------------------------------------------------;

;;;Function:CleanReactors;

;;;--------------------------------------------------------------;

;;;Description:Generalutilityfunctionusedforcleaningup;

;;;reactors.Itcanbeusedduringdebugging,as;

;;;wellascleaningupanyopenreactorsbefore;

;;;adrawingisclosed.;

;;;--------------------------------------------------------------;

(defunCleanReactors()

(mapcar'vlr-remove-all

'(:VLR-AcDb-reactor

:VLR-Editor-reactor

:VLR-Linker-reactor

:VLR-Object-reactor

)

)

)

Pleasesendusyourcommentaboutthispage

Page 153: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>

TestDrivingYourReactors

Bynow,youshouldhaveallthenecessarypiecesinplacetousesomelivereactors.

Totestthereactorcode

1. Loadallthesourcecodefromyourproject.(ChoosetheLoadSourceFilesbuttoninthegpathprojectwindow.)

2. StarttheC:GPathfunction.Theprogramwilldrawagardenpathforyou,justasyouwereabletoinLesson5.Youwon'tseeanythinginterestingatfirst.

3. Trythefollowingactionsafteryoudrawthepath:

Moveapolylinevertex.Pickthepolylineandturnonitsgrips,thendragavertextoanewlocation.

Stretchthepolyline.

Movethepolyline.

Erasethepolyline.

Examinethemessagesthatappear.Youarewatchingthebehind-the-scenesactivitiesofapowerfulcapability.

(Ifyourapplicationisnotworkingcorrectlyandyoudonotwanttotakethetimetodebugitrightnow,youcanrunthesamplecodeprovidedintheTutorial\VisualLISP\Lesson6directory.UsetheGpath6projectinthatdirectory.)

Note Becauseofthereactorbehavior,youmaynoticethataftertestingareactorsequenceinAutoCAD,youcannotreturntoVLISPbypressingALT+TAB,or

Page 154: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

byclickingtoactivatetheVLISPwindow.Ifthishappens,simplyentervlispattheAutoCADCommandprompttoreturntoVLISP.

Topicsinthissection

ExaminingReactorBehaviorinDetail

Pleasesendusyourcommentaboutthispage

Page 155: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>TestDrivingYourReactors>

ExaminingReactorBehaviorinDetail

Withastackofscrappaper,starttracingthereactoreventswithintheapplication.Hereisanexampleofthekindsofthingsyoushouldtrack:

Drawtengardenpaths,thentrackthefollowingCommand/Objectcombinations,selectingthepolylinesinsuccession:

Erase/Polylineborder(path1)

Erase/Circlewithinapolyline(path2)

Erase/Twopolylines(paths3and4)

Move/Polylineborder(path5)

Move/Circlewithinapolyline(path6)

Move/Twopolylinesandseveralcircles(paths7and8)

MoveVertex(throughgrips)/Polylineborder(path9)

Stretch/Polylineborder(path10)

Thisexercisewillgiveyouagoodunderstandingofwhatishappeningbehindthescenes.AtanytimethroughoutLesson7whenthereactorfunctionality

Page 156: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

becomesconfusing,refertoyour“reactor-tracesheets.”

Pleasesendusyourcommentaboutthispage

Page 157: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ActingwithReactors>

WrappingUpLesson6

Inthislesson,youwereintroducedtoAutoCADreactorsandhowtoimplementthemusingVLISP.Youdesignedaplanforaddingreactorstothegardenpathapplication,andaddedsomeofthecodeyourprogramwillneedtoimplementtheplan.

Reactorscanaddagreatdealoffunctionalitytoanapplication,butremember—themorepowerfulyourprogramscanbe,thehardertheycancrash.

Anotherthingtokeepinmindisthatthewayyourapplicationisdesigned,thereactorfunctionalityisnotpersistentfromonedrawingsessiontothenext.Ifyousaveadrawingthatcontainsagardenpathhookeduptoreactors,thereactorswillnotbetherethenexttimeyouopenthedrawing.Youcanlearnaboutaddingpersistentreactorsbyreviewingthe“TransientversusPersistentReactors”topicintheAutoLISPDeveloper'sGuide,andthenreadingaboutthereferencedfunctionsintheAutoLISPReference.

Pleasesendusyourcommentaboutthispage

Page 158: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether

InLesson6,youlearnedthebasicmechanicsbehindreactor-basedapplications.InLesson7,youwilladdfunctionalitytothisknowledgeandcreateagardenpaththatknowshowandwhentomodifyitself.Aftertestingyourapplicationanddeterminingthatitworkssatisfactorily,youwillcreateaVisualLISP®applicationfromyourVLISPproject.

Youshouldconsiderthispartofthetutorialastheadvancedtopicssection.Ifyouareabeginner,youmaynotunderstandalltheAutoLISP®codepresentedhere.ThereareseveralAutoLISPbookslistedattheendofthislessonthatprovidemorethoroughinformationonsomeoftheadvancedAutoLISPconceptspresentedhere.

Topicsinthissection

PlanningtheOverallReactorProcessAddingtheNewReactorFunctionalityRedefiningthePolylineBoundaryWrappingUptheCodeBuildinganApplicationWrappingUptheTutorialLISPandAutoLISPBooks

Pleasesendusyourcommentaboutthispage

Page 159: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

PlanningtheOverallReactorProcess

Youneedtodefineseveralnewfunctionsinthislesson.Ratherthanpresentyouwithdetailsonallaspectsofthenewcode,thislessonpresentsanoverviewandpointsouttheconceptsbehindthecode.Attheendofthelesson,youwillhaveallthesourcecodenecessarytocreateagardenpathapplicationidenticaltothesampleprogramyouraninLesson1.

Note Whenyouareinthemidstofdevelopinganddebuggingreactor-basedapplications,thereisalwaysthepotentialofleavingAutoCAD®inanunstablestate.Thiscanbecausedbyseveralsituations,suchasfailingtoremoveareactorfromdeletedentities.Forthisreason,itisrecommendedthatbeforebeginningLesson7,youshouldcloseVLISP,saveanyopenfilesasyoudoso,exitAutoCAD,thenrestartbothapplications.

BeginbyloadingtheprojectasitexistedattheendofLesson6.

Twoobviouspiecesofworkremaintobedoneinthegardenpathapplication:

Writingtheobjectreactorcallbacks.

Writingtheeditorreactorcallbacks.

Youalsoneedtoconsiderhowtohandletheglobalvariablesinyourprogram.Often,itisdesirabletohaveglobalsretainavaluethroughoutanAutoCADdrawingsession.Inthecaseofreactors,however,thisisnotthecase.Toillustratethis,imagineauserofyourgardenpathapplicationhasdrawnseveralgardenpathsinasingledrawing.Afterdoingthis,theusererasesthem,firstoneatatime,thentwoatatime,andsoon,untilallbutonepathiserased.

Lesson5introducedaglobalvariable*reactorsToRemove*,responsibleforstoringpointerstothereactorsforthepolylinesabouttobeerased.When*reactorsToRemove*isdeclaredingp:outline-erased,theeventletsyouknowthepolylineisabouttobeerased.Thepolylineisnotactuallyremoveduntilthegp:command-endedeventfires.

Page 160: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Thefirsttimetheuserdeletesapolyline,thingsworkjustasyouwouldexpect.Ingp:outline-erased,youstoreapointertothereactor.Whengp:command-endedfires,youremovethetilesassociatedwiththepolylinetowhichthereactorisattached,andalliswell.Then,theuserdecidestoerasetwopaths.Asaresult,yourapplicationwillgettwocallstogp:outline-erased,oneforeachpolylineabouttobeerased.Therearetwopotentialproblemsyoumustanticipate:

Whenyousetqthe*reactorsToRemove*variable,youmustaddapointertoareactortotheglobal,makingsurenottooverwriteanyvaluesalreadystoredthere.Thismeans*reactorsToRemove*mustbealiststructure,soyoucanappendreactorpointerstoit.Youcanthenaccumulateseveralreactorpointerscorrespondingtothenumberofpathstheuseriserasingwithinasingleerasecommand.

Everytimegp:command-will-startfires,indicatinganewcommandsequenceisbeginning,youshouldreinitializethe*reactorsToRemove*variabletonil.Thisisnecessarysothattheglobalisnotstoringreactorpointersfromthepreviouserasecommand.Ifyoudonotreinitializetheglobalvariableorusethecorrectdatastructure(inthiscase,alist),youwillgetunexpectedbehavior.Inthecaseofreactors,unexpectedbehaviorcanbefataltoyourAutoCADsession.

Hereisthechainofeventsthatneedstooccurforuserstoerasetwogardenpathswithasingleerasecommand.Notehowglobalvariablesarehandled:

Initiatetheerasecommand.Thistriggersthegp:command-will-startfunction.Set*reactorsToRemove*tonil.

Selecttwopolylines;yourapplicationisnotyetnotified.

PressENTERtoerasethetwoselectedpolylines.Yourapplicationgetsacallbacktogp:outline-erasedforoneofthepolylines.Additsreactorpointertothenullglobal,*reactorsToRemove*.Yourapplicationgetsacallbacktogp:outline-erasedforthesecondofthepolylines.Appenditsreactorpointertothe*reactorsToRemove*globalthatalreadycontainsthefirstreactor

Page 161: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

pointer.

AutoCADdeletesthepolylines.

Yourcallbackfunctiongp:command-endedfires.Eliminateanytilesassociatedwiththereactorpointersstoredin*reactorsToRemove*.

Inadditiontothe*reactorsToRemove*global,yourapplicationalsoincludesa*polyToChange*global,whichstoresapointertoanypolylinethatwillbemodified.Twoadditionalglobalsfortheapplicationwillbeintroducedlaterinthislesson.

Topicsinthissection

ReactingtoMoreUser-InvokedCommandsStoringInformationWithintheReactorObjects

Pleasesendusyourcommentaboutthispage

Page 162: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>PlanningtheOverallReactorProcess>

ReactingtoMoreUser-InvokedCommands

Whenwritingareactor-basedapplication,youneedtohandleanycommandthataffectsyourobjectsinasignificantway.OneofyourprogramdesignactivitiesshouldbetoreviewallpossibleAutoCADeditingcommandsanddeterminehowyourapplicationshouldrespondtoeachone.Theformatofthereactor-tracesheetshownneartheendofLesson6isverygoodforthispurpose.Invokethecommandsyouexpectyourusertouse,andwritedownthekindofbehaviorwithwhichyourapplicationshouldrespond.Otheractionstoplanforinclude

DeterminewhattodowhenusersissueUNDOandREDOcommands.

DeterminewhattodowhenusersissuetheOOPScommandaftererasingentitieslinkedwithreactors.

Topreventaverycomplexsubjectfrombecomingvery,verycomplex,thetutorialdoesnottrytocoverallthepossibilitiesthatshouldbecovered,andthefunctionalitywithinthislessoniskepttoanabsoluteminimum.

Eventhoughyouwon'tbebuildinginthecompletefunctionalityfortheseextracommands,examinewhatafewadditionaleditingfunctionswouldrequireyoutodo:

Ifusersstretchapolylineboundary(usingtheSTRETCHcommand)severalthingsshouldhappen.Itcouldbestretchedinanydirection,notjustonthemajororminoraxis,sotheboundarymayendupinaveryoddshape.Inaddition,youneedtotakeintoconsiderationhowmanyverticeshavebeenstretched.Asituationwhereonlyonevertexisstretchedwillresultinapolylinequitedifferentfromoneinwhichtwoverticesaremoved.Inanycase,thetilesmustbeerasedandnewpositionsrecalculatedonceyoudeterminetheadjustmentsneededtotheboundary.

Ifusersmoveapolylineboundary,allthetilesshouldbeerased,thenredrawninthenewlocation.Thisisafairlysimpleoperation,because

Page 163: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

thepolylineboundarydidnotchangeitssizeorshape.

Ifusersscaleapolylineboundary,youneedtomakeadecision.Shouldthetilesbescaledupaswell,sothatthepathcontainsthesamenumberoftiles?Or,shouldthetilesizeremainthesameandtheapplicationaddorremovetiles,dependingonwhetherthepolylinewasscaledupordown?

Ifusersrotateapolylineboundary,allthetilesshouldbeerased,thenredrawnintheneworientation.

Tobegin,though,justplanforthefollowing:

Warntheuseruponcommand-startthattheselectededitcommand(suchasstretch,move,orrotate)willhavedetrimentaleffectsonagardenpath.

Iftheuserproceeds,erasethetilesanddonotredrawthem.

Removethereactorsfromthepathoutline.

Note Inadditiontouser-invokedAutoCADcommands,entitiesmayalsobemodifiedordeletedthroughAutoLISPorObjectARX®applications.TheexampleprovidedintheGardenPathtutorialdoesnotcoverprogrammaticmanipulationofthegardenpathpolylineboundary,suchasthrough(entdel<polylineentity>).Inthiscase,theeditorreactorevents:vlr-commandWillStartand:vlr-commandEndedwillnotbetriggered.

Pleasesendusyourcommentaboutthispage

Page 164: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>PlanningtheOverallReactorProcess>

StoringInformationWithintheReactorObjects

Oneotherimportantaspectoftheapplicationyouneedtothinkaboutiswhatkindofinformationtoattachtotheobjectreactorthatiscreatedforeachpolylineentity.InLesson6,youaddedcodethatattachedthecontentsofgp_PathData(theassociationlist)tothereactor.Youexpandedthedatacarriedwithingp_PathDatabyaddinganewkeyedfield(100)totheassociationlist.Thisnewsublistisalistofpointerstoallthecircleentitiesassignedtoapolylineboundary.

Becauseoftheworkthatneedstobedonetorecalculatethepolylineboundary,fouradditionalkeyvaluesshouldbeaddedtogp_pathData:

;;;StartingPoint;

;;;(12.BottomStartingPoint)15------------------------14;

;;;(15.TopStartingPoint)||;

;;;EndingPoint10----pathAngle--->11;

;;;(13.BottomEndingPoint)||;

;;;(14.TopEndingPoint)12------------------------13;

;;;;

Theseorderedpointsarenecessarytorecalculatethepolylineboundarywhenevertheuserdragsacornergriptoanewlocation.Thisinformationalreadyexistswithinthegp:drawOutlinefunctioningpdraw.lsp.Butlookatthereturnvalueofthefunction.Currently,onlythepointertothepolylineobjectisreturned.Soyouneedtodothreethings:

Assembletheperimeterpointsintheformatrequired.

Modifythefunctionsothatitreturnstheperimeterpointlistsandthepointertothepolyline.

ModifytheC:GPathfunctionsothatitcorrectlydealswiththenewformatofthevaluesreturnedfromgp:drawOutline.

Assemblingtheperimeterpointlistsissimple.Lookatthecodein

Page 165: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

gp:drawOutline.Thelocalvariablep1correspondstothekeyvalue12,p2to13,p3to14,andp4to15.Youcanaddthefollowingfunctioncalltoassemblethisinformation:

(setqpolyPoints(list

(cons12p1)

(cons13p2)

(cons14p3)

(cons15p4)

))

Modifyingthefunctionsothatitreturnsthepolylineperimeterpointsandthepolylinepointerisalsoeasy.Asthelastexpressionwithingp:drawOutline,assemblealistofthetwoitemsofinformationyouwanttoreturn.

(listplinepolyPoints)

Toaddprogramlogictosavethepolylineperimeterpoints

1. Modifygp:drawOutlinebymakingthechangesshowninboldfaceinthefollowingcode(don'toverlooktheadditionofthepolyPointslocalvariabletothedefunstatement):

(defungp:drawOutline(BoundaryData/PathAngle

WidthHalfWidthStartPtPathLength

angm90angp90p1p2

p3p4poly2Dpoints

poly3DpointsplineStylepline

polyPoints

)

;;extractthevaluesfromthelistBoundaryData.

(setqPathAngle(cdr(assoc50BoundaryData))

Width(cdr(assoc40BoundaryData))

HalfWidth(/Width2.00)

StartPt(cdr(assoc10BoundaryData))

PathLength(cdr(assoc41BoundaryData))

angp90(+PathAngle(Degrees->Radians90))

angm90(-PathAngle(Degrees->Radians90))

p1(polarStartPtangm90HalfWidth)

p2(polarp1PathAnglePathLength)

p3(polarp2angp90Width)

p4(polarp3(+PathAngle

(Degrees->Radians180))PathLength)

poly2Dpoints(apply'append

(mapcar'3dPoint->2dPoint(listp1p2p3p4))

Page 166: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

)

poly3Dpoints(mapcar'float(appendp1p2p3p4))

;;getthepolylinestyle.

plineStyle(strcase(cdr(assoc4BoundaryData)))

;;AddpolylinetothemodelspaceusingActiveXautomation.

pline(if(=plineStyle"LIGHT")

;;createalightweightpolyline.

(vla-addLightweightPolyline

*ModelSpace*;GlobalDefinitionforModelSpace

(gp:list->variantArraypoly2Dpoints)

;dataconversion

);_endofvla-addLightweightPolyline

;;orcreatearegularpolyline.

(vla-addPolyline

*ModelSpace*

(gp:list->variantArraypoly3Dpoints)

;dataconversion

);_endofvla-addPolyline

);_endofif

polyPoints(list

(cons12p1)

(cons13p2)

(cons14p3)

(cons15p4)

)

);_endofsetq

(vla-put-closedplineT)

(listplinepolyPoints)

);_endofdefun

2. ModifytheC:GPathfunction(ingpmain.lsp).Lookforthelineofcodethatcurrentlylookslikethis:

(setqPolylineName(gp:drawOutlinegp_PathData))

Changeitsoitappearsasfollows:

(setqPolylineList(gp:drawOutlinegp_PathData)

PolylineName(carPolylineList)

gp_pathData(appendgp_pathData(cadrPolylineList))

);_endofsetq

Thegp_PathDatavariablenowcarriesalltheinformationrequiredbythereactorfunction.

3. AddPolylineListtothelocalvariablessectionoftheC:GPathfunctiondefinition.

Page 167: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 168: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

AddingtheNewReactorFunctionality

InLesson6,youhookedupcallbackfunctiongp:command-will-starttothereactorevent:vlr-commandWillStart.Asitcurrentlyexists,thefunctiondisplayssomemessagesandinitializestwoglobalvariables,*polyToChange*and*reactorsToRemove*,tonil.

Toaddfunctionalitytothegp:command-will-startcallbackfunction

1. Openyourgpreact.lspfile.

2. Inthegp:command-will-startfunction,addtwovariablestothesetqfunctioncallbymodifyingitasfollows:

;;Resetallfourreactorglobalstonil.

(setq*lostAssociativity*nil

*polyToChange*nil

*reactorsToChange*nil

*reactorsToRemove*nil)

3. Replacetheremainingcodeingp:command-will-start,uptothelastprincfunctioncall,withthefollowingcode:

(if(member(setqcurrentCommandName(carcommand-list))

'("U""UNDO""STRETCH""MOVE"

"ROTATE""SCALE""BREAK""GRIP_MOVE"

"GRIP_ROTATE""GRIP_SCALE""GRIP_MIRROR")

);_endofmember

(progn

(setq*lostAssociativity*T)

(princ"\nNOTE:The")

(princcurrentCommandName)

(princ"commandwillbreakapath'sassociativity.")

);_endofprogn

);_endofif

Thiscodecheckstoseeiftheuserissuedacommandthatbreaksthe

Page 169: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

associativitybetweenthetilesandthepath.Iftheuserissuedsuchacommand,theprogramsetsthe*lostAssociativity*globalvariableandwarnstheuser.Asyouexperimentwiththegardenpathapplication,youmaydiscoveradditionaleditingcommandsthatcanmodifythegardenpathandcausethelossofassociativity.Addthesecommandstothequotedlistsothattheuserisawareofwhatwillhappen.Whenthisfunctionfires,theuserhasstartedacommandbuthasnotselectedanyentitiestomodify.Theusercouldstillcancelthecommand,leavingthingsunchanged.

Topicsinthissection

AddingActivitytotheObjectReactorCallbackFunctionsDesigningthegp:command-endedCallbackFunctionHandlingMultipleEntityTypesUsingActiveXMethodsinReactorCallbackFunctionsHandlingNonlinearReactorSequencesCodingthecommand-endedFunctionUpdatinggp:Calculate-and-Draw-TilesModifyingOtherCallstogp:Calculate-and-Draw-Tiles

Pleasesendusyourcommentaboutthispage

Page 170: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

AddingActivitytotheObjectReactorCallbackFunctions

InLesson6,youregisteredtwocallbackfunctionswithobjectreactorevents.Thegp:outline-erasedfunctionwasassociatedwiththe:vlr-erasedreactorevent,andgp:outline-changedwasassociatedwiththe:vlr-modifiedevent.Youneedtomakethesefunctionsdowhattheyareintendedtodo.

Tomaketheobjectreactorcallbackfunctionsdowhattheyareintendedtodo

1. Ingpreact.lsp,changegp:outline-erasedsoitappearsasfollows:

(defungp:outline-erased(outlinePolyreactorparameterList)

(setq*reactorsToRemove*

(consreactor*reactorsToRemove*))

(princ)

);_endofdefun

Thereisjustoneoperationperformedhere.Thereactorattachedtothepolylineissavedtoalistofallreactorsthatneedtoberemoved.(Remember:thoughreactorsareattachedtoentities,theyareseparateobjectsentirely,andtheirrelationshipstoentitiesneedtobemanagedjustascarefullyasregularAutoCADentities.)

2. Changegp:outline-changedtoreflectthefollowingcode:

(defungp:outline-changed(outlinePolyreactorparameterList)

(if*lostAssociativity*

(setq*reactorsToRemove*

(consreactor*reactorsToRemove*))

(setq*polytochange*outlinePoly

*reactorsToChange*(consreactor*reactorsToChange*))

)

(princ)

)

Page 171: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Therearetwocategoriesoffunctionsthatcanmodifythepolylineoutline.Thefirstcategorycontainsthosecommandsthatwillbreakthepath'sassociativitywithitstiles.Youcheckedforthisconditioningp:command-will-startandsetthe*lostAssociativity*globalvariableaccordingly.Inthiscase,thetilesneedtobeerased,andthepathisthenintheuser'shands.TheothercategoryisthegripmodeoftheSTRETCHcommand,whereassociativityisretainedandyouneedtostraightenouttheoutlineaftertheuserhasfinisheddraggingavertextoanewlocation.The*polyToChange*variablestoresaVLA-Objectpointertothepolylineitself.Thiswillbeusedinthegp:command-endedfunctionwhenitcomestimetorecalculatethepolylineborder.

Pleasesendusyourcommentaboutthispage

Page 172: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

Designingthegp:command-endedCallbackFunction

Thegp:command-endededitorreactorcallbackfunctioniswheremostactiontakesplace.Untilthisfunctioniscalled,thegardenpathborderpolylinesare“openformodify;”thatis,usersmaystillbemanipulatingthebordersinAutoCAD.Withinthereactorsequence,youhavetowaituntilAutoCADhasdoneitspartoftheworkbeforeyouarefreetodowhatyouwanttodo.

Thefollowingpseudo-codeillustratesthelogicofthegp:command-endedfunction:

Determinetheconditionofthepolyline.

CONDITION1-POLYLINEERASED(Erasecommand)

Erasethetiles.

CONDITION2-LOSTASSOCIATIVITY(Move,Rotate,etc.)

Erasethetiles.

CONDITION3-GRIP_STRETCH-REDRAWANDRE-TILE

Erasethetiles.

Getthecurrentboundarydatafromthepolyline.

Ifitisalightweightpolyline,

Processboundarydataas2D

Else

Processboundarydataas3D

Endif

Redefinethepolylineborder(passinparametersofthecurrent

boundaryconfiguration,aswellastheold).

Getthenewboundaryinformationandputitintotheformat

requiredforsettingbackintothepolylineentity.

Regeneratethepolyline.

Redrawthetiles(forceActiveXdrawing).

Puttherevisedboundaryinformationbackintothereactor

namedin*reactorsToChange*.

Endfunction

Thepseudo-codeisrelativelystraightforward,butthereareseveralimportantdetailsburiedinthepseudo-code,andtheyarethingsyouwouldnotbeexpectedtoknowatthispoint.

Page 173: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 174: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

HandlingMultipleEntityTypes

Thefirstdetailisthatyourapplicationmaydrawtwokindsofpolylines:old-styleandlightweight.Thesedifferentpolylinetypesreturntheirentitydataindifferentformats.Theold-stylepolylinereturnsalistoftwelvereals:foursetsofX,Y,andZpoints.Thelightweightpolyline,though,returnsalisteightreals:foursetsofXandYpoints.

Youneedtodosomecalculationstodeterminetherevisedpolylineboundaryafterausermovesoneofthevertices.Itwillbealoteasiertodothecalculationsifthepolylinedatahasaconsistentformat.

TheLesson7versionoftheutils.lspfilecontainsfunctionstoperformthenecessaryformatconversions:xyzList->ListOfPointsextractsandformats3Dpointlistsintoalistoflists,andxyList->ListOfPointsextractsandformats2Dpointlistsintoalistoflists.

Toaddthecodeforconvertingpolylinedataintoaconsistentformat

1. Ifyouhaveacopyofutils.lspopeninaVLISPtexteditorwindow,closeit.

2. Copytheversionofutils.lspfromtheTutorial\VisualLISP\Lesson7directoryintoyourworkingdirectory.Inadditiontothetwofunctionsthatreformatpolylinedata,utils.lspcontainsadditionalutilityfunctionsneededinhandlinguseralterationstothegardenpath.

3. Openutils.lspinaVLISPtexteditorwindowandreviewthenewcode.

Pleasesendusyourcommentaboutthispage

Page 175: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

UsingActiveXMethodsinReactorCallbackFunctions

Theseconddetailappearinginthepseudo-codeshowsupneartheend,atthestepforredrawingthetiles.Hereisthepseudo-codestatement:

Redrawthetiles(forceActiveXdrawing)

Theparentheticalphrasesaysitall:forceActiveXdrawing.Whyisthisrequired?Whycan'ttheapplicationusetheobjectcreationpreferencestoredintheassociationsublist?

Theanswerisyoucannotusethecommandfunctionforentitycreationwithinareactorcallbackfunction.ThishastodowithsomeinternalworkingsofAutoCAD.YouneedtoforcethetiledrawingroutinetouseActiveX.Youwillhearmoreaboutthisissuelaterinthislesson.

Pleasesendusyourcommentaboutthispage

Page 176: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

HandlingNonlinearReactorSequences

Thefinalimportantdetaildealswithaquirkinthecommand/reactorsequenceinAutoCADwhenusersmodifyapolylinebyusingthespecializedGRIPcommands.Thesecommands,suchasGRIP_MOVEandGRIP_ROTATE,areavailablefromashortcutmenuafteryouselectthegripofanobjectandright-click.ThereactorsequenceisnotaslinearasasimpleMOVEorERASEcommand.Ineffect,theuserischangingtoadifferentcommandwhileinthemidstofanother.Todemonstratethissituation,youcanloadthecodefromLesson6thattracesthesequenceofreactorevents.OrsimplyreviewthefollowingannotatedVLISPConsolewindowoutputtoseewhathappens:

;;Tostart,selectthepolylineandsomeofthecirclesbyusinga

;;crossingselectionbox.Theitemsintheselectionset--

;;thechosencirclesandthepolyline--arenowshownwithgripson.

;;Toinitiatethesequence,clickononeofthepolylinegrips:

(GP:COMMAND-WILL-START#<VLR-Command-reactor>(GRIP_STRETCH))

;;Nowchangethecommandtoamovebyright-clickingandchoosing

;;MOVEfromthepop-upmenu.Noticethatthecommand-ended

;;reactorfiresinordertocloseouttheGRIP_STRETCHcommand

;;withouthavingfiredanobjectreactorevent:

(GP:COMMAND-ENDED#<VLR-Command-reactor>(GRIP_STRETCH))

(GP:COMMAND-WILL-START#<VLR-Command-reactor>(GRIP_MOVE))

;;Nowdragtheoutline(andtheselectedcircles)toanewlocation.

(GP:OUTLINE-CHANGED#<VLA-OBJECTIAcadLWPolyline028f3188>

#<VLR-Object-reactor>nil)

(GP:COMMAND-ENDED#<VLR-Command-reactor>(GRIP_MOVE))

Thisdemonstratesthatyoucannotbecertainyourobjectreactorcallbackswillbecalledinallcases.

Thereisarelatedquirkinthissequence.Evenduringthefinalcommand-endedcallback,thecirclesthatarestillpartofthegripselectionsetcannotbedeleted.ThesecirclesarestillopenbyAutoCAD.Ifyouattempttoerasethemduringthecommand-endedcallback,youcancrashAutoCAD.Togetaroundthis,youcanuseanotherglobalvariabletostorealistofpointerstothetileobjectsuntilthey

Page 177: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

canbedeleted.

Toprocessnonlinearreactorsequences

1. Addthefollowingfunctiontothegpreact.lspfile:

(defungp:erase-tiles(reactor/reactorDatatilestile)

(if(setqreactorData(vlr-datareactor))

(progn

;;Tilesinthepatharestoredasdatainthereactor.

(setqtiles(cdr(assoc100reactorData)))

;;Erasealltheexistingtilesinthepath.

(foreachtiletiles

(if(and(null(membertile*Safe-to-Delete*))

(not(vlax-erased-ptile))

)

(progn

(vla-put-visibletile0)

(setq*Safe-to-Delete*(constile*Safe-to-Delete*))

)

)

)

(vlr-data-setreactornil)

)

)

)

Thisnewfunctionwillbeusedinthefirstphaseoferasingtiles.Noticethatthetilesarenotactuallyerased:theyaremadeinvisibleandareaddedtoaglobalvariablenamed*Safe-to-Delete*.

2. Addthefollowingfunctiontothegpreact.lspfile:

(defunGp:Safe-Delete(activeCommand)

(if(not(equal

(strcase(substractiveCommand15))

"GRIP_"

)

)

(progn

(if*Safe-to-Delete*

(foreachItem*Safe-to-Delete*

(if(not(vlax-erased-pItem))

(vla-eraseitem)

)

)

)

Page 178: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

(setq*Safe-to-Delete*nil)

)

)

)

ThisfunctioncanbeinvokedatatimewhenaGRIP_MOVEorGRIP_STRETCHcommandisnotbeingexecuted.

Pleasesendusyourcommentaboutthispage

Page 179: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

Codingthecommand-endedFunction

Nowthatyouhaveseenthepseudo-codeandhandledsomeimportantdetails,replacethestubbed-outcodeinthegp:command-endedreactorcallbackwiththefollowing:

(defungp:command-ended(reactorcommand-list

/objReactor

reactorToChangereactorData

coordinateValuescurrentPoints

newReactorDatanewPts

tileList

)

(cond

;;CONDITION1-POLYLINEERASED(Erasecommand)

;;Ifoneormorepolylinebordersarebeingerased(indicated

;;bythepresenceof*reactorsToRemove*),erasethetiles

;;withintheborder,thenremovethereactor.

(*reactorsToRemove*

(foreachobjReactor*reactorsToRemove*

(gp:erase-tilesobjReactor)

)

(setq*reactorsToRemove*nil)

)

;;CONDITION2-LOSTASSOCIATIVITY(Move,Rotate,etc.)

;;Ifassociativityhasbeenlost(undo,move,etc.),then

;;erasethetileswithineachborder

;;

((and*lostassociativity**reactorsToChange*)

(foreachreactorToChange*reactorsToChange*

(gp:erase-tilesreactorToChange)

)

(setq*reactorsToChange*nil)

)

;;CONDITION3-GRIP_STRETCH

;;Inthiscase,theassociativityofthetilestothepathis

;;kept,butthepathandthetileswillneedtobe

;;recalculatedandredrawn.AGRIP_STRETCHcanonlybe

;;performedonasinglePOLYLINEatatime.

Page 180: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

((and(not*lostassociativity*)

*polytochange*

*reactorsToChange*

(member"GRIP_STRETCH"command-list)

;;foraGRIP_STRETCH,therewillbeonlyonereactorin

;;theglobal*reactorsToChange*.

(setqreactorData

(vlr-data(setqreactorToChange

(car*reactorsToChange*)

)

)

)

)

;;First,erasethetileswithinthepolylineborder.

(gp:erase-tilesreactorToChange)

;;Next,getthecurrentcoordinatevaluesofthepolyline

;;vertices.

(setqcoordinateValues

(vlax-safearray->list

(vlax-variant-value

(vla-get-coordinates*polyToChange*)

)

)

)

;;Iftheoutlineisalightweightpolyline,youhave

;;2dpoints,souseutilityfunctionxyList->ListOfPoints

;;toconvertthecoordinatedataintolistsof

;;((xy)(xy)...)points.Otherwise,usethe

;;xyzList->ListOfPointsfunctionthatdeals

;;with3dpoints,andconvertsthecoordinatedatainto

;;listsof((xyz)(xyz)...)points.

(setqCurrentPoints

(if(=(vla-get-ObjectName*polytochange*)"AcDbPolyline")

(xyList->ListOfPointscoordinateValues)

(xyzList->ListOfPointscoordinateValues)

)

)

;;SendthisnewinformationtoRedefinePolyBorder--this

;;willreturnthenewPolylineBorder

(setqNewReactorData

(gp:RedefinePolyBorderCurrentPointsreactorData)

)

;;GetalltheborderPointsand...

(setqnewpts(list(cdr(assoc12NewReactorData))

(cdr(assoc13NewReactorData))

(cdr(assoc14NewReactorData))

(cdr(assoc15NewReactorData))

)

)

;;...updatetheoutlineofthepolylinewiththenewpoints

Page 181: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

;;calculatedabove.Ifdealingwithalightweightpolyline,

;;convertthesepointsto2D(sinceallthepointsin

;;newptsare3D),otherwiseleavethemalone.

(if(=(cdr(assoc4NewReactorData))"LIGHT")

(setqnewpts(mapcar'(lambda(point)

(3dPoint->2dPointPoint)

)

newpts

)

)

)

;;Nowupdatethepolylinewiththecorrectpoints.

(vla-put-coordinates

*polytochange*

;;Fordescriptionofthelist->variantArrayseeutils.lsp.

(gp:list->variantArray(apply'appendnewpts))

)

;;NowusethecurrentdefinitionoftheNewReactorData,

;;whichisreallythesameasthegardenpathdata

;;structure.Theonlyexceptionisthatthefield(100)

;;containingthelistoftilesisnil.ThisisOKsince

;;gp:Calculate-and-Draw-Tilesdoesnotrequirethisfield

;;todrawthetiles.Infactthisfunctioncreatesthetiles

;;andreturnsalistofdrawntiles.

(setqtileList(gp:Calculate-and-Draw-Tiles

;;pathdatalistwithoutcorrecttilelist

NewReactorData

;;Objectcreationfunction

;;Withinareactorthis*MUST*beActiveX

"ActiveX"

)

)

;;Nowthatyouhavereceivedallthetilesdrawn,rebuild

;;thedatastructurewiththecorrecttileListvalueand

;;resetthedatapropertyinthereactor.

;;Updatethetilesassociatedwiththepolylineborder.

(setqNewReactorData

(subst(cons100tileList)

(assoc100NewReactorData)

NewReactorData

)

)

;;Bynowyouhavethenewdataassociatedwiththepolyline.

;;Allthereislefttodoisassociateitwiththereactor

;;usingvlr-data-set.

(vlr-data-set(car*reactorsToChange*)NewReactorData)

;;Removeallreferencestothetemporary

;;variables*polytochange*and*reactorsToChange*.

(setq*polytochange*nil

*reactorsToChange*nil

Page 182: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

)

)

)

;;Deleteanyitemsinthe*Safe-to-Delete*globalifyoucan!!!

(Gp:Safe-Delete(carcommand-list))

(princ)

)

Pleasesendusyourcommentaboutthispage

Page 183: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

Updatinggp:Calculate-and-Draw-Tiles

Earlierinthislesson,itwasnotedthatyouneedtoforcegp:Calculate-and-Draw-TilestouseActiveXtocreateobjectswheninvokedfromareactorcallback.Thismeansoverridingtheobjectcreationstyle(ActiveX,entmake,orcommand)chosenbytheuser,ifnecessary.Thecodeyoujustupdated,inthegp:command-endedfunction,containsthefollowinginvocationofthetiledrawingroutine:

(setqtileList(gp:Calculate-and-Draw-Tiles

;;pathdatalistwithoutcorrecttilelist.

NewReactorData

;;Objectcreationfunction.

;;Withinareactorthis*MUST*beActiveX.

"ActiveX"

)

)

Twoparametersarepassedtogp:Calculate-and-Draw-Tiles:NewReactorData(whichisalistintheformoftheoriginalgp_PathDataassociationlist)andthestring"ActiveX"(whichwillsettheobjectcreationstyle).Buttakealookatthecurrentdefinitionofgp:Calculate-and-Draw-Tiles.(Incaseyouhaveforgotten,thisfunctionisdefinedingpdraw.lsp.)Hereisthepartofthefunctionthatdeclarestheparametersandlocalvariables:

(defungp:Calculate-and-Draw-Tiles(BoundaryData/

PathLengthTileSpace

TileRadiusSpaceFilled

SpaceToFillRowSpacing

offsetFromCenterrowStartPoint

pathWidthpathAngle

ObjectCreationStyleTileList)

Noticeonlythatoneparameteriscurrentlyspecified,andObjectCreationStyleisidentifiedasalocalvariable.Reviewhowthe

Page 184: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

ObjectCreationStylevariableisset,whichisalittlefartherintothefunction:

(setqObjectCreationStyle(strcase(cdr(assoc3BoundaryData))))

TheObjectCreationStyleiscurrentlysetinternallywithinthefunctionbyretrievingthevaluetuckedawayintheBoundaryDatavariable(theassociationlist).Butnowyouneedtobeabletooverridethatvalue.

Tomodifygp:Calculate-and-Draw-Tilestoacceptanobjectcreationstyleargument

1. AddtheObjectCreationStylevariabletothefunctionargument.

2. RemoveObjectCreationStylefromthelocalvariables.Thedefunstatementforthefunctionshouldlooklikethefollowing:

(defungp:Calculate-and-Draw-Tiles(BoundaryData

ObjectCreationStyle

/PathLengthTileSpace

TileRadiusSpaceFilled

SpaceToFileRowSpacing

offsetFromCenterrowStartPoint

pathWidthpathAngle

TileList);removeObjectCreationStylefromlocals

Notethatifyoudeclareavariablebothasaparameter(beforetheslash)andasalocalvariable(aftertheslash),VLISPwillpointthisouttoyou.Forexample,ifyoudeclareObjectCreationStyleasbothaparameterandavariable,thenusetheVLISPsyntaxcheckingtoolonthegp:Calculate-and-Draw-Tilesfunction,thefollowingmessagewillappearintheBuildOutputwindow:

;***WARNING:samesymbolbeforeandafter/inargumentslist:OBJECTCREATIONSTYLE

3. Modifythefirstsetqexpressionwithingp:Calculate-and-Draw-Tilessothatitlookslikethefollowing:

(setq

PathLength(cdr(assoc41BoundaryData))

TileSpace(cdr(assoc43BoundaryData))

TileRadius(cdr(assoc42BoundaryData))

Page 185: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

SpaceToFill(-PathLengthTileRadius)

RowSpacing(*(+TileSpace(*TileRadius2.0))

(sin(Degrees->Radians60))

)

SpaceFilledRowSpacing

offsetFromCenter0.0

offsetDistance/(+(*TileRadius2.0)TileSpace)2.0)

rowStartPointcdr(assoc10BoundaryData))

pathWidthcdr(assoc40BoundaryData))

pathAnglecdr(assoc50BoundaryData))

);_endofsetq

(if(notObjectCreationStyle)

(setqObjectCreationStyle(strcase(cdr(assoc3BoundaryData))))

)

TheoriginalassignmentstatementforObjectCreationStylehasbeenremoved.ThecodenowcheckstoseeifavaluehasbeenprovidedforObjectCreationStyle.IfObjectCreationStyleisnotset(thatis,thevalueisnil),thefunctionassignsitavaluefromtheBoundaryDatavariable.Thereisonemoreseriesofchangesyouneedtomaketogp:Calculate-and-Draw-Tiles.

Pleasesendusyourcommentaboutthispage

Page 186: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>AddingtheNewReactorFunctionality>

ModifyingOtherCallstogp:Calculate-and-Draw-Tiles

Inthereactorcallback,ahard-codedstring"ActiveX"ispassedtogp:Calculate-and-Draw-TilesastheObjectCreationStyleargument.Butwhatabouttheothertimesgp:Calculate-and-Draw-Tilesisinvoked?

IfyourememberbacktoLesson4,itwaspointedoutthatwheneveryouchangeastubbed-outfunction,youneedtoaskthefollowingquestions:

Hasthefunctioncall(invocation)changed?Thatis,doesthefunctionstilltakethesamenumberofarguments?

Doesthefunctionreturnsomethingdifferent?

Thesamequestionsneedtobeaskedanytimeyoumakeasignificantchangetoaworkingfunctionasyoubuild,refine,andupdateyourapplications.Inthiscase,youneedtofindanyotherfunctionsinyourprojectthatinvokegp:Calculate-and-Draw-Tiles.VLISPhasafeaturethathelpsyoudothis.

Tofindallcallstogp:Calculate-and-Draw-Tilesinyourproject

1. IntheVLISPtexteditorwindow,double-clickonthewordgp:Calculate-and-Draw-Tileswithinthegpdraw.lspfile.

2. ChooseSearch FindfromtheVLISPmenu.

Becauseyoupreselectedthefunctionname,itisalreadylistedasthestringtosearchfor.

3. SelecttheProjectbuttonlistedunderSearchintheFinddialogbox.Whenyouselectthisoption,theFinddialogboxexpandsatthebottom,

Page 187: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

andyoucanselecttheprojecttobesearched.

4. Specifyyourcurrentprojectname,thenchoosetheFindbutton.VLISPdisplaystheresultsintheFindoutputwindow:

5. LookattheresultsintheFindOutputwindowanddeterminewhetherthereareanyotherlocationsinyourcodewhereyoumakeacalltogp:Calculate-and-Draw-Tiles.Thereshouldonlybeone:alocationwithingpmain.lsp.

6. IntheFindOutputwindow,double-clickonthelineofcodecallinggp:Calculate-and-Draw-Tiles.VLISPactivatesatexteditorwindowandtakesyourighttothatlineofcodeingpmain.lsp.Thecodecurrentlyappearsasfollows:

(setqtilelist(gp:Calculate-and-Draw-Tilesgp_PathData))

7. Replacethelineofcodewiththefollowing:

(setqtilelist(gp:Calculate-and-Draw-Tilesgp_PathDatanil))

Whynil?Takeanotherlookatthepseudo-code:

IfObjectCreationStyleisnil,assignitfromtheBoundaryData.

Passingnilasaparametertogp:Calculate-and-Draw-Tilescausesthatfunctiontochecktheuser'schoiceofhowtodrawthetiles(asdeterminedbythedialogboxselectionandstoredingp_PathData).Subsequentcallsfromthecommand-endedreactorcallback,however,willoverridethisbehaviorbyforcingtheuseofActiveX.

Congratulations!Younowhavethebasicreactorfunctionalityinplace.Ifyouprefer,copythegpmain.lspandgpdraw.lspfilesfromtheTutorial\VisualLISP\Lesson7intoyourworkingdirectoryandexaminethecompleted,debuggedcode.

Thereisstillalotofworktobedone,anditisalltriggeredfromthisfragmentofcodeinthegp:Command-endedfunction:

(setqNewReactorData

(gp:RedefinePolyBorderCurrentPointsreactorData)

Page 188: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

);_endofsetq

Pleasesendusyourcommentaboutthispage

Page 189: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

RedefiningthePolylineBoundary

Youhaveworkedhardtogettothispoint,andyourbrainhasprobablyhadenoughnewconcepts,terms,commands,andimperativesforawhile.Withthatinmind,itisrecommendedthatyoucopythesamplecodesuppliedwiththetutorial,ratherthanenteringitonyourown.

Tocopythecodeusedtoredefinethepolylineboundary

1. Copythefilegppoly.lspfromtheTutorial\VisualLISP\Lesson7directoryintoyourworkingdirectory.

2. Intheprojectwindowforyourproject,choosetheProjectPropertiesbutton.

3. Addthegppoly.lspfiletotheproject.

4. ChooseOKtoaccepttheprojectwiththeadditionalfile.

5. Intheprojectwindow,double-clickthegppoly.lspfiletoopenit.

Topicsinthissection

LookingattheFunctionsingppoly.lspUnderstandingthegp:RedefinePolyBorderFunctionUnderstandingthegp:FindMovedPointFunctionUnderstandingthegp:FindPointInListFunctionUnderstandingthegp:recalcPolyCornersFunctionUnderstandingthegp:pointEqual,gp:rtos2,andgp:zeroSmallNumFunctions

Page 190: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Pleasesendusyourcommentaboutthispage

Page 191: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

LookingattheFunctionsingppoly.lsp

Thefilegppoly.lspcontainsanumberoffunctionsrequiredforstraighteningapolylinewhenasinglegriphasbeenstretched.Onlysomeofthesefunctionswillbeexplainedindepthinthistutorial.

Note ThissectionoftheGardenPathtutorialcontainssomeofthemostcomplexcodeandconceptsintheentirelesson.Ifyouareabeginner,youmaywanttojumpaheadtotheBuildinganApplicationsection.

Thefunctionswithinthegppoly.lspfileareorganizedinawaythatyoumayhavenoticedinotherAutoLISPsourcecodefiles.Thehighest-levelfunction,oftenthemain,orC:function(inthiscase,gp:Redefine-PolyBorder),islocatedatthebottomofthefile.Thefunctionscalledwithinthemainfunctionaredefinedaboveitwithinthesourcefile.Thisconventiongoesbacktotheolddaysofprogramming,whensomedevelopmentenvironmentsrequiredthatfilesbeorganizedthisway.WithVLISP,thisisamatterofpersonalstyle;thereisnorequirementthatyouorganizeyourfunctionsinanyspecificsequence.

Beforedivingintothedetails,stepbackandlookatwhatneedstobedonetorecalculateanddrawthegardenpathboundary.Thefollowingillustrationshowsanexampleofagardenpath,alongwiththeassociationlistkeypointsstoredinthereactordata:

Page 192: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Inthisexample,the12keypointisthelower-leftcorner,13islower-right,andsoon.Iftheusermovestheupper-rightpoint(the14keypoint),theprogramwillneedtorecalculatetwoexistingpoints—thelower-right(13)andupper-left(15).

Pleasesendusyourcommentaboutthispage

Page 193: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

Understandingthegp:RedefinePolyBorderFunction

Thefollowingpseudo-codeshowsthelogicbehindthemainfunction,gp:RedefinePolyBorder:

Functiongp:RedefinePolyBorder

Extractthepreviouspolylinecornerpoints(12,13,14,and15

keyvalues).

Findthemovedcornerpointbycomparingtheprevious

polylinecornerpointswiththecurrentcornerpoints.

(Theone"misfit"pointwillbethepointthatmoved.)

Setthenewcornerpointsbyrecalculatingthetwopoints

adjacenttothemovedpoint.

Updatethenewcornerpointsinthereactordata(thatwill

bestoredbackinthereactorforthemodifiedpolyline).

Updateotherinformationinthereactordata.(Startpoint,

endpoint,width,andlengthofpathneedtoberecalculated.)

Pleasesendusyourcommentaboutthispage

Page 194: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

Understandingthegp:FindMovedPointFunction

Thegp:FindMovedPointfunctioncontainssomeverypowerfulLISPexpressionsdealingwithlistmanipulation.Essentially,whatthisfunctiondoesiscomparethelistofthecurrentpolylinepoints(aftertheuserdraggedonetoanewlocation)tothepreviouspoints,andreturnthekeyedlist(the13<xvalue><yvalue>)forthemovedpoint.

Thebestwaytofigureouthowthisfunctionworksistostepthroughthecodeandwatchthevaluesthatitmanipulates.Setabreakpointrightatthefirstexpression(setqresult...)andwatchthefollowingvariableswhileyoustepthroughthefunction:

KeyListToLookFor

PresentPoints

KeyedList

Result

KeyListStatus

MissingKey

MovedPoint

Themapcarandlambdafunctionswillbeexaminedinthefollowingsection.Fornow,however,followthecommentsinthecodetoseeifyoucanunderstandwhatishappeningwithinthefunctions.

Pleasesendusyourcommentaboutthispage

Page 195: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

Understandingthegp:FindPointInListFunction

Thefunctionheaderinthesourcecodeexplainshowgp:FindPointInListtransformstheinformationitworkswith.Likethepreviousfunction,Gp:FindMovedPoint,thisfunctionusesLISP'slistmanipulationcapabilitiestoperformthework.Whenoperatingwithlists,youwilloftenseethemapcarandlambdafunctionsusedtogetherastheyarehere.Atfirst,thesearestrangeandconfusingfunctions,withnamesthatdonotindicatewhattheydo.Onceyoulearnhowtousethem,however,youwillfindthemtobetwoofthemostpowerfulfunctionswithintheAutoLISPrepertoire.Whatfollowsisabriefoverviewofmapcarandlambda.

Themapcarfunctionapplies(maps)anexpressiontoeveryiteminalist.Forexample,givenalistoftheintegers1,2,3,and4,mapcarcanbeusedtoapplythe1+functiontoadd1toeachnumberinthelist:

_$(mapcar'1+'(1234))(2345)

Aninitialdefinitionformapcaristhatitmapsthefunctiongiveninthefirstparametertothesuccessiveitemsinthesecondparameter—thelist.Theresultingvaluefromamapcaroperationisthelisttransformedbywhateverfunctionorexpressionwasappliedtoit.(Actually,mapcarcandomorethanthat,butfornowthisdefinitionwillsuffice.)

Inthesuppliedexample,everyvalueinthelist'(1234)waspassedtothe1+function.Essentially,mapcarperformedthefollowingoperations,assemblingtheresultingvaluesinalist:

(1+1)->2

(1+2)->3

(1+3)->4

(1+4)->5

Page 196: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Hereisanotherexampleofmapcar,thistimeusingthenullfunctiontotestwhetherornotthevaluesinalistarenull(nottrue)values:

_$(mapcar'null(list1

(=3"3")nil"Steve"))(nilTTnil)

Whathappenedinthiscodewasessentiallythefollowing:

(null1)->nil

(null(=3"3")->T

(nullnil)->T

(null"Steve")->nil

YoucanusemanyexistingAutoLISPfunctionswithinamapcar.Youcanalsouseyourownfunctions.Forexample,imagineyouhavejustcreatedaverypowerfulfunctionnamedequals2:

_$(defunequals2(num)(=

num2))EQUALS2

_$(mapcar'equals2'(1

234))(nilTnilnil)

Okay,soequals2isnotallthatpowerful.Butitisinsuchcasesthatlambdacomesinhandy.Youcanuselambdaincaseswhereyoudonotwantorneedtogothroughtheoverheadofdefiningafunction.Youwillsometimesseelambdadefinedasananonymousfunction.Forexample,insteadofdefiningafunctioncalledequals2,youcouldwritealambdaexpressiontoperformthesameoperationwithouttheoverheadofthefunctiondefinition:

_$(mapcar'(lambda(num)

(=num2))'(1234))(nilTnilnil)

Whathappenedinthecodewasthis:

(=12)->nil

(=22)->T

(=32)->nil

(=42)->nil

Page 197: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

Withthisknowledge,seeifthegp:FindPointInListfunctionmakessense.Again,reviewthecommentswithinthesourcecode.

Pleasesendusyourcommentaboutthispage

Page 198: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

Understandingthegp:recalcPolyCornersFunction

Thekeytounderstandinghowgp:recalcPolyCornersworksistorevisitthediagramshowingwhatthekeyvaluesof12through15represent:

Inthediagram,theusermovedthecornerpointassociatedwiththekeyvalueof14.Thismeansthecornerpointsassociatedwith13and15needtoberecalculated.

Point15needstobemovedalongthecurrentvectordefinedbypoint12topoint15untilitlinesupwiththenewpoint14.Thevectorsfrom12to15,andfrom14to15,mustbeperpendiculartoeachother.Thesameoperationmustbeappliedtorecalculatethenewlocationforpoint13.

Nowtakeanotherlookatthecodetoseeifitmakessense.

Pleasesendusyourcommentaboutthispage

Page 199: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>RedefiningthePolylineBoundary>

Understandingthegp:pointEqual,gp:rtos2,andgp:zeroSmallNumFunctions

ThesethreefunctionsarerequiredtogetaroundoneofthequirksofprogramminginanAutoCADsystem,which,asyouarewellaware,allowsyouagreatdealofprecision.Occasionally,though,numbersarenotquitepreciseenough,duetotheroundingupordownoffloatingpointvaluesdefininggeometricpositions.Youmustbeabletocompareonesetofpointswithotherpoints,soyoumustdealwiththesecases.

Haveyouevernoticedthatoccasionally,whenyoulisttheinformationassociatedwithanAutoCADentity,youseeavaluesuchas1.0e-017?Thisnumberisalmostzero,butwhenyouarecomparingittozerowithinaLISPprogram,almostdoesnotcount.

Withinthegardenpath,youneedtobeabletocomparenumberswithouthavingtoworryaboutthefactthat1.0e-017isnotquitezero.Thegp:pointEqual,gp:rtos2,andgp:zeroSmallNumfunctionshandleanydiscrepanciesinroundingwhencomparingpointlists.

Thiscompletesyourtourofthefunctionsingppoly.lsp.

Pleasesendusyourcommentaboutthispage

Page 200: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

WrappingUptheCode

Sofar,youhavedonethefollowinginthislesson:

Modifiedthegp:drawOutlinefunctionsothatitreturnsthepolylineperimeterpointsinadditiontothepointertothepolyline.Youaddedthisinformationtothegp_PathDatavariable.Thisvariableisstoredwiththereactordataintheobjectreactorattachedtoeverygardenpath.

Updatedthereactorfunctionsingpreact.lsp.

AddedfunctionsxyzList->ListOfPoints, xyList->ListOfPoints,andotherutilityfunctionstotheutils.lspfile.

Updatedthegp:Calculate-and-Draw-TilesfunctionsothatObjectCreationStyleisnowaparametertothefunctionratherthanalocalvariable.

Modifiedthecalltogp:Calculate-and-Draw-TilesintheC:GPathfunctionwithinthegpmain.lspfile.

Addedgppoly.lsptoyourproject,andexaminedthefunctionswithinit.

Givethecompletedapplicationatry.Saveyourwork,thenloadintheprojectsources,runtheGpathfunction,andtrystretchingandmovingthegardenpathboundary.Remember:ifsomethingisnotworkingandyouareunabletodebugtheproblem,youcanloadthecompletedcodefromtheTutorial\VisualLISP\Lesson7directory.

Pleasesendusyourcommentaboutthispage

Page 201: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

BuildinganApplication

Thefinalactwithinthistutorialistotakeyourgardenpathcodeandturnitintoastand-aloneapplication.Thisway,itcanbedistributedasasingleexecutabletoanyuserorcustomer.Fortunately,thislastsetoftasksisprobablytheeasiestinthisentiretutorial,asVLISPdoespracticallyalltheworkforyou.

Note Itisrecommendedthatyouproceedwithbuildinganapplicationonlyifyourcodeisingoodworkingform.Makesurethatyouhavetestedyourapplicationusingtheoriginalsourcefiles,andthatyouaresatisfiedwiththeresults.

Topicsinthissection

StartingtheMakeApplicationWizard

Pleasesendusyourcommentaboutthispage

Page 202: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>BuildinganApplication>

StartingtheMakeApplicationWizard

Toassistyouincreatingstandaloneapplications,VLISPprovidestheMakeApplicationwizard.

ToruntheMakeApplicationwizard

1. Tostartthewizard,chooseFile MakeApplication NewApplicationWizardfromtheVLISPmenu.

2. SelectExpertmodeandchooseNext.ThewizardpromptsyoutospecifythedirectoryinwhichtostorefilescreatedbyMakeApplication,andtonameyourapplication.MakeApplicationproducestwooutputfiles:a.vlxfilecontainingyourprogramexecutable,anda.prvfilecontainingtheoptionsyouspecifytoMakeApplication.The.prvfileisalsoknownasamakefile.Youcanusethemakefiletorebuildyourapplication,whennecessary.

3. SpecifyyourTutorial\VisualLISP\MyPathdirectoryastheapplicationlocation,andcalltheapplicationgardenpath.VLISPusestheapplicationnameintheoutputfilenames(inthisinstance,gardenpath.vlxandgardenpath.prv.)ChooseNexttocontinue.

4. Theapplicationoptionsarenotcoveredinthistutorial.AcceptthedefaultsandchooseNext.(Forinformationonseparatenamespaceapplications,see“RunninganApplicationinItsOwnNamespace”intheAutoLISPDeveloper'sGuide.)

5. Inthisstep,thewizardispromptingyoutoidentifyalltheAutoLISPsourcecodefilesthatmakeuptheapplication.YoucouldindividuallyselecttheLISPsourcefiles,butthereisaneasierway.Changethepull-downfiletypeselectionboxsothat“VisualLISPProjectfile”isshown,

Page 203: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

thenchoosetheAddbutton.SelecttheGpathprojectfileandchooseOpen.Note Dependingonhowyouworkedthroughthetutorial,youmayhaveseveralGpathprojectfilesshowingup.Selectthemostrecentfile.IfyoucopiedinthecompletedsourcecodefromLesson7,theprojectnametoselectshouldbeGpath7.prj.

Afterselectingtheprojectfile,chooseNexttocontinue.OneadvantageofcompiledVLXapplicationsisthatyoucancompileyourdialogcontrolfiles(.dcl)intothecompleteapplication.Thisreducesthenumberofindividualsourcefilesyourendusersneedtodealwith,andeliminatesanyofthesearchpathproblemswhenloadingaDCLfile.

6. Changethepull-downfiletypeselectionboxsothat“DCLfiles”isshown,thenchoosetheAddbutton.Selectthegpdialog.dclfile,thenchooseOpen.ChooseNexttocontinuebuildingtheapplication.

7. Compilationoptionsarenotcoveredinthistutorial.AcceptthedefaultsandchooseNext.(Forinformationoncompileoptions,see“OptimizingApplicationCode”intheAutoLISPDeveloper'sGuide.)

8. Thefinalstepisusedtoreviewtheselectionsyou'vemade.Atthispoint,youcanselectFinish.VLISPwillbeginthebuildprocess,displayingtheresultsintheBuildOutputwindow.Severalintermediatefileswillbeproduced,asyourindividualsourcecodefilesarecompiledintoaformatthatcanbelinkedintothesingleVLXapplication.

Whenitisallcomplete,you'llhaveanexecutablefilenamedgardenpath.vlx.Totestit,dothefollowing:

FromtheToolsmenuinAutoCAD,selectLoadApplication.

Loadthegardenpath.vlxapplicationthatwasjustcreatedandisfoundintheTutorial\VisualLISP\MyPathdirectory.

Runthegpathcommand.

Pleasesendusyourcommentaboutthispage

Page 204: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

WrappingUptheTutorial

Youhavefinallymadeittotheendofthepath!Asyouhavediscovered,alotofmaterialwascoveredinthistutorial.BothAutoLISPconceptsandVLISPoperationshavebeenintroduced.The“gardenpathrevisited”wasdesignedtogiveyouasamplingofmanytopicsandconcepts.Youmightbeinterestedinmoreinformation.ThefollowingisabriefbibliographyofsomecommonLISPandAutoLISPbooks.

Pleasesendusyourcommentaboutthispage

Page 205: Introduction - documentation.help · Introduction > Working in Visual LISP This tutorial assumes you have some familiarity with LISP or AutoLISP. It also assumes you understand basic

PuttingItAllTogether>

LISPandAutoLISPBooks

UnderstandingAutoLISP:ProgrammingforProductivity,WilliamKramer,AutodeskPress,ISBN0-8273-5832-6.

AutoLISPinPlainEnglish:APracticalGuideforNon-Programmers,GeorgeO.Head,VentanaPress,ISBN:1566041406.

LISP,3rdEdition,PatrickHenryWinstonandBertholdKlausPaulHorn,Addison-WesleyPublishingCompany,ISBN0-201-08319-1.

ANSICommonLisp,PaulGraham,PrenticeHall,ISBN0-13-370875-6.

CommonLISP,TheLanguage,SecondEdition,GuyL.Steele,Jr.,DigitalPress,ISBN1-55558-041-6.

Pleasesendusyourcommentaboutthispage


Recommended