Help with code



  • So I'm trying to both import an .obj and subsequently load a morph target to it

    Here are the codes as they are in the manual

    <NoneType> Import(<StringType> fileSuffix, <StringType> filePath,
    {<DictType> options})

    <NoneType>LoadMorphTargetFile(<StringType> FileName)

    Could just be my combined inexperience with the poser API and python in general but whenever I try it's not working. From my understanding, the following code should perform both of these functions:

    import poser
    newobj = poser.Scene.Import("OBJ","C:\Users\Pip\objtoload.obj")
    LoadMorphTargetFile("C:\Users\Pip\morphtarget.obj")
    

    But it's not working. Any help?



  • Here's my code snippet for importing an obj to the scene:

    		objExt = 'obj'
    		scene = poser.Scene()	
    		imEx = scene.ImExporter()
    		imOpt = imEx.ImportOptions( objExt, None )
    		try: # Overcome bugs in Poser Pro 11.0.7.33999 Python API constants
    			imOpt[ poser.kImOptCodeCENTERED ] = 0 # This is Centred (9001)
    			imOpt[ poser.kImOptCodePLACEONFLOOR ] = 0 # This is Place on floor (9002)
    			imOpt[ poser.kImOptCodePERCENTFIGSIZE ] = 0#100.0 # Use 0 to ignore scaling
    			imOpt[ poser.kImOptCodeSCALEABSOLUTE ] = 0.0 # This is offset X (9004)
    			imOpt[ poser.kImOptCodeOFFSETX ] = 0.0 # This is offset Y (9004)
    			imOpt[ poser.kImOptCodeOFFSETY ] = 0.0 # This is offset Z (9004)
    			imOpt[ poser.kImOptCodeOFFSETZ ] = 0 # This is Weld (9005)
    			imOpt[ poser.kImOptCodeWELDIDENTICALVERTS ] = 0 # This is Normals Consistent (9006)
    			imOpt[ poser.kImOptCodeMAKEPOLYNORMSCONSISTENT ] = 0 # This is Flip Normals (9007)
    			imOpt[ poser.kImOptCodeFLIPNORMS ] = 0 # This is Flip U (9008)
    			imOpt[ poser.kImOptCodeFLIPUTEXTCOORDS ] = 0 # This is Flip V (9009)
    			imOpt[ poser.kImOptCodeFLIPVTEXTCOORDS ] = 0 # This does nothing
    		except AttributeError: # Poser Pro 2014 has no kImOptCodeSCALEABSOLUTE attribute and no API constant bug
    			imOpt[ poser.kImOptCodeCENTERED ] = 0
    			imOpt[ poser.kImOptCodePLACEONFLOOR ] = 0
    			imOpt[ poser.kImOptCodePERCENTFIGSIZE ] = 0 # Use 0 to ignore scaling
    			imOpt[ poser.kImOptCodeOFFSETX ] = 0.0
    			imOpt[ poser.kImOptCodeOFFSETY ] = 0.0
    			imOpt[ poser.kImOptCodeOFFSETZ ] = 0.0
    			imOpt[ poser.kImOptCodeWELDIDENTICALVERTS ] = 0
    			imOpt[ poser.kImOptCodeMAKEPOLYNORMSCONSISTENT ] = 0
    			imOpt[ poser.kImOptCodeFLIPNORMS ] = 0
    			imOpt[ poser.kImOptCodeFLIPUTEXTCOORDS ] = 0
    			imOpt[ poser.kImOptCodeFLIPVTEXTCOORDS ] = 0
    		if debug or verbose:
    			print 'Import Options', imOpt
    		imEx.Import( objExt, None, objFile, imOpt )
    		newProp = scene.Actor( objName )
    

    From your code, you have several problems:
    The Scene method of the poser object needs parentheses () to identify it as a method call returning an object.
    The Import() is a method of the ImEx() object, not Scene()
    The manual entry is confusing (because it is only implicit in the example) in that it does not show the call example explicitly: i.e. ImEx.Import(...)
    The imEx.Import() call has no return value, you must subsequently select the newly imported object within the scene before you can load morph targets to it.
    The LoadMorphTargetFile() is a method of an actor, so you have to use:

    import poser
    poser.Scene().ImExporter().Import("OBJ","C:\Users\Pip\objtoload.obj")
    newobj = poser.Scene().Actor("objtoload")
    newobj.LoadMorphTargetFile("C:\Users\Pip\morphtarget.obj")
    

    Ignore all the gumph in my code dealing with the try: except:, you can just set everything to zero in the import options to get your unmodified prop loaded.

    When debugging python scripts, I find it very helpful to open the Python Shell within Poser and try out commands by hand. The auto-completion feature is also very helpful in presenting you with the parameters for a method call. If you don't see the parameter options, the method probably doesn't exist (typo) or hasn't been instanciated sufficiently for the shell to work out what you're referring to (e.g. chaining methods like poser.Scene().ImExporter().Import(...) doesn't give the shell a chance to evaluate the Scene() method call before you ask it to use one of Scene()'s internal methods, so it can be better for prototyping code to assign each method call result to a variable before executing the subsequent method call.)



  • mmm okay, it's now returning this error:

    poser.error: Error parsing Import()
    Usage: <NoneType> Import(<StringType> fileSuffix, <StringType> pluginName, <StringType> filePath, {<DictType> options})

    when running this line:

    poser.Scene().ImExporter().Import("OBJ","C:\Users\pip.obj")
    

    So I'm assuming I'm still messing up the syntax somehow? I tried in theshell and it's just thee final part (.import(...) ) that's going wrong



  • @pip.jr sorry, my bad. I was just correcting one error on that first line and overlooked the second.

    >>> help(imEx.Import())
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
    error: Error parsing Import()
    Usage: <NoneType> Import(<StringType> fileSuffix, <StringType> pluginName, <StringType> filePath, {<DictType> options})
    

    As you see from the Python shell excerpt, you can ask for syntax help on methods. The Traceback error comes because I left out all the parameters in imEx.Import(), but the important bit is in the Usage message, which shows that there are four (4) parameters for Import(), but only the first three are required (the fourth is shown in {braces}, indicating it is optional).

    In my example code, I specified all four:

    imEx.Import( objExt, None, objFile, imOpt )
    

    but in your initial version,

    newobj = poser.Scene.Import("OBJ","C:\Users\Pip\objtoload.obj")
    

    which I copied, before adding the parentheses to the Scene() method, there are only two, one short of the minimum requirement of three.

    So, you're missing the pluginName parameter, which is only necessary (apart from maintaining mandatory parameter positional order), according to the documentation, when there are multiple-different Import/Export plugins which can decode ".obj" format. I've seen others use "Wavefront" for that parameter, but personally, I just plug None in there. So your code should look like:

    import poser
    poser.Scene().ImExporter().Import("OBJ",None,"C:\Users\Pip\objtoload.obj")
    newobj = poser.Scene().Actor("objtoload")
    newobj.LoadMorphTargetFile("C:\Users\Pip\morphtarget.obj")
    

    Now, there's still one caveat to warn you about. If you don't explicitly pass in that fourth options parameter to Import, it will use whatever the default, or previously used parameters were. E.g. If you had manually selected the menu option to Import an object, and changed the scale, for instance, to 50%, every time you ran your python script in that Poser session afterwards, it would continue to import your prop at 50% of its original size. So be wary.



  • Your paths are wrong. Backslashes in Python strings need to be escaped, see https://docs.python.org/2.0/ref/strings.html

    It should read: C:\\Users\\Pip\\objtoload.obj



  • @stefan Thanks, being on Mac, that didn't immediately spring to mind.


Log in to reply
 

Looks like your connection to Graphics Forum was lost, please wait while we try to reconnect.