PDA

View Full Version : Polygon iterator error



clintonman
03-24-2012, 10:24 PM
I'm trying to use the mesh info iterator to read polygon information in a scene, but I get a "LWPolID" argument error. Anyone have an idea or solution?

see ..../LightWave11.0/sdk/lwsdk11.0/html/meshinfo.html

"LWMESHITER_POLYGON"
"createMeshIterator"
"destroyMeshIterator"



#! /usr/bin/env python
# -*- Mode: Python -*-
# -*- coding: ascii -*-

"""
This is a LightWave Generic plug-in to test polygon iterator
"""

import os
import sys
import math
import lwsdk

__author__ = "Clinton Reese"
__date__ = "Mar 24 2012"
__copyright__ = "Copyright (C) 2012 Clinton's 3D Creations"
__version__ = "1.0"
__maintainer__ = "Clinton Reese"
__email__ = "[email protected]"
__status__ = "Example modified 3"
__lwver__ = "11"

#assumes a polygon mesh is in the scene
class random_test(lwsdk.IGeneric):
def __init__(self, context):
super(random_test, self).__init__()

def process(self, ga):
item_info = lwsdk.LWItemInfo()
object_info = lwsdk.LWObjectInfo()
objectID = item_info.first( lwsdk.LWI_OBJECT, lwsdk.LWITEM_NULL )
while objectID:
numPolygons = object_info.numPolygons( objectID )
if numPolygons > 0:
meshinfo = object_info.meshInfo( objectID, False )

#LWMESHITER_POLYGON - an iterator over all polygons of the mesh
iterator = meshinfo.createMeshIterator( lwsdk.LWMESHITER_POLYGON )

#LWMESHITER_POLYGON - returns an LWPolID
polygonID = meshinfo.iterateMesh( iterator )
print polygonID

nvert = meshinfo.polSize( polygonID ) #LWPolID ERROR ON THIS LINE
print nvert

meshinfo.destroyMeshIterator( iterator )

objectID = item_info.next( objectID )

return lwsdk.AFUNC_OK

# /LightWave11.0/sdk/lwsdk11.0/html/server.html
ServerTagInfo = [
( "Python RandomTest", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Random Test", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]

ServerRecord = { lwsdk.GenericFactory("LW_PyRandomTest", random_test) : ServerTagInfo }

artstorm
03-25-2012, 05:45 AM
I tried your script and iterateMesh seems to return an object of the type 'LWMTThreadID' instead of LWPolID or an object type where you can get the ID. Which would explain why polSize() won't take the object you get from the iteration as an LWPolID. So I suppose this is a reportable bug.

In the meantime scanPolys() and scanPoints() have worked fine for me, which depending on what you intend to to, will probably provide the functionality you need.

clintonman
03-25-2012, 06:38 PM
Thanks, I'll use the scanPoly/scanPoints for now

Gorbag
04-10-2012, 12:09 PM
I see the problem.

Some elements of the SDK (well, in fact, a majority of elements of the SDK) cannot be wrapped simply as they are. They need some kind of "massaging" to make them directly useful within Python. This is an example of one (of a multitude). Let me see if I can explain what is happening.

The LWMeshInfo.iterateMesh() function in the SDK has this signature:


void* (*iterateMesh)(LWMeshInfoID, LWMeshIteratorID);

As you can see, the return type is "void *". Internally, this type is wrapped literally as a concrete type, even though in C/C++ it is intended to be typeless. So when you print the return value in your script, you see something like:


_f09bba0b00000000_p_void

The "_p_void" indicates the concrete type (a pointer to a void data type). However, the LWMeshInfo.polSize() function is expecting a different type:


int (*polSize)(LWMeshInfoID, LWPolID);

Now, a compiled language like C will "auto-cast" the provided argument from its type to the target type if it is possible. So, the "void *" returned by iterateMesh() will be cast to a "LWPolID" value (which is NOT a "void *", btw) "automagically" when it is provided to that function. However, the wrapper layer for Python does no such "automagic" casting. Hence, the data types do not match, and you get the error.

Since Python has no way to "cast" data types it does not know about, this means I have to provide some explicit mechanism for converting one data type ("void *") to another ("LWPolID") in order to make this work smoothly within the Python environment.

Hope that made some sense.

Gorbag
04-10-2012, 05:21 PM
I have it fixed now. Here's the output of running your script (with some minor mods by me) on a cube in Layout:

http://www.lucidgears.com/images/iterator_001.png

The "implicit" conversion of "void *" to LWPolID (or LWEdgeID or LWPntID) is now happening in the wrapper layer using some explicit code, so you needn't do anything in your Python scripts. Here's the modification I made to your script:


...
polygonID = meshinfo.iterateMesh( iterator )
while polygonID:
nvert = meshinfo.polSize( polygonID ) #LWPolID ERROR ON THIS LINE
print polygonID, ': %d' % nvert
polygonID = meshinfo.iterateMesh( iterator )
...

Just made the actual iteration work.

clintonman
04-10-2012, 06:07 PM
So does this mean you work for Newtek and it's working in the next release of Lightwave?

Gorbag
04-10-2012, 06:19 PM
So does this mean you work for Newtek...

I've been on the project for more than 15 years now. :hey:


...and it's working in the next release of Lightwave?

Yes, it works in LightWave from this point forward.