Jump to content

vs.GetPolyPt and vs.GetPolylineVertex return a bidimensional tuple (loss of z values if you had them)

Recommended Posts

It is good that I am a person with lots of patience and a good measure of endurance... after I don't really know how many days of early morning trials I finally managed to discover the reason of some heavy quirks in my [never ending] ramp project in Python, my current baby.


And here they are, for you NOT to go through the same:

  • vs.GetPolyPt and vs.GetPolylineVertex return a bidimensional tuple
  • If you passed some z values before in the third slot, you'll loose them
  • expected: set items 0 and 1, leave 2 as it is. Certainly not shorten the tuple!

The fact that these routines kill the third item is also bad for usage in the vs vector routines, such as vs.Vec2Ang, which expect a 3-items tuple.

Is this a bug or expected behaviour in Python?


Try this:

# test GetPolyPt
p = (0, 0, 0)
vs.AlrtDialog( 'init tuple: ' + str(len(p)) ) # 3 items
p = vs.GetPolyPt(vs.FSActLayer(), 1)
vs.AlrtDialog( 'after GetPolyPt: ' + str(len(p)) ) # 2 items?!?

# test GetPolylineVertex
p = (0, 0, 0)
vs.AlrtDialog( 'init tuple: ' + str(len(p)) ) # 3 items
p, vertexType, arcRadius = vs.GetPolylineVertex(vs.FSActLayer(), 1)
vs.AlrtDialog( 'after GetPolylineVertex: ' + str(len(p)) ) # 2 items?!?


Link to comment

I'm not following.

Maybe this is a python thing, but the value of your variable 'p' gets overwritten once you set it to vs.GetPolyPt(vs.FSActLayer(), 1).

The GetPolyPt function always returns a tuple of 2 values. So whatever 'p' was before will become whatever GetPolyPt gives it.



p = "Hello there"
# "Hello there"
p = (0,1,2)
# "(0,1,2)"


variables in python are dynamically typed.

Link to comment

I'm not sure the function itself shortens the variable 'p'. It overrides it completely with whatever the GetPolyPt or any other function spits out. Which in the case of the GetPolyPt is a 2-dim tuple.


So in the case of the vs.Vec2Ang() function, that particular function 'requires' a 3-dim tuple, when you are passing values from GetPolyPt into the Vec2Ang function you'd have to unpack the values you get from GetPolyPt and add a 3rd value.


p = vs.GetPolyPt(handle_to_poly, 1)
ang = vs.Vec2Ang((p[0], p[1], 0)) # the third value 0 is added by you



I think we are coming to the same conclusion, I'm just a bit thrown off by your original post stating "If you passed some z values before in the third slot, you'll loose them".

From my knowledge whatever 'p' was before you set it is overwritten with this new value and type.


I also just saw your commenting on the DevWiki which explains things very clearly.


Link to comment

Yes, I experimented extensively and added various notes and will add more in these days, hopefully this will help other Python novices.


I kept on trying to fetch vectorial data and getting abstruse nonsense values. 

The loss was due the fact that, in spite proper 3-dimensional inits:

  • both routines GetPolyPt and GetPolyLineVertex return 2-dimensional tuples, shortening if longer.
  • vector routines expect 3-dimensional tuples or return gibberish


I think that both GetPolyPt and GetPolyLineVertex should simply set the first two items and leave the third alone. It does feel wrong, when an item is deleted from a tuple.

There are scenarios where a z value is preloaded. 


But as always is rather a matter of finding an acceptable workaround (and documenting the problem), which in this case was easy.

As a principle all problems I am having in Python are due to the way vectors are accessed, manipulated and resolved. So, that overcome, all will be well.



p = vs.GetPolyPt( polyHandle, vtx1 ) # sets a tuple with 2 items in the form ( 0, 0 )
ang = vs.Vec2Ang( (p[0], p[1], 0) ) 
# make sure that there is a z coordinate or vs.Vec2Ang will fail, if p has only 2 items (VS Python only, Pascal OK )

# alternatively

if len(p) == 2:
    p += (0,) # add a 3rd item to the tuple
ang = vs.Vec2Ang( p ) # returns angle

# ang = vs.Vec2Ang( p ) # always returns 90
# ang = vs.Vec2Ang( (p[0], p[1]) ) # always returns 90






Link to comment

And thinking better: items within Python's tuples are immutable. The routines can thus only return a new tuple.

So I see these options:

  • var v = ( x, y, z ) if a vector variable is preloaded with a third item, return a new tuple whose var[2] has the preloaded var[2] value
  • var v = ( x, y ) if not, return a tuple in the form ( x, y, 0 )



Edited by _c_
  • Like 1
Link to comment

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.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...