PoserObject2Json.py
from __future__ import print_function
import sys
import json
from collections import OrderedDict
import re
try:
    import poser
except ImportError:
    raise NotImplementedError("Script must run in Poser Python.")

__all__ = ["DONTCALL", "PoserDict", "poserobject2json", "toDict"]


class PoserDict(OrderedDict):
    pass

RE_DONTCALL = re.compile("^(_|Create|New|Dialog|Wx).*")

def toDict(poserobject):
    def resolve(_obj):
        if isinstance(_obj, (basestring, int, float)):
            return _obj
        try:
            if hasattr(_obj, "InternalName"):
                return _obj.InternalName()
            elif hasattr(_obj, "Name"):
                return _obj.Name()
        except Exception:
            pass
        return ""

    d = PoserDict()
    t = poserobject
    for test in (poser.ActorType,
                 poser.FigureType,
                 poser.ParmType,
                 poser.MaterialType,
                 poser.ShaderTreeType,
                 poser.ShaderNodeType,
                 poser.ShaderNodeInputType):
        if isinstance(poserobject, test):
            t = test
            break

    for parmname in sorted(dir(t)):
        if RE_DONTCALL.match(parmname) or parmname in DONTCALL:
            continue

        try:
            result = getattr(poserobject, parmname)()
        except Exception as err:
            continue

        if parmname == "Parent" or parmname.startswith("Current"):
            result = resolve(result)

        if isinstance(result, tuple):
            d[parmname] = tuple((resolve(_v) for _v in result))
        elif isinstance(result, list):
            d[parmname] = [resolve(_v) for _v in result]
        else:
            d[parmname] = resolve(result)

    return d


def poserobject2json(poserobject, indent=0):
    try:
        if hasattr(poserobject, "InternalName"):
            return "\"{}\": ".format(poserobject.InternalName()) + json.dumps(toDict(poserobject),
                                                                              indent=indent)

        return json.dumps(toDict(poserobject), indent=indent)
    except Exception as err:
        print(err)
        pass

    return poserobject


