AutoCAD Visual LISP / AutoLISP :: ANGTOS Return Accurate Result For Number If Decimal Places Requested
Jan 5, 2012
I work with ANGTOS and ANGTOF quite a bit. I'm working with latitude and longitude conversions in MAP 3D for an application where accuracy is top priority. Most of the time ANGTOS (and RTOS, for that matter) return an accurate result for the number if decimal places requested, but then I run into a situation like this:
How to change the number of decimal places of the elevation of points?
as the points are labeled with their elevations, I couldn’t find how the number of the decimal places of the elevation be chosen. In this case, I wanted to let the number of the decimal places to be zero.
How to set the number of the decimal places to be zero or 1, for example? how to sepcify it height (size)?
I have a couple of strange angles and moving parts going on in an assembly. there is 1 constraint i am happy for inventor to predict the offset for. the problem is I am using other constraints i later want to bin, to pin it in position then try to apply this constraint. it looks like the predict offset tick box only measures to 3 dp, so as soon as i apply this constraint my model goes sick. I have to take a measurment and copy and place the measurment with all dp's into the constraint to make it work.
Is there a setting to specify the predict offset number of decimal places?
The defaul label style for the Elevation of points is set to 3 decimal places. We are trying to change the elevation display to 2 decimal places. We have tried the directions in the following discussion: [URL].......
Which is:
Toolspace
->Settings -->Drawing name --->Edit Drawing Settings ---->Ambient Settings ----->Elevation ------>Precision -> We modify from 3 to 2 decimal places.
It does not modify the display settings.
Also:
Toolspace
->Settings -->Drawing --->Point ---->Label Styles ----->(right-click) Edit label styles ------>Layout ------->Text -------->Contents --------->click on the "..." (three points) button
(Open "Text Component Editor - Contents"
--------->Select Point Elevation in the driop down list. ---------->Precision: Set to 0.01 ------------>Ok, Apply, etc...
I have a number like 4534.3245 If I say 4534.3245 as Integer I get 4534 thats fine.
Is there an easy way in maxscript to return the number after the decimal only no matter what it is? like saying: 4534.3245 as fraction returns .3245?
With the numbers I am dealing with the integer part could be any size and fraction decimal section could be any size so I am hoping for a general rule or method for getting that after decimal number.
when I try things like formattedprint there is a rounding off happening changing it to .3245 to .3247 and more digits added etc but I dont want all that because it is changing the value of the number before I have even done anything with it. Maybe their is a formattedprint method but I am not seeing it.
Is there a way to find the name of the second folder?
Is there a way to find the name of the third folder?
The string length of the characters for each of the first, second, third (and so on) folders are different, which means I can't count character using the "substr" function.
I recently wrote a lisp routine that was supposed to get the 4 coordinates of a rectangle (LWPolyline). It worked fine in *MY* tests. But when someone else ran it, the routine operated as though the order of the points had been rearranged.
How can I get the points AND the order in which they belong?
Here's a sketch to show you what I mean. As part of my troubleshooting, I had a lisp routine draw a new pline using the points gathered by my first routine. The result of that on the left. On the right is the result of that when someone else runs the two routines.
I need to return the entity name of the largest (longest closed) polyline in a selection set. At this point I have no trouble creating the selection set and even getting the area of the boundingbox, which is not the most accurate way to find the true size, but it's a start. The part that has me stumped is: if I iterate through the selection set, then how can I compare one to the other when I have access to the current entity. I've been staring at examples of lambdas but it seems to me that iterating through the selection set is going about it wrong in the first place.
Below is my current code with a remaining issue. I can return the largest area of the polylines (no good for more than two entities in selection set), but I do not know how to return the entity name:
(IF (> (SETQ SS (SSGET "x" '((0 . "*POLYLINE") (8 . "POOL") (-4 . "<OR") (62 . 5) (62 . 256) (-4 . "OR>")))) 1 ) (PROGN (SETQ a (1- a) ent (CDR (CAR (SSNAME ss a))) en2 (CDR (CAR (SSNAME ss (1- a)))) ar1 (APPLY '* (LIST (LAMBDA (ent) (VLAX-INVOKE-METHOD (VLAX-ENAME->VLA-OBJECT ent) 'getboundingbox 'minpt 'maxpt) (SETQ pt1 [code]......
(layoutlist) ... returns a list of strings of the layout tabs in the drawing.I've used this ages... Isn't it a core lisp function, or is it coming from express tools or somewhere else?
I've got a subroutine that gets the centroid of a closed polygon (lwpoly). It appears to fail if the polygon has any zero length line segments. I've added a trap that catches the error and "highlights" the offending polygon, but it stops there and does not return to the main function that called the subroutine. Is there a way to get back to the main function from the trap?
Here's the subroutine (original function by _gile (Autodesk LISP Forum 9-18-2006):
(defun return-centroid (lwpoly space / obj Region Centroid) (setq *error* trap1) (setq obj (vlax-ename->vla-object lwpoly)) (setq Region (vlax-invoke space 'addRegion (list obj))) (setq Centroid (trans (vlax-get (car Region) 'Centroid) 1 0)) (vla-delete (car Region))
As you smart individuals can figure out, we do up drawing packages for construction that consist of several drawings, hundreds of drawings, for several modules of construction. Our process usually consists of one layout per drawing, so that the lisp guy can do a drawing count and put in sheet numbers based on how I manipulate the list of drawings in the one directory folder.
Now I have a client, despite the way we currently do things, requires that about 70% of the drawings will have multiple layouts. Now we're back in the stone ages, manually putting in sheet numbers, eating up our budget for this contract.
The Field dialog box has an item for CurrentSheetNumber with field expression: %<AcSm Sheet.Number>%
Is it possible to create a Field to display the Next Sheet Number (CurrentSheetNumber + 1) and a Field to display the Previous Sheet Number (CurrentSheetNumber - 1)?
I have the need to make the current open dwg (name) equal to its predefined number in a large list. For example, building66.dwg is equal to 123789. I’ll have a large list in a tab delimited txt file with the example below. I can put the list in the lsp file if needed. Something like (if (getvar "dwgname") make equal to listname) and go out to the list and return its number. Seems kind of easy but I can’t make it happen.
I have a simple hexagon block with one attribute, i need to be able to copy it and as i do it increases the number by one.
the Block name is note1-2006 the attribute name is NOTENUM. I have tried using some other Lisps but i cant ge them to work. Sometimes i have to put 40 of these on a sketch i hate copying and changing the attribute by one everytime. so it would be nice to copy and as i pick mutliple spots it increase number. Dont know if there is a way to ask user to keep same number or increase. This would save me so much time.
I have a simple block that consists of a point and an attribute that contains the point number. I want to generate a table with point number from the attribute, and x, y and z of the block's insertion point. I want a routine that sets out the blocks and then create the table. The first part of the routine I have (in LISP), I need it to generate the table. I was intended to use the -DATA EXTRACTION but unfortunately it does not allow me to select objects (blocks). Are there other ways to do this? I'm using AutoCAD 2011.
I currently have a LISP routine that will replace the value of a specific attribute name with sequential numbers in the order that the blocks are selected. Like TCOUNT for attributes - and it only looks for a specific attribute Tag Name called "ID".
However, what I want it to do now, instead of just putting the number into the attribute value, I want the number to be a suffix to the existing default tag value of the tag named "ID" which is "ADDRESS:" for some blocks and "ELEVATION:" for other blocks but the tag name that the routine always has to filter for is "ID". That way the user can pick anywhere on the block - not being forced to pick the tag we want to add numbers to.
What I need the new LISP to do is append a space and then a number to the existing tag value in the block, so that the result would look like "ADDRESS: 1", "ADDRESS: 2", "ADDRESS 3" or "ELEVATION: 1", ELEVATION: 2", etc. depending on whatever the default value for the tag "ID" is.
there are several hundred different block names - but they all have a Tag Name of "ID" - whose default value is sometimes "ADDRESS:" and sometimes "ELEVATION:".
I am basically trying to determine how many lines are in the mutliline attribute. I have abandoned the idea of directly trying to find the the number of lines and have moved on to trying to fine the height of the multiline attribute. I have included the lisp and sample drawing that will draw a box of the boundingbox around the mutiline attribute.
This block as originally a dynamic block that different visual states. I have tried using the bounding box option on the block itself, however, if there are blocks hidden with the visual state, it will draw the bounding box according to the largest element in dynamic block every time. So I need to determine the height of the multiline attributes instead and adjust the dynamic block accordingly.
I am modifying stuff in a dynamic block insert entity. There is no "endblk" entity at the end of these definitions and I need to cycle through every entity within the block definition. When it gets to the last entity, I get an error because you cannot entnext passed the last entity. There are 2 things:
1. How to retrieve the # of entities in a block without cycling through it. Or 2. A quick lesson in the *error* function, I cannot figure out how to implement this. I basically want to to say:
(if (entnext myent)) returns a error, don't abort & continue on.
I am looking for a way to extract (filter) all polylines, and loop a lisp based on the number that are found within a "W" selection window.I am frustrated getting "malformed list" or errors, even after defining "n" for repeat.The code I have so far looks like this:
Without the (repeat () portion, it was working ok with selection window, however it only would run the commands for a single polyline. What needs to be done without overhauling the code? The lisp has worked on a drawing-wide basis, however needs to run on only on user-windowed polylines since there are other polylines within the drawing which are attached to layouts via viewports.
(defun layun (target_obj / original_layer original_layer_info target_obj_atts new_layer )(setqoriginal_layer (cdr (assoc 8 (entget target_obj)))original_layer_info (tblsearch "layer" original_layer)target_obj_atts (entget target_obj));setq(if (or(wcmatch original_layer "*-P123"); REMOVES 4 CHARACTERS(wcmatch original_layer "*-P123456"); REMOVES 7 CHARACTERS(wcmatch original_layer "*-P123456789"); REMOVES 10 CHARACTERS );or(progn(setq new_layer (substr original_layer 1 (- (strlen original_layer) ??))) ; NEED TO ASSIGN VARIABLE TO MATCH THE NUMBER OF CHARACTERS TO REMOVE(if (not (tblsearch "layer" new_layer))(progn(entmake ;;;begin to make new layer(list'(0 . "LAYER")'(100 . "AcDbSymbolTableRecord")'(100 . "AcDbLayerTableRecord")(cons 2 new_layer) ;;; layer name(assoc 6 original_layer_info) ;;;re-use original linetype'(70 . 0) ;;;flags - use default flags(assoc 62 original_layer_info) ;;;re-use original color);list);entmake);progn);if(entmod (subst (cons 8 new_layer) (assoc 8 target_obj_atts) target_obj_atts)));progn);if);defun
assign a character where ? is shown so that it matches with the number of characters to remove based on the 3 lines above (see wcmatch lines). At present, whatever number I replace that ?? with, it removes that number of characters from the layer that I selected (if it meets that WCMATCH criteria). Another option which may be more difficult is to be able to have the routine look at the object layer and if it contains -N- or -D- or -NEW- or -DEMO- then to remove all the characters that follow these layer modifiers. This way I can cleanly add another project modifier behind these modifers.
I am wanting to get a separate block to load if a third number is entered when prompted. If enter is hit or only 2 of the numbers are entered, load the other block. I couldn't even get it to do right by even equaling a specific number.
I am running AutoCAD Map 3D 2011. When i use the ID command to acquire x,y coordinates by snapping to an object, it gives me only one decimal place. When i do the command out in space, it gives me 4 decimal spaces. I need to get at least two decimal places while snapping to objects. Examples below:
id command (out in space, not using osnap)
X = 4006431.3366 Y = 359556.5635
id command (snapping to entity)
X = 4006252.3000 Y = 360712.5000
by the way, my units precision is set to .00 and it doesnt seem to make any difference with the id command.
I have used stringer connect in the past and it seemed that my traverse shots (which went to four decimal places 0.0000) that were in my raw file were converted to a fbk file and it held the decimal places. Now when I use it, the program rounds my shots to three decimal places (0.000) which changes the locations just slightly. I don't think I changed any settings deliberately. How can I get my four decimal places back?
My professor wants all of our dimensions to have 2 decimals places except for a few that he wants to have 3 decimal places. How do I change those few to have 3 places while everything else has 2?
Why does the Round() function require that the number of decimal places be either a number or an object if you want to use a variable? It seems that a Single should work here, but iLogic won't accept it.
See sample code below which is rounding off dimension values. If I dim the variable "somenumber" as Single or Double, I get this error message from the Round() function: "Overload resolution failed because no accessible 'Round' can be called without a narrowing conversion."
When I dim "somenumber" as an object it works, but this seems unnecessary when all it is storing is a single digit number. Why wouldn't Single or Double work for this variable?
Here's the code snippet:
'Dim Current Sketch & Count Constraints Dim oSketch As Sketch = ThisApplication.ActiveEditObject Dim oDimCount As Single = oSketch.DimensionConstraints.Count