Jef! Posted December 20, 2013 Posted December 20, 2013 Hi everyone! I'm trying to union some 3dsolids via lisp, but cant achieved it so far. Here'S the code i'm trying to debug (DEFUN C:test () (setq lastEnt(entlast)) (COMMAND "CIRCLE" "0,0,0" "1" ) (COMMAND "EXTRUDE" "L" "" ".1") (COMMAND "CIRCLE" "0,0,0" ".5" ) (COMMAND "EXTRUDE" "L" "" "-.1") (setq selSet(ssadd)) (while (setq lastEnt (entnext lastEnt)) (ssadd lastEnt selset) ) (COMMAND UNION (ssget selset)) ) There are 2 things i'm not sure: 1- What is my selset made of? 2 solids, 2 circles, or 2 circles and 2 solids? 2- Can we feed a selset to a command? Thanks for your guidance, and a merry Christmas! Jef! Quote
ReMark Posted December 20, 2013 Posted December 20, 2013 I would surmise it would be two solids. Quote
Jef! Posted December 20, 2013 Author Posted December 20, 2013 Well I guess that it is a good beginning, as the required selset i need is 2 solids. But the mystery remains... Can we feed a selset to a command? How? I think i'm very close but havn't figured yet on my own. Quote
ReMark Posted December 20, 2013 Posted December 20, 2013 I take it the user will not be making the selection themselves (ex. - selecting objects by window). Correct? Quote
Jef! Posted December 20, 2013 Author Posted December 20, 2013 exactly. The lisp make 3dsolids than union them (without any output from the user beside launching the command that.. makes the 3dsolids and union them) =) Quote
ReMark Posted December 20, 2013 Posted December 20, 2013 I'm only the night watchman here not a lisp guru but I'll see if I can find an answer to your question. Quote
Jef! Posted December 20, 2013 Author Posted December 20, 2013 meh! of course! The first thing I tried was (COMMAND UNION selset) I just cant believe I did not notice that on the FIFTH command I used on a 10 lines lisp had no quotation marks. thank you soo much gp_! Quote
Lee Mac Posted December 21, 2013 Posted December 21, 2013 Here's another route using ActiveX methods: ([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] cir1 cir2 doc reg1 reg2 sol1 sol2 spc ) ([color=BLUE]setq[/color] doc ([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color])) spc ([color=BLUE]vlax-get-property[/color] doc ([color=BLUE]if[/color] ([color=BLUE]=[/color] 1 ([color=BLUE]getvar[/color] 'cvport)) 'paperspace 'modelspace)) cir1 ([color=BLUE]vlax-invoke[/color] spc 'addcircle '(0.0 0.0 0.0) 1.0) cir2 ([color=BLUE]vlax-invoke[/color] spc 'addcircle '(0.0 0.0 0.0) 0.5) reg1 ([color=BLUE]vlax-invoke[/color] spc 'addregion ([color=BLUE]list[/color] cir1)) reg2 ([color=BLUE]vlax-invoke[/color] spc 'addregion ([color=BLUE]list[/color] cir2)) sol1 ([color=BLUE]vlax-invoke[/color] spc 'addextrudedsolid ([color=BLUE]car[/color] reg1) 0.1 0.0) sol2 ([color=BLUE]vlax-invoke[/color] spc 'addextrudedsolid ([color=BLUE]car[/color] reg2) -0.1 0.0) ) ([color=BLUE]vla-boolean[/color] sol1 [color=BLUE]acunion[/color] sol2) ([color=BLUE]foreach[/color] obj ([color=BLUE]vl-list*[/color] cir1 cir2 ([color=BLUE]append[/color] reg1 reg2)) ([color=BLUE]vla-delete[/color] obj)) ([color=BLUE]princ[/color]) ) ([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color]) Some food for thought perhaps. Quote
Jef! Posted January 7, 2014 Author Posted January 7, 2014 Hi there! Lee I just came back from 2 weeks vacations (happy new year!), and just read your reply! Here's another route using ActiveX methods:(...)Some food for thought perhaps. That is indeed quite a.. brain meal! Lisp, AutoLisp, ActiveX, man, you sure have your share of knowledge. I very much like to see the equivalent of a lisp written with Autolisp or ActiveX, and sometimes few lines can replace a bunch of lines of lisp much more efficiently, but since I'm clearly not as good as you, I tend to stick to code that I fully understand so that I can mold it to fully suit my needs. I must say that you have a way to write code so clear and simplified that quite often I fully understand it just staring at it for a few minutes. In that specific example, for instance, I can figure out that vlax-invoke needs the space as a parameter and you get it by looking at vlax-get-property of the vla-get-activedocument.. but never understood why many functions need a nested vlax-get-acad-object. I can see the necessecity of deleting the cir1 cir2 and the regions that were used to make the solids, but never would be able to write the line on my own. When I post, I make a simple example to get feedback and help faster by not asking people to analyse pages of coding. As an example, my lisp from my first post will be used to merge many solids together, and depending of the user's choices, the number will vary. Thats why I used a while to grab my selectin set; to be able to use it no matter how many solids i want to merge. I'm sure it could also be achieved via ActiveX, but would have to 100% rely on you to write it. Many "true" lispers tend to avoid using commands while creating routines, but I don't know exactly why. Maybe because I have more years of experience as a draftsman than weeks of experience as a lisper. Feel free to tell me if it aint a true-lisper-secret! =) That being said, you are most welcome to pop in any of my threads to share few thougths. One thing that I like very much from seeing examples like yours totally done "from the back", it always help! When I saw your foreach it reminded me that I almost forgot to control the DELOBJ variable! Thanks and Cheers! Jef! ps.: to clearly put into perspective where I am compared M. Lee Mac, I've updated my avatar. I hope you'll like it! ...next step => tricycle Quote
Bhull1985 Posted January 7, 2014 Posted January 7, 2014 Well I can't answer all of your questions, but from one draftsman turned lisper to another, here goes. ....but never understood why many functions need a nested vlax-get-acad-object..... The reason for this is that when you see something along the lines of.. [font=Courier New](setq mydoct (vla-get-ActiveDocument (vlax-get-acad-object)))[/font] That's the coder making a direct pointer object to the "CURRENT DRAWING" , using active-x. Basically, it reads...set a variable mydoct equal to the active document within the autocad window. Now when the active-x methods and properties are applied to this pointer, "mydoct", they will be occurring in the open autocad drawing, i.e. the current drawing. 99% of the time, this is where you want to be working in any given lisp routine, and hence seeing the call like that over and over from routine to routine. Of course you would be able to make an active-x that doesn't have this pointer, but I would expect it to be a background operation of some sort. Many "true" lispers tend to avoid using commands while creating routines, but I don't know exactly why. Well the main reason is that any given command in the autocad version that you are using has a different "COMMAND" name in well, other languages and regions- across the world that command "line" is command "linea"! And that's precisely the reason that you will rarely see a naked (command "dothis") in lisp. At the very least people use some built-in autolisp functionality to make their program universally applicable. I bet you may have seen (command "_.line") and the underscore and period are indeed doing a lot here. Rather than just linking to this blog I'll repost the relevant portions... An underscore _ This calls the English version of the command. For example, the command, _LINE, can be issued from all localized releases and English AutoCAD. A period . This calls the original command when a command was redefined. For example, whena user redefines the LINE command. In such a case, _.line can be issued from all localized releases and English AutoCAD. It will always invoke the original LINE command. A hyphen - This calls the command-line version of the command (when available). For example, _.-layer calls the command line version of the original layer command in all AutoCAD releases, independent of the localization. taken from: http://adndevblog.typepad.com/autocad/2012/10/invoking-commands-in-localized-versions.html HTH! Quote
GP_ Posted January 7, 2014 Posted January 7, 2014 ...Many "true" lispers tend to avoid using commands while creating routines, but I don't know exactly why. Maybe because I have more years of experience as a draftsman than weeks of experience as a lisper. Feel free to tell me if it aint a true-lisper-secret! =) http://cadpanacea.com/node/107 Quote
Jef! Posted January 8, 2014 Author Posted January 8, 2014 I was kind of expecting an answer like "for speed", very interesting information on that link, thanks. I used many lisps that added objects (hardware, channel/hss/pipe profiles, etc). From recalling maybe the max entities drawn by these lisps were 30-50. While it is good to see the impact on a larger scale, drawing 1000 lines with 4 different ways (command / entmake / vla-addline / vlax-invoke 'addline) **results posted by rkmcswain back in march 2010** Command: 0.797018 Entmake: 0.046992 VLA1:0.18700361 VLA2: 0.12500435 I made the same test drawing 1000 lines Command:0.382979 Entmake:0.029974 VlaAddline:0.09201318 Vlax-Invoke:0.06497651 From calculations, with my current computer, using entmake instead of drawing to draw 50 entities (which is already far far more than I'll probably ever use) would save me .00175 seconds and i'd have to use that that routine 571 times to save 1 second =) It is very good to know that entmake is roughly 15 times faster than using command because eventually, since i'm planning to use extended entity data, I'll have to dive sooner or later. It will be much simpler to use entmake and create with the extended data instead of creating via commands and have to modify it to append the extended data... I think.. I'm use to operate Autocad, and fairly new to lisps. For now I use commands and learn to master functions "around", and I want to go deeper for sure. When I create I create the global lisp structure using almost only alerts like "here i'll do that", then sunstitute alerts for functions, I draw basic shapes, then refine to draw real shape, then refine again to get a dynamic input instead of a static one, and keep going one step at the time. I probably will want to change all the commands that I can to create entities from the back, but so far I did not have any luck searching to entmake polygons. Quote
Jef! Posted January 8, 2014 Author Posted January 8, 2014 Feel free to comment my coding, I've just taken my project to the next step. So Long story short, I make many solids, create a select set than union them. (I've reverted the solid creation back to the basic example in the 1rst post of this thread to simplify your visualization.) I've simplified the selection set making process and made it as sub-commands to reuse it), and I'd like to get some comments about it! This is how it is used in the simple (updated) routine posted previously (defun c:test (/) ([color=purple]SelSetStart[/color]) (COMMAND "CIRCLE" "0,0,0" "1" ) (COMMAND "EXTRUDE" "L" "" ".1") (COMMAND "CIRCLE" "0,0,0" ".5" ) (COMMAND "EXTRUDE" "L" "" "-.1") ([color=green]SelSetEnd[/color]) (COMMAND "UNION" ([color=sienna]UseSelSet[/color]) "") ) The conds are mainly to give me feedback if I use them incorrectly. ;Jef! 2014-01-08 work in progress defun [color=purple]SelSetStart[/color] () (cond ((and ReturnSelSet)(alert "One Selection Is Pending!") ) ((and SelSetTmp)(alert "One Selection Have Already Been Started!") ) (T (setq SelSetTmp (entlast)) ) );cond );defun (defun [color=green]SelSetEnd[/color] () (cond ((and ReturnSelSet)(alert "One Selection Is Pending!") ) ((not SelSetTmp)(alert "Selection Must Be First!") ) (T (setq selSet(ssadd)) (while (setq SelSetTmp (entnext SelSetTmp)) (ssadd SelSetTmp selset) );while );end t cond );cond );defun (defun [color=sienna]UseSelSet[/color] ( / ReturnSelSet) (setq ReturnSelSet selset) (setq selset nil SelSetTmp nil);dump selset and SelSetTmp ReturnSelSet );defun What do you think? Seems like pretty nice stuff for a newbie like me that is I set all my vars, then modelize so there is anything else than drawing/extruding in between my subcommands SelSetStart and UseSelSet, but.. Should I be affraid of users using undos? Can't wait to read feedback/comments! Cheers, Jef! Quote
ymg3 Posted January 9, 2014 Posted January 9, 2014 Jef! Using " command" or "vl-cmdf" is perfectly alright, specially for those fast litlle routine. Autolisp at the onset, was to replace macro. This way you mimic a draughtman train of though. Just get in the habit of putting the "_" underscore prefix and others will be able to use your work. When you need speed, First see if you can do it with entmake. Activex does have some capacity that cannot be achieved, or are difficult to achieve with Vanilla Autolisp. You will like the curves function. Array are available in activex, not so in Vanilla etc. etc. Main point is you have lots of tools at your disposal, and you use the ones that makes the job. Congratulations! on your routine. ymg Quote
Lee Mac Posted January 12, 2014 Posted January 12, 2014 That is indeed quite a.. brain meal! Lisp, AutoLisp, ActiveX, man, you sure have your share of knowledge. Thank you Jef! - but you give me too much credit, I am unfortunately not versed in the far more powerful Common LISP, but am only conversant in the AutoLISP & Visual LISP (with ActiveX) dialects. You see, LISP refers to a family of programming languages - each of which is known as a 'dialect' of LISP. AutoLISP & Visual LISP are simply two dialects of LISP and are rather restrictive dialects at that, tailored for use with AutoCAD. As I've mentioned, there are far more powerful dialects such as Common LISP or Scheme, which are far more ubiquitous & mainstream than the specialised AutoLISP dialects. I must say that you have a way to write code so clear and simplified that quite often I fully understand it just staring at it for a few minutes. Thank you - I think good code formatting also adds a lot to the readability of the code, and personally I try to maintain a standard in my code formatting (which has varied over the years). In that specific example, for instance, I can figure out that vlax-invoke needs the space as a parameter and you get it by looking at vlax-get-property of the vla-get-activedocument.. but never understood why many functions need a nested vlax-get-acad-object. Because the vlax-get-acad-object function retrieves a pointer to the Application Object, which is the root of the AutoCAD ActiveX Object Model (known also as the Component Object Model - the 'COM' in vl-load-com). The set of open drawings is then beneath the Application Object in the object model hierarchy, and reside in the Documents Collection - a property of the Application Object. Though, for convenience, since most operations are always performed on the current drawing, rather than retrieving this object from the Documents Collection, a pointer to the Active Document Object can be retrieved directly from the Application Object via the activedocument property, as you see in my code. The ActiveX Document Object then contains further properties, allowing you to drill further down the Object Model hierarchy to access the components of the application to be manipulated by your program. When I post, I make a simple example to get feedback and help faster by not asking people to analyse pages of coding. As an example, my lisp from my first post will be used to merge many solids together, and depending of the user's choices, the number will vary. This is a good practice to follow - since we are all volunteers, many of us will not have time to trudge through reams of code, and furthermore, by demonstrating that you have taken the time and effort to target the issue in your understanding, you are far more likely to spark the interest of other members to answer your questions. On this topic, you might like to read this fantastic article on the best practices when posting to a public forum or message board. Many "true" lispers tend to avoid using commands while creating routines, but I don't know exactly why. Maybe because I have more years of experience as a draftsman than weeks of experience as a lisper. Feel free to tell me if it aint a true-lisper-secret! =) There are several reasons why most would tend to avoid calling AutoCAD commands in their programs: Calling an AutoCAD command is introducing a 'middle-man' to the program, and consequently knocking the performance of the program. For example, if you wish to create a Line object, you could call the LINE command and respond to the various command prompts by instructing the command or vl-cmdf function issue the necessary values to the command line similar to a Macro or Script (all of which would also be printed to the command-line if CMDECHO is not disabled) and the LINE command would then modify the drawing database of the active drawing to add the data for the Line to be created. However, by using entmake/entmakex/vla-addline, we can cut out this middle-man and modify the drawing database directly. AutoCAD commands can change between AutoCAD versions - some core commands become obsolete, some externals commands become core (for example, the ET layer tools), and prompt keywords & prompt order are also subject to change from version to version. Without the power of telepathy these changes cannot be accounted for when a writing a program which uses command calls, and consequently, programs can break when used in newer versions. By avoiding command calls, we can substantially reduce (though not extinguish) this risk of incompatibility. Of course, in some situations it is far more practical (and sometimes faster) to use an AutoCAD command - to give a few examples: the use of the -BOUNDARY command, or the PEDIT > JOIN functionality springs to mind. These commands could be replicated using Vanilla AutoLISP or Visual LISP without command calls, but given the amount of code required to reproduce the commands, it becomes more practical & manageable to simply call the command. That being said, you are most welcome to pop in any of my threads to share few thougths. One thing that I like very much from seeing examples like yours totally done "from the back", it always help! When I saw your foreach it reminded me that I almost forgot to control the DELOBJ variable! I try to contribute and offer my thoughts and suggestions where I feel they may be useful & welcome, though unfortunately my shortage of free time restricts the amount I can participate in the discussion. ps.: to clearly put into perspective where I am compared M. Lee Mac, I've updated my avatar. I hope you'll like it! ...next step => tricycle Remember Jef - we all started somewhere so far I did not have any luck searching to entmake polygons. These threads contain some examples: When to use entmake Various methods to construct an LWPolyline (old post) Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.