Here is a hook written for shotgun where you can publish the particle cache and store it in the desired location. The following hook is used like this :

1) Create a Particle flow object in 3ds max, do all the simulations and add all the force fields that are needed , complete the whole simulation.

2)Next, the following hook can be used by adding it to the hooks section of your shotgun installation and then hit on Publish Particles

3)The particle flow caching is filled up automatically and the particles are cached and stored on disk. All done automatically inside 3ds max.

Let me know if you have any questions regarding this . We have 2 different scripts , one for pre-publish and another for publish .

# Copyright (c) 2013 Shotgun Software Inc.
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit 
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your 
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights 
# not expressly granted therein are reserved by Shotgun Software Inc.

import os
import shutil
from Py3dsMax import mxs

import tank
from tank import Hook
from tank import TankError

class PublishHook(Hook):
    Single hook that implements publish functionality for secondary tasks
    def execute(self, tasks, work_template, comment, thumbnail_path, sg_task, primary_publish_path, progress_cb, **kwargs):
        Main hook entry point
        :tasks:         List of secondary tasks to be published.  Each task is a 
                        dictionary containing the following keys:
                            item:   Dictionary
                                    This is the item returned by the scan hook 
                                        name:           String
                                        description:    String
                                        type:           String
                                        other_params:   Dictionary

                            output: Dictionary
                                    This is the output as defined in the configuration - the 
                                    primary output will always be named 'primary' 
                                        name:             String
                                        publish_template: template
                                        tank_type:        String

        :work_template: template
                        This is the template defined in the config that
                        represents the current work file

        :comment:       String
                        The comment provided for the publish

        :thumbnail:     Path string
                        The default thumbnail provided for the publish

        :sg_task:       Dictionary (shotgun entity description)
                        The shotgun task to use for the publish    

        :primary_publish_path: Path string
                        This is the path of the primary published file as returned
                        by the primary publish hook

        :progress_cb:   Function
                        A progress callback to log progress during pre-publish.  Call:

                            progress_cb(percentage, msg)

                        to report progress to the UI

        :returns:       A list of any tasks that had problems that need to be reported 
                        in the UI.  Each item in the list should be a dictionary containing 
                        the following keys:
                            task:   Dictionary
                                    This is the task that was passed into the hook and
                                    should not be modified

                            errors: List
                                    A list of error messages (strings) to report    
        results = []

        # publish all tasks:
        for task in tasks:
            item = task["item"]
            output = task["output"]
            errors = []

            # report progress:
            progress_cb(0, "Publishing", task)

           # publish alembic_cache output
            if output["name"] == "particle_cache":
                self._publish_particle_cache_for_item(item, output, work_template, primary_publish_path, 
                                                     sg_task, comment, thumbnail_path, progress_cb)
             except Exception, e:
                errors.append("Publish failed - %s" % e)
                # don't know how to publish this output types!
                errors.append("Don't know how to publish this item!")

                # if there is anything to report then add to result
            if len(errors) > 0:
                # add result:
                results.append({"task":task, "errors":errors})


        return results

    def _publish_particle_cache_for_item(self, item, output, work_template, primary_publish_path, sg_task, comment, thumbnail_path, progress_cb):
        Export an Particle cache for the specified item and publish it
        to Shotgun.
        group_name = item["name"].strip("|")
        tank_type = output["tank_type"]
        publish_template = output["publish_template"]        

        # get the current scene path and extract fields from it
        # using the work template:
        scene_path = mxs.execute('maxFilePath + maxFileName')
        fields = work_template.get_fields(scene_path)
        publish_version = fields["version"]

        # update fields with the group name:
        fields["grp_name"] = group_name

        # create the publish path by applying the fields 
        # with the publish template:
        publish_path = publish_template.apply_fields(fields)
        zero_publish_path = publish_template.apply_fields(fields)

        if not os.path.exists(zero_publish_path):
            os.makedirs( os.path.dirname(zero_publish_path) )

        one_publish_path = zero_publish_path.replace("\\","\\\\")
        two_publish_path = one_publish_path

        # build and execute the Krakatoa Particle Cache command for this item:
        mxs.execute('FranticParticles.SetProperty "ParticleMode" "Save Particles To File Sequence" ')

        mxs.execute('FranticParticles.SetProperty "ParticleFiles" "%s"'%two_publish_path )
        mxs.execute('rendTimeType = 2 ')
        mxs.execute('max quick render ')

        # Finally, register this publish with Shotgun

    def _register_publish(self, path, name, sg_task, publish_version, tank_type, comment, thumbnail_path, dependency_paths=None):
        Helper method to register publish using the 
        specified publish info.
        # construct args:
        args = {
            "tk": self.parent.tank,
            "context": self.parent.context,
            "comment": comment,
            "path": path,
            "name": name,
            "version_number": publish_version,
            "thumbnail_path": thumbnail_path,
            "task": sg_task,
            "dependency_paths": dependency_paths,

        # register publish;
        sg_data = tank.util.register_publish(**args)

        return sg_data


Leave a Reply