# Dont execute the following commands/statements while converting to dict:
DONTCALL = set(_s.strip() for _s in """ 
AddKeyFrame 
ClearLocalTransformCallback 
ClearVertexCallback 
CredManager 
CurrentFireFlyOptions 
CurrentSuperFlyOptions 
Delete 
DeleteKeyFrame 
DropToFloor 
error 
ImExporter 
LoadMaterialCollection 
LoadMorphTargetFile 
MarkGeomChanged 
Memorize 
MovieMaker 
PointAt 
RemoveValueParameter 
Reset 
Restore 
SaveMaterialCollection 
SetAlignmentRotationXYZ 
SetAmbientOcclusion 
SetAmbientOcclusionBias 
SetAmbientOcclusionDistance 
SetAmbientOcclusionStrength 
SetAnimatableOrigin 
SetAtmosphereStrength 
SetBackfaceCull 
SetBends 
SetCastsShadows 
SetCreaseAngle 
SetCustomData 
SetDisplacementBounds 
SetDisplayOrigin 
SetDisplayStyle 
SetEndPoint 
SetGeometry 
SetIncludeInBoundingBox 
SetLightAttenType 
SetLightOn 
SetLightType 
SetLocalTransformCallback 
SetMagnetAffectedObjects 
SetName 
SetNumbSubdivLevels 
SetNumbSubdivRenderLevels 
SetOnOff 
SetOrientation 
SetOrigin 
SetParameter 
SetParent 
SetRangeConstant 
SetRangeLinear 
SetRangeSpline 
SetRayTraceShadows 
SetShadingRate 
SetShadow 
SetShadowBiasMax 
SetShadowBiasMin 
SetShadowBlurRadius 
SetShadowRaytraceSoftness 
SetShadowSamples 
SetSmoothPolys 
SetSplineBreak 
SetStatic 
SetSubdivideWithFigure 
SetVertexCallback 
SetVisible 
SetVisibleInCamera 
SetVisibleInIDL 
SetVisibleInReflections 
SetVisibleInRender 
SetZoneVertexWeights 
SpawnTarget 
SpawnTargetFromGeometry 
WeldGoals 
AddClothActor 
AddCollisionActor 
AddCollisionFigure 
CalculateDyamics 
CalculateDynamics 
ClearDynamics 
Delete 
RemoveClothActor 
RemoveCollisionActor 
RemoveCollisionFigure 
SetCollisionProperty 
SetCurrentClothActor 
SetDrapingFrames 
SetDynamicsProperty 
SetEndFrame 
SetName 
SetStartFrame 
EnablePasswordSaving 
GetPassword 
SaveFacebookToken 
SavePassword 
AddButtonCallback 
SetButtonValue 
SetText 
Show 
Path 
Show 
Path 
Show 
Show 
Text 
ApplyMotionRig 
AutoGroupActor 
CheckFigureMagnets 
ClearStartupScript 
ConformTo 
ConvertToUniversalPose 
CopyJointParmsFrom 
CreateFullBodyMorph 
Delete 
DropToFloor 
FigureMeasure 
Memorize 
Reset 
Restore 
SetConformTarget 
SetCustomData 
SetDisplayStyle 
SetFollowOriginsWhenConforming 
SetIkStatus 
SetIncludeMorphsWhenConforming 
SetIncludeScalesWhenConforming 
SetIncludeTranslationsWhenConforming 
SetMatchEndpointsWhenConforming 
SetMeAsStartupScript 
SetName 
SetNumbSubdivLevels 
SetNumbSubdivRenderLevels 
SetOnOff 
SetParentActor 
SetSkinType 
SetStartupScript 
SetVisible 
StraightenBody 
SwapBottom 
SwapTop 
SymmetryBotLeftToRight 
SymmetryBotRightToLeft 
SymmetryLeftToRight 
SymmetryRightToLeft 
SymmetryTopLeftToRight 
SymmetryTopRightToLeft 
LoadPreset 
SavePreset 
SetAutoValue 
SetBucketSize 
SetDepthOfField 
SetDisplacement 
SetDisplacementBounds 
SetDrawToonOutline 
SetExtraOutput 
SetFilterSize 
SetFilterType 
SetGIIntensity 
SetGIMaxError 
SetGINumBounces 
SetGINumSamples 
SetGIOnlyRender 
SetGIPassScale 
SetGamma 
SetHDRIOutput 
SetHider 
SetManual 
SetMaxError 
SetMaxRayDepth 
SetMaxSampleSize 
SetMaxTextureRes 
SetMinShadingRate 
SetMotionBlur 
SetPixelSamples 
SetRayAccelerator 
SetRayTracing 
SetRemoveBackfacing 
SetShadowOnlyRender 
SetShadows 
SetSmoothPolys 
SetTextureCacheCompression 
SetTextureCacheSize 
SetTextureFiltering 
SetToneExposure 
SetToneGain 
SetToonOutlineStyle 
SetUseGI 
SetUseGamma 
SetUseIrradianceCache 
SetUseOcclusionCulling 
SetUseSSS 
SetUseTextureCache 
AddGeneralMesh 
Weld 
Export 
Import 
CreateLayer 
DeleteLayer 
Layer 
LayerByExtName 
LayerByName 
Layers 
LoadMaterialSet 
SaveMaterialSet 
SetAmbientColor 
SetAmbientMapFileName 
SetBumpMapFileName 
SetDiffuseColor 
SetReflectionColor 
SetReflectionMapFileName 
SetSelected 
SetSpecularColor 
SetTextureColor 
SetTextureMapFileName 
SetTransparencyMapFileName 
AddNodeChannel 
SetAttemptContinuous 
SetNodeTargets 
SetRestOrientations 
SetSwapXZ 
FlashDrawOuterLines 
MakeFlash 
MakeMovie 
OutputFormats 
SetAntialias 
SetFlashAutoPlay 
SetFlashDrawInnerLines 
SetFlashDrawOuterLines 
SetFlashLineWidth 
SetFlashNumColors 
SetFlashOverlapColors 
SetFlashQuantizeAll 
SetFlashQuantizeFrame 
SetFlashQuantizeOne 
SetFrameOptions 
SetMotionBlur 
SetMovieFormat 
SetMovieRenderer 
SetOutputEndFrame 
SetOutputRes 
SetOutputResScale 
SetOutputStartFrame 
AddKeyFrame 
AddValueOperation 
AddZone 
ApplyLimits 
ClearUpdateCallback 
DeleteKeyFrame 
DeleteValueOperation 
NumMorphTargetDeltas 
SetForceLimits 
SetHidden 
SetInternalName 
SetMorphTargetDelta 
SetName 
SetRangeConstant 
SetRangeLinear 
SetRangeSpline 
SetSensitivity 
SetSplineBreak 
SetUpdateCallback 
SetValue 
SetValueFrame 
SetWantsConform 
SplitMorphLeftRight 
IncludeInGroup 
RemoveFromGroup 
SetMaterialIndex 
AnimSet 
AntialiasNow 
ClearEventCallback 
ClearStartupScript 
ClearWorldspaceCallback 
CopyToClipboard 
CreateAnimSet 
CurrentMaterialLayer 
DeleteAnimSet 
DeleteCurrentFigure 
DeleteCurrentProp 
Draw 
DrawAll 
FrameSelected 
GroundShadows 
LoadLibraryCamera 
LoadLibraryFace 
LoadLibraryFigure 
LoadLibraryHair 
LoadLibraryHand 
LoadLibraryLight 
LoadLibraryPose 
LoadLibraryProp 
MemorizeAll 
MemorizeLights 
PmdDiff 
ProcessSomeEvents 
Render 
RenderCastShadows 
RenderIgnoreShaderTrees 
RenderInBackground 
RenderToQueue 
ResolvePendingTextures 
RestoreAll 
RestoreLights 
SaveImage 
SaveLibraryCamera 
SaveLibraryFace 
SaveLibraryFigure 
SaveLibraryHair 
SaveLibraryHand 
SaveLibraryLight 
SaveLibraryPose 
SaveLibraryProp 
SceneBBox 
SelectActor 
SelectFigure 
SelectMaterial 
SelectMaterialLayer 
SetBackgroundColor 
SetBackgroundImage 
SetBackgroundMovie 
SetChanged 
SetCurrentCamera 
SetCurrentLight 
SetCurrentRenderEngine 
SetDisplayStyle 
SetEventCallback 
SetForegroundColor 
SetFrame 
SetGeometricOutline 
SetGeometricOutlineWelding 
SetGroundColor 
SetGroundShadows 
SetMeAsStartupScript 
SetNumFrames 
SetOutputRange 
SetOutputRes 
SetRenderAntiAliased 
SetRenderBumpMaps 
SetRenderCastShadows 
SetRenderDimAutoscale 
SetRenderIgnoreShaderTrees 
SetRenderOnBGColor 
SetRenderOnBGPict 
SetRenderOnBlack 
SetRenderOverType 
SetRenderTextureMaps 
SetRenderToNewWindow 
SetResolution 
SetResolutionScale 
SetShadowColor 
SetSound 
SetSoundRange 
SetStartupScript 
SetWorldspaceCallback 
UpdateBGPreview 
WorldToScreen 
Disconnect 
InOutput 
SetAnimated 
SetColor 
SetFloat 
SetName 
SetString 
Texture 
CompoundData 
ConnectToInput 
Delete 
IsRoot 
Output 
OutputByInternalName 
SetInputsCollapsed 
SetLocation 
SetName 
SetPreviewCollapsed 
SetSelectedOutput 
AttachTreeNodes 
DeleteNode 
DetachTreeNode 
Nodes 
SetRendererRootNode 
UpdatePreview 
BranchedPathTracing 
DepthOfField 
Devices 
MotionBlur 
ProgressiveRefinement 
ReflectiveCaustics 
RefractiveCaustics 
SampleAllLightsDirect 
SampleAllLightsIndirect 
SetAOSamples 
SetBranchedPathTracing 
SetBucketSize 
SetClampDirectSamples 
SetClampIndirectSamples 
SetDepthOfField 
SetDevice 
SetDiffuseBounces 
SetDiffuseSamples 
SetFilterGlossy 
SetGlossyBounces 
SetGlossySamples 
SetMaxBounces 
SetMaxTransparentBounces 
SetMeshLightSamples 
SetMinBounces 
SetMinTransparentBounces 
SetMotionBlur 
SetPixelSamples 
SetProgressiveRefinement 
SetReflectiveCaustics 
SetRefractiveCaustics 
SetSampleAllLightsDirect 
SetSampleAllLightsIndirect 
SetSubsurfaceSamples 
SetTransmissionBounces 
SetTransmissionSamples 
SetVolumeBounces 
SetVolumeSamples 
SetU 
SetV 
SetX 
SetY 
SetZ 
ClearCommands 
ClearTextureCache 
CloseDocument 
CommandNames 
DefineMaterialWacroButton 
DefineProjGuideHTMLWidget 
DefineProjGuideScriptButton 
DefineScriptButton 
EnableParallelComputeActors 
ExecFile 
Geometry 
Gimbal 
MainWindow 
NewDocument 
OpenDocument 
PaletteById 
Palettes 
PrefsLocation 
ProcessCommand 
Quit 
Redo 
RegisterAddon 
RevertDocument 
SaveDocument 
SavePrefs 
SetCheckZeroMorphs 
SetCurrentRoom 
SetFileMetadata 
SetNumRenderThreads 
SetPreviewRenderEngineType 
SetRenderInSeparateProcess 
SetWriteBinaryMorphs 
ShowFrameRate 
SplitMorphLeftRight 
SubdivGeometry 
TempLocation 
Undo 
UnimeshInfo 
""".split())