TheResultDirectory = "C:\\ShowcasePowerPointResults"
TheResultFile = "ShowcaseResult.pptx"
TheTemplateFile = "C:\\showcasetemplate.pptx"
TheMovieFramesPerSecond = 4
TheMovieCompression = ('Microsoft Video 1',7500)
TheMovieExtension = "avi"
TheUseRaytracing = False
TheAALevel = 4
__all__ = ['PPTFromShotsCustom', 'instantiate']
from MessageInterpreter import MessageInterpreter
from ScriptRunner import ScriptRunner
from UserCustomization import UserCustomBase, CustomInfo
from Utilities import CreateDirectory, RemoveFile
from RunInUiThread import RunInUiThread, RunInUiThreadBlock
import PowerPoint
import os.path
import ShotIO
import math
class BaseClass(ScriptRunner):
def __init__( self, scriptName, args ):
ScriptRunner.__init__( self, scriptName, args )
self.mySizes = None
self.myContactSize = None
self.myContactSizes = None
self.myItems = None
def Main( self ):
if not os.path.isdir(TheResultDirectory):
CreateDirectory(TheResultDirectory)
self.sendMessageSync( 'STATUSBAR_SET_TEXT',
(("Using template %s" % (TheTemplateFile)),))
self.process(TheResultDirectory,TheResultFile,"images",False)
RunInUiThreadBlock(self._collectSizes)
self.process(TheResultDirectory,TheResultFile,"images",True)
if self.myItems:
RunInUiThread(self.presentation)
def movie( self, width, height, file, name ):
self.sendMessageSync( 'SAVE_SHOT_AS_MOVIE_AT_RESOLUTION',
(width+width%2,
height+height%2,
TheMovieFramesPerSecond, 0,
TheAALevel, False,
file, (name,),
TheMovieCompression,
(None,None,("","",False))),
userConditions="SHOT_PLAYING_DONE",
userTimeout=3600)
def position(self,shot):
(navState,dispState) = shot.do_step(1.0)
fov = math.degrees(dispState.getFOV())
self.sendMessageSync('NAVIGATION_SET_VIEW',(navState,))
self.sendMessageSync('NAVIGATION_SET_COI',(navState.getCOI(),))
self.sendMessageSync('DISPLAY_SET_VERTICAL_FOV',(fov,False))
return (navState,dispState)
def image( self, width, height, file ):
self.sendMessageSync('SAVE_SCREENSHOT_AT_RESOLUTION',
(file,width,height,
3, TheAALevel, False,))
def _collectSizes(self):
if self.myItems:
self.announce("Template %s" % (TheTemplateFile))
p = PowerPoint.Presentation(TheTemplateFile)
p.setItems(self.myItems)
css = p.contactShapeSize()
if css:
if css[0]:
self.myContactSize = (css[1],css[2])
else:
self.myContactSizes = css[1]
self.mySizes = p.assemble(False)
self.announce("Sizes %s and %s and %s" % (str(self.myContactSize),
str(self.myContactSizes),
str(self.mySizes)))
p.closeTemplate()
p.reset()
def presentation(self):
if self.myItems:
p = PowerPoint.Presentation(TheTemplateFile)
p.setItems(self.myItems)
p.setDestination(os.path.join(TheResultDirectory,TheResultFile))
p.contact(0.25)
p.assemble(True)
p.closeTemplate()
p.saveDestination()
for toremove in p.myConsumed:
RemoveFile(toremove)
def announce( self, m ):
print m
self.sendMessage( 'STATUSBAR_SET_TEXT', (m,) )
class SynchronizedScriptShots( BaseClass ):
def __init__( self, scriptName, args ):
BaseClass.__init__( self, scriptName, args )
def process(self, imageDir, imageFile, imageRoot, create):
self.myItems = []
if self.document().has(ShotIO.id):
defaultWidth = 512
defaultHeight = 512
dashPresentDir = os.path.join(imageDir, "%s-presentation" % (os.path.splitext(imageFile)[0]))
if not os.path.isdir(dashPresentDir):
CreateDirectory(dashPresentDir)
self.announce( "Shots on %s in %s" % (imageRoot, imageDir) )
cntr = 0
for s in self.document().get(ShotIO.id).shots:
shotId = s.getName()
shotLabel = s.getLabel()
if self.mySizes:
try:
ss = self.mySizes[shotId]
shotWidth = int(ss[0])
shotHeight = int(ss[1])
except:
shotWidth = int(defaultWidth)
shotHeight = int(defaultHeight)
else:
shotWidth = int(defaultWidth)
shotHeight = int(defaultHeight)
if self.myContactSize:
thumbWidth = int(self.myContactSize[0])
thumbHeight = int(self.myContactSize[1])
elif self.myContactSizes and cntr < len(self.myContactSizes):
cs = self.myContactSizes[cntr]
thumbWidth = int(cs[0])
thumbHeight = int(cs[1])
else:
(thumbWidth,thumbHeight) = (defaultWidth,defaultHeight)
cntr += 1
fThumb = os.path.join( dashPresentDir, "%s_thumbnail_%s.%s" % (imageRoot,
s.getName(),
"jpg") )
if s.getShotType() == "ShotStill":
self.announce("Processing image from %s (%s)" % (s.getLabel(),s.getName()))
fImage = os.path.join( dashPresentDir, "%s_%s.%s" % (imageRoot,
s.getName(),
"jpg") )
shotMedia = fImage
shotMediaType = 'image'
if create:
self.announce( "Positioning %s" % (s.getLabel()) )
(navState,dispState) = self.position(s)
self.announce( "Saving image of shot %s (%s) to %s at (%d,%d) and (%d,%d)" % \
(s.getLabel(),s.getName(),shotMedia,
shotWidth,shotHeight,
thumbWidth,thumbHeight) )
self.image(shotWidth, shotHeight, fImage)
self.image(thumbWidth, thumbHeight, fThumb,)
else:
pk = s.getParameters()['Keyframe']
navState = pk[0]
dispState = pk[1]
pos = navState.getPosition()
la = navState.getLookAt()
shotTitle = shotLabel
shotThumbnail = fThumb
shotNotes = _(" Resolution %dx%d\n") % (shotWidth, shotHeight)
showcaseItem = PowerPoint.ShowcaseItem(shotId,shotLabel,shotNotes,
shotTitle,shotMedia,shotMediaType,
shotWidth,shotHeight,shotThumbnail)
self.myItems.append(showcaseItem)
else:
self.announce("Processing movie from %s (%s)" % (s.getLabel(),s.getName()))
fMovie = os.path.join( dashPresentDir, "%s_%s" % (imageRoot,s.getName()) )
shotMedia = "%s.%s" % (fMovie,TheMovieExtension)
shotMediaType = 'movie'
if create:
self.announce( "Positioning %s" % (s.getLabel()) )
self.announce( "Saving movie of shot %s (%s) to %s at (%d,%d) and (%d,%d)" % \
(s.getLabel(),s.getName(),shotMedia,
shotWidth,shotHeight,
thumbWidth,thumbHeight) )
self.movie(shotWidth, shotHeight, fMovie, s.getName())
self.image(thumbWidth, thumbHeight, fThumb)
shotTitle = shotLabel
shotThumbnail = fThumb
pk = s.getParameters()['Keyframe']
navState = pk[0]
dispState = pk[1]
pos = navState.getPosition()
la = navState.getLookAt()
shotNotes = _(" Resolution %dx%d\n") % (shotWidth, shotHeight)
showcaseItem = PowerPoint.ShowcaseItem(shotId,shotLabel,shotNotes,
shotTitle,shotMedia,shotMediaType,
shotWidth,shotHeight,shotThumbnail)
self.myItems.append(showcaseItem)
class PPTFromShotsBatch:
def instantiate( self, scriptName, args ):
return SynchronizedScriptShots( scriptName, args )
class PPTFromSlidesBatch:
def instantiate( self, scriptName, args ):
return SynchronizedScriptSlides( scriptName, args )
class PPTFromShotsCustom (UserCustomBase):
def __init__(self):
self.myCallMenu = None
self.myCallId = None
self.myInterpreter = LocalInterpreter()
def getInterpreter(self,isInteractive):
if isInteractive:
return self.myInterpreter
return None
def appendMenuItems(self,id,menu):
if "File" == id:
self.myCallMenu = menu
self.myCallId = menu.appendItem(_( 'Shots as PowerPoint' ),
self.__onPPTFromShots )
self.myCallId = menu.appendItem(_( 'Slides as PowerPoint' ),
self.__onPPTFromSlides )
def enableMenuStates(self,id,enableStates):
if "File" == id:
enableStates[self.myCallId] = True
def __onPPTFromShots( self, event ):
self.myInterpreter.PPTFromShots( event )
def __onPPTFromSlides( self, event ):
self.myInterpreter.PPTFromSlides( event )
class LocalInterpreter( MessageInterpreter ):
def __init__( self ):
MessageInterpreter.__init__( self )
def PPTFromShots( self, event ):
module = PPTFromShotsBatch()
self.sendMessage( "EXECUTE_MODULE", ("PPTExportShots", module) )
def PPTFromSlides( self, event ):
module = PPTFromSlidesBatch()
self.sendMessage( "EXECUTE_MODULE", ("PPTExportSlides", module) )
def instantiate():
return PPTFromShotsCustom()
def info():
customInfo = CustomInfo()
customInfo.vendor = 'Autodesk'
customInfo.version = '1.0'
customInfo.api = '2013'
customInfo.shortInfo = "PowerPoint presentation from Showcase shots."
customInfo.longInfo = \
"""This only works if the PowerPoint template for Showcase exists in %s. The PowerPoint will be saved in %s, as will all the original images. In general, each still shot will produce an image.
""" % (TheTemplateFile,os.path.join(TheResultDirectory,TheResultFile))
return customInfo