David Bengali Posted June 13, 2020 Share Posted June 13, 2020 (edited) Wondering if anyone can advise on this - I'm having some trouble with control point precision that is leading to erroneous behavior in a plugin object. I detected this issue in part through the debugger. Basically, when I drag a control point, it seems that the values I get when I access its coordinates from inside the scripting environment are truncated to only 6 decimal places. This introduces error into calculations based on that value. I have tested further by creating an object to use as a snapping location, and setting the position of this object to coordinates that require more than 6 decimal places to represent. If I increase the decimal place precision in the document unit preferences, I can see all of these decimal places in the OIP for the reference object. If I drag a control point in my plugin object to snap to this reference object, and then, by setting a breakpoint, inspect the value I get inside my script by accessing the control point (with, for example, vs.PControlPoint01Y), I see the value is still truncated, regardless of the document unit / precision settings. At only 6 decimal places, this can introduce pretty significant error. Is there some obvious thing I am missing to correct this behavior? I would expect that when I snap a control point to a location, the control point would be assigned a value as accurate as possible, or at least as accurate as the document settings indicate. Not sure if this is specific to Python scripting or not. Edited June 15, 2020 by David Bengali discovered issue arises not just with Control Point parameters Quote Link to comment
David Bengali Posted June 15, 2020 Author Share Posted June 15, 2020 To make matters worse, if I expose the control point fields in the OIP, and turn up the decimal places document unit preference to a high value, I can see that if I snap the control point to a reference object whose position requires a large number of decimal places to represent, the PIO's control point field shows the correct value, with all the decimal places. But I just am unable to access that value from inside the scripting environment. If I expand the Globals -> vs module in the variable inspector (I am using Aptana as recommended on the wiki), the value of PControlPoint01X or PControlPoint01Y is truncated to 6 decimal places even though the OIP field shows more decimal places. I have tried changing units between feet and meters to see if that makes a difference, but it does not. In fact, this is not limited to control points (perhaps I should change the post title). For example, if I type a value with 9 decimal places into the field for a plain Number parameter, the value is accepted and displayed. But if I inspect the value of that parameter from inside the scripting environment, it has been truncated to 6 decimal places. Is this simply a (severe) limitation of scripting in Vectorworks? Or is there a way around this? Quote Link to comment
MullinRJ Posted June 16, 2020 Share Posted June 16, 2020 Hi David, I think it's a "feature" of Python, and not a limitation of VW. In VectorScript you get 15 decimals displayed for REALS. Is there a way to declare your variables as double precision REALS before you use them? If so, I'm not sure how you would do that for Control Point variables in a PIO. Raymond Quote Link to comment
David Bengali Posted June 16, 2020 Author Share Posted June 16, 2020 Hi, thanks Raymond, Just to clarify, float variables in Python do have more decimal places than this, I believe the same internal precision as REALS in VectorScript. Float's in Python are already the equivalent of double's. Can you verify that, in the case of a PIO built with VectorScript, when you access the Parameter values inside the script, you are getting all the available decimal places of precision, e.g., matching what you see in the Object Info Palette with the document unit preferences set to display 9 or more decimal places? What I am observing is not an issue of float variable precision. It specifically refers to what Vectorworks does, not to variables in general, but to PIO Parameters when it accesses them, at which point it seems to truncate the value, even when more decimal places are displayed in the Object Info Palette. I can assign a float value with greater precision than this to any variable within Python. But Vectorworks appears to have dropped that available precision when it stores Parameter values in the vs object's "P" variables, which is where we must look up these values from within the code. So, the precision is not being lost when storing the parameter value into another variable. It seems to be gone from the beginning of execution. There is no way that I know of to access Parameter values other than via vs.P[parameter name], and it does not look like there is anywhere to specify greater precision in the plugin definition parameter list, at least that I have found so far. Also to clarify, I am observing this not just with Control Point parameters, but with other Number parameters as well Quote Link to comment
Pat Stanford Posted June 16, 2020 Share Posted June 16, 2020 May I ask what units you are using and what scales where 6 digit decimal accuracy is not sufficient? My rough calculation says this is about 1/16" in 1 mile. So you are either dealing in huge dimensions or accuracy that is far higher than typical for most applications. Quote Link to comment
MullinRJ Posted June 16, 2020 Share Posted June 16, 2020 Hi David, Yes, I have seen the 6 digit rounding when using Python for PIOs. The OIP will display 10 digits, and VS functions like Concat(pRealPIOParam) will display 15 decimal places when they convert Reals to Strings. Example from a VS PIO script I am currently working on showing 15 significant digits: ControlPoint01X= 0 ControlPoint01Y= 15.8676746286034 ControlPoint02X= 0 ControlPoint02Y= 26.1038951010443 I do not have a workaround for Python. Perhaps someone else does. Raymond Quote Link to comment
David Bengali Posted June 16, 2020 Author Share Posted June 16, 2020 Hi Pat, I am working on a scale of meters and feet, and using the values of control points and other parameters to perform calculations that then determine how the object is drawn, as well as what the values of other parameters will be, in addition to the position of various control points, as a result of the math. The errors pile up surprisingly quickly with a series of relatively simple mathematical operations, which is how I discovered this issue -- in some cases I start to see numeric errors appear in the first three decimal places of results when the underlying Parameter values can only be accessed to 6 decimal places and this error propagates. Without going into to much detail, one of the main issues (but not the only one) is that this limitation also prevents control points or drawing elements whose position is driven by mathematical calculations (or even simply by the value of another parameter) from landing in the spot that one would expect when using snapping. Two drawing elements that should be in the same place in the drawing end up slightly offset, which is not what a user will expect from snapping. Since Vectorworks clearly has access itself to more precision, and can show it in the OIP, I am surprised that it prevents us from getting those values inside of a script, especially since the values are already stored in a float, which does not have this limitation intrinsically. Quote Link to comment
Pat Stanford Posted June 16, 2020 Share Posted June 16, 2020 @Vlado Can you comment on numeric accuracy in Python in VW? Quote Link to comment
Vectorworks, Inc Employee Vlado Posted June 16, 2020 Vectorworks, Inc Employee Share Posted June 16, 2020 @David Bengali oh wow, you have found a bug. I never realized this was there, yes the doubles are truncated when going from vectorworks to the python, and it is python specific. Unfortunately, we just released SP4, so it will be fixed in the next SP and the next version. Until then, you can use vs.GetRField to access the parameter values with full precision. it's a string you get back, but it has full precision number. I'm sorry for the bug, it's a sneaky thing. Thank you for reporting it! 2 Quote Link to comment
David Bengali Posted June 17, 2020 Author Share Posted June 17, 2020 Thank you @Vlado (and @Pat Stanford and @MullinRJ ) for tracking this down with me! And for the current workaround info. David Quote Link to comment
David Bengali Posted June 18, 2020 Author Share Posted June 18, 2020 Just one quick followup @Vlado - It looks to me that if a parameter is a Dimension or a Control Point, then indeed vs.GetRField returns the value with full precision. However, if the Parameter is a Number, vs.GetRField returns a string representation that is truncated at 8 decimal places, even if the value shown in the OIP has more precision. Not sure if this is related. best, David Quote Link to comment
Vectorworks, Inc Employee Vlado Posted June 19, 2020 Vectorworks, Inc Employee Share Posted June 19, 2020 23 hours ago, David Bengali said: It looks to me that if a parameter is a Dimension or a Control Point, then indeed vs.GetRField returns the value with full precision. However, if the Parameter is a Number, vs.GetRField returns a string representation that is truncated at 8 decimal places, even if the value shown in the OIP has more precision. Not sure if this is related. This is a different thing and it is intended that way. GetRField really returns a string, so it more picky of the precision. However, it is specifically implemented to preserve the precision of dimensions and control points. This is the same for both script languages. Quote Link to comment
David Bengali Posted June 19, 2020 Author Share Posted June 19, 2020 understood, thanks Quote Link to comment
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.