def set_data(self, value):
        """
        Set the internal frame data using once function call.

        Expected data structure is::

            {
                'number': int or float,
                'tags': list of strs,
            }

        :param value: Data structure with both 'number' and 'tags' keys.
        :type value: dict

        :return: None
        """
        assert isinstance(value, dict)

        num = value.get('number')
        tags = value.get('tags')
        if num is None:
            msg = 'Data is not valid, number value not valid; {0}'
            msg = msg.format(value)
            raise excep.NotValid(msg)
        if tags is None:
            msg = 'Data is not valid, tags value not valid; {0}'
            msg = msg.format(value)
            raise excep.NotValid(msg)

        self.set_number(num)
        self.set_tags(tags)
        return
Beispiel #2
0
    def _compile(self, prog_fn=None, status_fn=None):
        """
        Take the data in this class and compile it into keyword argument flags.

        :return: list of keyword arguments.
        :rtype: list of dict
        """
        # TODO: Cache the compiled result internally to speed up
        # 'is_valid' then '_compile' calls.

        # If the class attributes haven't been changed, re-use the previously
        # generated arguments.
        if len(self._kwargs_list) > 0:
            return self._kwargs_list

        # Re-compile the arguments.
        kwargs_list = []
        col_node = self.get_node()

        # Check Solvers
        sol_list = self.get_solver_list()
        sol_enabled_list = filter(lambda x: x.get_enabled() is True, sol_list)
        if len(sol_enabled_list) == 0:
            msg = 'Collection is not valid, no enabled Solvers given; '
            msg += 'collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Check Markers
        mkr_list = self.get_marker_list()
        if len(mkr_list) == 0:
            msg = 'Collection is not valid, no Markers given; collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Check Attributes
        attr_list = self.get_attribute_list()
        if len(attr_list) == 0:
            msg = 'Collection is not valid, no Attributes given; collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Compile all the solvers
        for sol in sol_enabled_list:
            if sol.get_frame_list_length() == 0:
                raise excep.NotValid(msg)
            kwargs = self.__compile_solver(sol, mkr_list, attr_list)
            if isinstance(kwargs, dict):
                kwargs_list.append(kwargs)
            else:
                msg = 'Collection is not valid, failed to compile solver;'
                msg += ' collection={0}'
                msg = msg.format(repr(col_node))
                raise excep.NotValid(msg)

        # Set arguments
        self._kwargs_list = kwargs_list  # save a copy
        return self._kwargs_list
Beispiel #3
0
def collection_compile(col_node,
                       sol_list,
                       mkr_list,
                       attr_list,
                       withtest=False,
                       prog_fn=None,
                       status_fn=None):
    """
    Take the data in this class and compile it into actions to run.

    :return: list of SolverActions.
    :rtype: [SolverAction, ..]
    """
    action_list = []
    vaction_list = []
    if len(sol_list) == 0:
        msg = 'Collection is not valid, no Solvers given; '
        msg += 'collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    sol_enabled_list = [sol for sol in sol_list if sol.get_enabled() is True]
    if len(sol_enabled_list) == 0:
        msg = 'Collection is not valid, no enabled Solvers given; '
        msg += 'collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    if len(mkr_list) == 0:
        msg = 'Collection is not valid, no Markers given; collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    if len(attr_list) == 0:
        msg = 'Collection is not valid, no Attributes given; collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    # Compile all the solvers
    msg = 'Collection is not valid, failed to compile solver;'
    msg += ' collection={0}'
    msg = msg.format(repr(col_node))
    for sol in sol_enabled_list:
        assert isinstance(sol, solverbase.SolverBase)
        for action, vaction in sol.compile(mkr_list,
                                           attr_list,
                                           withtest=withtest):
            if not isinstance(action, api_action.Action):
                raise excep.NotValid(msg)
            assert action.func is not None
            assert action.args is not None
            assert action.kwargs is not None
            action_list.append(action)
            vaction_list.append(vaction)
    assert len(action_list) == len(vaction_list)
    return action_list, vaction_list
Beispiel #4
0
    def _link_to_marker_group(self, mkr_grp):
        """
        Parent a marker under a Marker Group.
        """
        assert isinstance(mkr_grp, markergroup.MarkerGroup)

        mkr_node = self.get_node()
        mkr_grp_node = mkr_grp.get_node()

        # Make sure the camera is valid for us to link to.
        if mkr_grp.is_valid() is False:
            msg = 'Cannot link Marker to Marker Group; Marker Group is not valid.'
            msg += ' marker={0} marker group={1}'
            msg = msg.format(repr(mkr_node), repr(mkr_grp_node))
            raise excep.NotValid(msg)

        # Check if we're trying to link the the camera that we're already
        # linked to.
        current_mkr_grp = self.get_marker_group()
        if current_mkr_grp is not None:
            assert isinstance(current_mkr_grp, markergroup.MarkerGroup)
            current_mkr_grp = current_mkr_grp.get_node()
            if current_mkr_grp == mkr_grp_node:
                msg = 'Marker is already linked to Marker Group, skipping.'
                msg += ' marker={0} marker group={1}'
                msg = msg.format(repr(mkr_node), repr(mkr_grp_node))
                raise excep.AlreadyLinked(msg)

        # Move the marker under the marker group, make sure the relative
        # marker attribute values are maintained.
        maya.cmds.parent(mkr_node, mkr_grp_node, relative=True)
        return
    def _link_to_camera(self, cam):
        """
        Parent a marker under the marker group which is under the given camera.
        If there is no marker group, one is created.

        :param cam: The camera to connect this Marker to.
        :type cam: None or Camera

        :returns: None
        """
        assert isinstance(cam, camera.Camera)

        mkr_node = self.get_node()
        if mkr_node is None:
            LOG.warn('Could not get Marker node. self=%r', self)
            return
        cam_tfm = cam.get_transform_node()
        cam_shp = cam.get_shape_node()

        # Make sure the camera is valid for us to link to.
        if cam.is_valid() is False:
            msg = 'Cannot link Marker to Camera; Camera is not valid.'
            msg += ' marker={0} camera={1}'
            msg = msg.format(repr(mkr_node), repr(cam_shp))
            raise excep.NotValid(msg)

        # Check if we're trying to link the the camera that we're already
        # linked to.
        current_cam = self.get_camera()
        if current_cam is not None:
            assert isinstance(current_cam, camera.Camera)
            current_cam_shp = current_cam.get_shape_node()
            if current_cam_shp == cam_shp:
                msg = 'Marker is already linked to camera, skipping.'
                msg += ' marker={0} camera={1}'
                msg = msg.format(repr(mkr_node), repr(cam_shp))
                raise excep.AlreadyLinked(msg)

        # Create Marker Group
        mkr_grp = None
        mkr_grp_nodes = maya.cmds.ls(cam_tfm, dag=True, long=True,
                                     type='mmMarkerGroupTransform') or []
        mkr_grp_nodes = sorted(mkr_grp_nodes)
        if len(mkr_grp_nodes) == 0:
            mkr_grp = markergroup.MarkerGroup().create_node(cam=cam)
        else:
            mkr_grp = markergroup.MarkerGroup(node=mkr_grp_nodes[0])

        # Link to Marker Group
        self.set_marker_group(mkr_grp)
        return
Beispiel #6
0
    def add_frame(self, frm):
        assert isinstance(frm, frame.Frame)
        key = 'frame_list'
        frm_list_data = self._data.get(key)
        if frm_list_data is None:
            frm_list_data = []

        # check we won't get a double up.
        add_frm_data = frm.get_data()
        for frm_data in frm_list_data:
            if frm_data.get('number') == add_frm_data.get('number'):
                msg = 'Frame already added to the solver, cannot add again: {0}'
                msg = msg.format(add_frm_data)
                raise excep.NotValid(msg)

        frm_list_data.append(add_frm_data)
        self._data[key] = frm_list_data
        return
Beispiel #7
0
def attributes_compile_flags(attr_list, use_animated, use_static):
    # Get Attributes
    attrs = []
    for attr in attr_list:
        assert isinstance(attr, attribute.Attribute)
        if attr.is_locked():
            continue
        name = attr.get_name()
        node_name = attr.get_node()
        attr_name = attr.get_attr()

        # If the user does not specify a min/max value then we get it
        # from Maya directly, if Maya doesn't have one, we leave
        # min/max_value as None and pass it to the mmSolver command
        # indicating there is no bound.
        min_value = attr.get_min_value()
        max_value = attr.get_max_value()
        if min_value is None:
            min_exists = maya.cmds.attributeQuery(
                attr_name,
                node=node_name,
                minExists=True,
            )
            if min_exists:
                min_value = maya.cmds.attributeQuery(
                    attr_name,
                    node=node_name,
                    minimum=True,
                )
                if len(min_value) == 1:
                    min_value = min_value[0]
                else:
                    msg = 'Cannot handle attributes with multiple '
                    msg += 'minimum values; node={0} attr={1}'
                    msg = msg.format(node_name, attr_name)
                    raise excep.NotValid(msg)

        if max_value is None:
            max_exists = maya.cmds.attributeQuery(
                attr_name,
                node=node_name,
                maxExists=True,
            )
            if max_exists is True:
                max_value = maya.cmds.attributeQuery(
                    attr_name,
                    node=node_name,
                    maximum=True,
                )
                if len(max_value) == 1:
                    max_value = max_value[0]
                else:
                    msg = 'Cannot handle attributes with multiple '
                    msg += 'maximum values; node={0} attr={1}'
                    msg = msg.format(node_name, attr_name)
                    raise excep.NotValid(msg)

        # Scale and Offset
        scale_value = None
        offset_value = None
        attr_type = maya.cmds.attributeQuery(attr_name,
                                             node=node_name,
                                             attributeType=True)
        if attr_type.endswith('Angle'):
            offset_value = 360.0

        animated = attr.is_animated()
        static = attr.is_static()
        use = False
        if use_animated and animated is True:
            use = True
        if use_static and static is True:
            use = True
        if use is True:
            attrs.append((name, str(min_value), str(max_value),
                          str(offset_value), str(scale_value)))
    return attrs
Beispiel #8
0
    def _compile(self, prog_fn=None, status_fn=None):
        """
        Take the data in this class and compile it into keyword argument flags.

        :return: list of keyword arguments.
        :rtype: list of dict
        """
        # TODO: Cache the compiled result internally to speed up
        # 'is_valid' then '_compile' calls.

        # If the class attributes haven't been changed, re-use the previously
        # generated arguments.
        if len(self._kwargs_list) > 0:
            return self._kwargs_list

        # Re-compile the arguments.
        kwargs_list = []
        col_node = self.get_node()

        # Check Solvers
        sol_list = self.get_solver_list()
        sol_enabled_list = [sol for sol in sol_list
                            if sol.get_enabled() is True]
        if len(sol_enabled_list) == 0:
            msg = 'Collection is not valid, no enabled Solvers given; '
            msg += 'collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Check Markers
        mkr_list = self.get_marker_list()
        if len(mkr_list) == 0:
            msg = 'Collection is not valid, no Markers given; collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Check Attributes
        attr_list = self.get_attribute_list()
        if len(attr_list) == 0:
            msg = 'Collection is not valid, no Attributes given; collection={0}'
            msg = msg.format(repr(col_node))
            raise excep.NotValid(msg)

        # Compile all the solvers
        for i, sol in enumerate(sol_enabled_list):
            if sol.get_frame_list_length() == 0:
                msg = 'Collection is not valid, no frames to solve;'
                msg += ' collection={0}'
                msg = msg.format(repr(col_node))
                raise excep.NotValid(msg)
            kwargs = self.__compile_solver(sol, mkr_list, attr_list)

            debug_file = maya.cmds.file(query=True, sceneName=True)
            debug_file = os.path.basename(debug_file)
            debug_file, ext = os.path.splitext(debug_file)
            # TODO: Find a way to set the default directory path.
            debug_file_path = os.path.join(
                os.path.expanduser('~/'),
                debug_file + '_' + str(i).zfill(6) + '.log')
            if len(debug_file) > 0 and debug_file_path is not None:
                kwargs['debugFile'] = debug_file_path

            if isinstance(kwargs, dict):
                kwargs_list.append(kwargs)
            else:
                msg = 'Collection is not valid, failed to compile solver;'
                msg += ' collection={0}'
                msg = msg.format(repr(col_node))
                raise excep.NotValid(msg)

        # Set arguments
        self._kwargs_list = kwargs_list  # save a copy
        return self._kwargs_list
Beispiel #9
0
    def __compile_solver(self, sol, mkr_list, attr_list, prog_fn=None):
        """
        Compiles data given into flags for a single run of 'mmSolver'.

        :param sol: The solver to compile
        :type sol: Solver

        :param mkr_list: Markers to measure
        :type mkr_list: list of Marker

        :param attr_list: Attributes to solve for
        :type attr_list: list of Attribute

        :param prog_fn: Progress Function, with signature f(int)
        :type prog_fn: function

        :return: The keyword arguments for the mmSolver command.
        :rtype: None or dict
        """
        assert isinstance(sol, solver.Solver)
        assert isinstance(mkr_list, list)
        assert isinstance(attr_list, list)
        assert sol.get_frame_list_length() > 0

        kwargs = dict()
        kwargs['camera'] = []
        kwargs['marker'] = []
        kwargs['attr'] = []
        kwargs['frame'] = []

        # Get Markers and Cameras
        added_cameras = []
        markers = []
        cameras = []
        for mkr in mkr_list:
            assert isinstance(mkr, marker.Marker)
            mkr_node = mkr.get_node()
            assert isinstance(mkr_node, basestring)
            bnd = mkr.get_bundle()
            if bnd is None:
                msg = 'Cannot find bundle from marker, skipping; mkr_node={0}'
                msg = msg.format(repr(mkr_node))
                LOG.warning(msg)
                continue
            bnd_node = bnd.get_node()
            if bnd_node is None:
                msg = 'Bundle node is invalid, skipping; mkr_node={0}'
                msg = msg.format(repr(mkr_node))
                LOG.warning(msg)
                continue
            cam = mkr.get_camera()
            if cam is None:
                msg = 'Cannot find camera from marker; mkr={0}'
                msg = msg.format(mkr.get_node())
                LOG.warning(msg)
            cam_tfm_node = cam.get_transform_node()
            cam_shp_node = cam.get_shape_node()
            assert isinstance(cam_tfm_node, basestring)
            assert isinstance(cam_shp_node, basestring)
            markers.append((mkr_node, cam_shp_node, bnd_node))
            if cam_shp_node not in added_cameras:
                cameras.append((cam_tfm_node, cam_shp_node))
                added_cameras.append(cam_shp_node)
        if len(markers) == 0:
            LOG.warning('No Markers found!')
            return None
        if len(cameras) == 0:
            LOG.warning('No Cameras found!')
            return None

        # Get Attributes
        use_animated = sol.get_attributes_use_animated()
        use_static = sol.get_attributes_use_static()
        attrs = []
        for attr in attr_list:
            assert isinstance(attr, attribute.Attribute)
            if attr.is_locked():
                continue
            name = attr.get_name()
            node_name = attr.get_node()
            attr_name = attr.get_attr()

            # If the user does not specify a min/max value then we get it
            # from Maya directly, if Maya doesn't have one, we leave
            # min/max_value as None and pass it to the mmSolver command
            # indicating there is no bound.
            min_value = attr.get_min_value()
            max_value = attr.get_max_value()
            if min_value is None:
                min_exists = maya.cmds.attributeQuery(
                    attr_name,
                    node=node_name,
                    minExists=True,
                )
                if min_exists:
                    min_value = maya.cmds.attributeQuery(
                        attr_name,
                        node=node_name,
                        minimum=True,
                    )
                    if len(min_value) == 1:
                        min_value = min_value[0]
                    else:
                        msg = 'Cannot handle attributes with multiple '
                        msg += 'minimum values; node={0} attr={1}'
                        msg = msg.format(node_name, attr_name)
                        raise excep.NotValid(msg)

            if max_value is None:
                max_exists = maya.cmds.attributeQuery(
                    attr_name,
                    node=node_name,
                    maxExists=True,
                )
                if max_exists is True:
                    max_value = maya.cmds.attributeQuery(
                        attr_name,
                        node=node_name,
                        maximum=True,
                    )
                    if len(max_value) == 1:
                        max_value = max_value[0]
                    else:
                        msg = 'Cannot handle attributes with multiple '
                        msg += 'maximum values; node={0} attr={1}'
                        msg = msg.format(node_name, attr_name)
                        raise excep.NotValid(msg)

            animated = attr.is_animated()
            static = attr.is_static()
            use = False
            if use_animated and animated is True:
                use = True
            if use_static and static is True:
                use = True
            if use is True:
                attrs.append((name, str(min_value), str(max_value)))
        if len(attrs) == 0:
            LOG.warning('No Attributes found!')
            return None

        # Get Frames
        frm_list = sol.get_frame_list()
        frame_use_tags = sol.get_frames_use_tags()
        frames = []
        for frm in frm_list:
            num = frm.get_number()
            tags = frm.get_tags()
            use = False
            if len(frame_use_tags) > 0 and len(tags) > 0:
                for tag in frame_use_tags:
                    if tag in tags:
                        use = True
                        break
            else:
                use = True
            if use is True:
                frames.append(num)
        if len(frames) == 0:
            LOG.warning('No Frames found!')
            return None

        kwargs['marker'] = markers
        kwargs['camera'] = cameras
        kwargs['attr'] = attrs
        kwargs['frame'] = frames

        solver_type = sol.get_solver_type()
        if solver_type is not None:
            kwargs['solverType'] = solver_type

        iterations = sol.get_max_iterations()
        if iterations is not None:
            kwargs['iterations'] = iterations

        verbose = sol.get_verbose()
        if verbose is not None:
            kwargs['verbose'] = verbose

        delta_factor = sol.get_delta_factor()
        if delta_factor is not None:
            kwargs['delta'] = delta_factor

        auto_diff_type = sol.get_auto_diff_type()
        if auto_diff_type is not None:
            kwargs['autoDiffType'] = auto_diff_type

        tau_factor = sol.get_tau_factor()
        if tau_factor is not None:
            kwargs['tauFactor'] = tau_factor

        gradient_error_factor = sol.get_gradient_error_factor()
        if gradient_error_factor is not None:
            kwargs['epsilon1'] = gradient_error_factor

        parameter_error_factor = sol.get_parameter_error_factor()
        if parameter_error_factor is not None:
            kwargs['epsilon2'] = parameter_error_factor

        error_factor = sol.get_error_factor()
        if error_factor is not None:
            kwargs['epsilon3'] = error_factor

        # msg = 'kwargs:\n' + pprint.pformat(kwargs)
        # LOG.debug(msg)
        return kwargs
Beispiel #10
0
    def create_node(self,
                    name='marker1',
                    colour=None,
                    cam=None,
                    mkr_grp=None,
                    bnd=None):
        """
        Create a marker node network from scratch.

        :param name: Name of the marker to create.
        :type name: str

        :param colour: Colour of marker as R, G and B.
                       'None' will leave as default.
        :type colour: (float, float, float) or None

        :param cam: The camera to create the marker underneath.
        :type cam: Camera

        :param mkr_grp: The marker group to create the marker underneath.
        :type mkr_grp: MarkerGroup

        :param bnd: The bundle to attach to the newly created marker.
        :type bnd: Bundle

        :return: Marker object with newly created node.
        :rtype: Marker
        """
        assert isinstance(name, (str, unicode))
        if cam is not None:
            if mkr_grp is not None:
                msg = 'Cannot specify both camera and marker group, '
                msg += 'please choose only one.'
                raise excep.NotValid(msg)
            assert isinstance(cam, camera.Camera)
        if mkr_grp is not None:
            if cam is not None:
                msg = 'Cannot specify both camera and marker group, '
                msg += 'please choose only one.'
                raise excep.NotValid(msg)
            assert isinstance(mkr_grp, markergroup.MarkerGroup)
        if bnd is not None:
            assert isinstance(bnd, mmSolver._api.bundle.Bundle)
        if colour is not None:
            assert isinstance(colour, (tuple, list))
            assert len(colour) == 3

        # Transform
        tfm = maya.cmds.createNode(const.MARKER_TRANSFORM_NODE_TYPE, name=name)
        tfm = node_utils.get_long_name(tfm)
        maya.cmds.setAttr(tfm + '.tz', -1.0)
        maya.cmds.setAttr(tfm + '.tz', lock=True)
        maya.cmds.setAttr(tfm + '.rx', lock=True)
        maya.cmds.setAttr(tfm + '.ry', lock=True)
        maya.cmds.setAttr(tfm + '.rz', lock=True)
        maya.cmds.setAttr(tfm + '.sx', lock=True)
        maya.cmds.setAttr(tfm + '.sy', lock=True)
        maya.cmds.setAttr(tfm + '.sz', lock=True)
        maya.cmds.setAttr(tfm + '.shxy', lock=True)
        maya.cmds.setAttr(tfm + '.shxz', lock=True)
        maya.cmds.setAttr(tfm + '.shyz', lock=True)
        maya.cmds.setAttr(tfm + '.tz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.rx', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.ry', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.rz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sx', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sy', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.shxy', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.shxz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.shyz', keyable=False, channelBox=False)

        # Shape Node
        shp_name = tfm.rpartition('|')[-1] + 'Shape'
        shp = maya.cmds.createNode(const.MARKER_SHAPE_NODE_TYPE,
                                   name=shp_name,
                                   parent=tfm)
        maya.cmds.setAttr(shp + '.localScaleX', 0.01)
        maya.cmds.setAttr(shp + '.localScaleY', 0.01)
        maya.cmds.setAttr(shp + '.localScaleZ', 0.0)
        maya.cmds.setAttr(shp + '.localScaleZ', lock=True)

        # Add attrs
        _create_marker_attributes(tfm)

        src = '{0}.{1}'.format(tfm, const.MARKER_ATTR_LONG_NAME_ENABLE)
        dst = '{0}.{1}'.format(tfm, 'lodVisibility')
        maya.cmds.connectAttr(src, dst)

        self.set_node(tfm)

        # Set Colour (default is red)
        if colour is not None:
            self.set_colour_rgb(colour)
        else:
            red = (1.0, 0.0, 0.0)
            self.set_colour_rgb(red)

        # Link to Camera
        if cam is not None:
            self.set_camera(cam)

        # Link to MarkerGroup
        if mkr_grp is not None:
            self.set_marker_group(mkr_grp)

        # Link to Bundle
        if bnd is not None:
            self.set_bundle(bnd)

        return self
Beispiel #11
0
    def create_node(self,
                    name='marker1',
                    colour=None,
                    cam=None,
                    mkr_grp=None,
                    bnd=None):
        """
        Create a marker node network from scratch.

        :param name: Name of the marker to create.
        :type name: str

        :param colour: Colour of marker as R, G and B.
                       'None' will leave as default.
        :type colour: (float, float, float) or None

        :param cam: The camera to create the marker underneath.
        :type cam: Camera

        :param mkr_grp: The marker group to create the marker underneath.
        :type mkr_grp: MarkerGroup

        :param bnd: The bundle to attach to the newly created marker.
        :type bnd: Bundle

        :return: Marker object with newly created node.
        :rtype: Marker
        """
        assert isinstance(name, (str, unicode))
        if cam is not None:
            if mkr_grp is not None:
                msg = 'Cannot specify both camera and marker group, '
                msg += 'please choose only one.'
                raise excep.NotValid(msg)
            assert isinstance(cam, camera.Camera)
        if mkr_grp is not None:
            if cam is not None:
                msg = 'Cannot specify both camera and marker group, '
                msg += 'please choose only one.'
                raise excep.NotValid(msg)
            assert isinstance(mkr_grp, markergroup.MarkerGroup)
        if bnd is not None:
            assert isinstance(bnd, mmSolver._api.bundle.Bundle)
        if colour is not None:
            assert isinstance(colour, (tuple, list))
            assert len(colour) == 3

        # Transform
        tfm = maya.cmds.createNode('transform', name=name)
        tfm = api_utils.get_long_name(tfm)
        maya.cmds.setAttr(tfm + '.tz', -1.0)
        maya.cmds.setAttr(tfm + '.tz', lock=True)
        maya.cmds.setAttr(tfm + '.rx', lock=True)
        maya.cmds.setAttr(tfm + '.ry', lock=True)
        maya.cmds.setAttr(tfm + '.rz', lock=True)
        maya.cmds.setAttr(tfm + '.sx', lock=True)
        maya.cmds.setAttr(tfm + '.sy', lock=True)
        maya.cmds.setAttr(tfm + '.sz', lock=True)
        maya.cmds.setAttr(tfm + '.tz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.rx', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.ry', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.rz', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sx', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sy', keyable=False, channelBox=False)
        maya.cmds.setAttr(tfm + '.sz', keyable=False, channelBox=False)

        # Shape Node
        shp_name = tfm.rpartition('|')[-1] + 'Shape'
        shp = maya.cmds.createNode('locator', name=shp_name, parent=tfm)
        maya.cmds.setAttr(shp + '.localScaleX', 0.01)
        maya.cmds.setAttr(shp + '.localScaleY', 0.01)
        maya.cmds.setAttr(shp + '.localScaleZ', 0.0)
        maya.cmds.setAttr(shp + '.localScaleZ', lock=True)

        # Add attrs
        maya.cmds.addAttr(tfm,
                          longName='enable',
                          at='short',
                          minValue=0,
                          maxValue=1,
                          defaultValue=1)
        maya.cmds.addAttr(tfm,
                          longName='weight',
                          at='double',
                          minValue=0.0,
                          defaultValue=1.0)
        maya.cmds.addAttr(tfm, longName='bundle', at='message')
        maya.cmds.addAttr(tfm, longName='markerName', dt='string')
        maya.cmds.addAttr(tfm, longName='markerId', at='long', defaultValue=-1)

        maya.cmds.setAttr(tfm + '.enable', keyable=True, channelBox=True)
        maya.cmds.setAttr(tfm + '.weight', keyable=True, channelBox=True)
        maya.cmds.setAttr(tfm + '.markerName', lock=True)
        maya.cmds.connectAttr(tfm + '.enable', tfm + '.lodVisibility')

        self.set_node(tfm)

        # Set Colour (default is red)
        if colour is not None:
            self.set_colour_rgb(colour)
        else:
            red = (1.0, 0.0, 0.0)
            self.set_colour_rgb(red)

        # Link to Camera
        if cam is not None:
            self.set_camera(cam)

        # Link to MarkerGroup
        if mkr_grp is not None:
            self.set_marker_group(mkr_grp)

        # Link to Bundle
        if bnd is not None:
            self.set_bundle(bnd)

        return self
Beispiel #12
0
def collection_compile(col,
                       sol_list,
                       mkr_list,
                       attr_list,
                       withtest=False,
                       prog_fn=None,
                       status_fn=None):
    """
    Take the data in this class and compile it into actions to run.

    :return: list of SolverActions.
    :rtype: [SolverAction, ..]
    """
    col_node = col.get_node()
    action_list = []
    vaction_list = []
    if len(sol_list) == 0:
        msg = 'Collection is not valid, no Solvers given; '
        msg += 'collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    sol_enabled_list = [sol for sol in sol_list if sol.get_enabled() is True]
    if len(sol_enabled_list) == 0:
        msg = 'Collection is not valid, no enabled Solvers given; '
        msg += 'collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    if len(mkr_list) == 0:
        msg = 'Collection is not valid, no Markers given; collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    if len(attr_list) == 0:
        msg = 'Collection is not valid, no Attributes given; collection={0}'
        msg = msg.format(repr(col_node))
        raise excep.NotValid(msg)

    # Query and cache static values from Maya, so we don't need to
    # re-compute the values inside Solvers.
    attr_static_values = get_attributes_static_values(col, attr_list)
    attr_stiff_static_values = get_attr_stiffness_static_values(col, attr_list)
    attr_smooth_static_values = get_attr_smoothness_static_values(
        col, attr_list)
    mkr_static_values = get_markers_static_values(mkr_list)
    precomputed_data = {
        solverbase.MARKER_STATIC_VALUES_KEY: mkr_static_values,
        solverbase.ATTR_STATIC_VALUES_KEY: attr_static_values,
        solverbase.ATTR_STIFFNESS_STATIC_VALUES_KEY: attr_stiff_static_values,
        solverbase.ATTR_SMOOTHNESS_STATIC_VALUES_KEY:
        attr_smooth_static_values,
    }

    # Compile all the solvers
    msg = 'Collection is not valid, failed to compile solver;'
    msg += ' collection={0}'
    msg = msg.format(repr(col_node))
    for sol in sol_enabled_list:
        assert isinstance(sol, solverbase.SolverBase)
        sol.set_precomputed_data(precomputed_data)
        for action, vaction in sol.compile(col,
                                           mkr_list,
                                           attr_list,
                                           withtest=withtest):
            if not isinstance(action, api_action.Action):
                raise excep.NotValid(msg)
            assert action.func is not None
            assert action.args is not None
            assert action.kwargs is not None
            action_list.append(action)
            vaction_list.append(vaction)
    assert len(action_list) == len(vaction_list)
    return action_list, vaction_list
Beispiel #13
0
def attributes_compile_flags(col,
                             attr_list,
                             use_animated,
                             use_static,
                             attr_static_values=None):
    """
    Compile Attributes into flags for mmSolver.

    :param col: Collection to be used for min/max values,
    :type col: Collection

    :param attr_list: List of Attributes to compile
    :type attr_list: [Attribute, ..]

    :param use_animated: Should we compile Attributes that are animated?
    :type use_animated: bool

    :param use_static: Should we compile Attributes that are static?
    :type use_static: bool

    :param attr_static_values: Attribute static values that can optionally
        be used to speed up compiling.

    :returns:
        List of tuples. Attributes in a form to be given to the
        mmSolver command.
    :rtype: [(str, str, str, str, str), ..]
    """
    assert isinstance(use_animated, bool)
    assert isinstance(use_static, bool)
    if attr_static_values is None:
        attr_static_values = dict()
    assert isinstance(attr_static_values, dict)

    attrs = []
    for attr in attr_list:
        assert isinstance(attr, attribute.Attribute)
        name = attr.get_name()
        attr_cache = DictGetOrCall(attr_static_values.get(name, dict()))

        locked = attr_cache.get_or_call('is_locked', attr.is_locked)
        if locked is True:
            continue

        node_name = attr_cache.get_or_call('node_name', attr.get_node)
        attr_name = attr_cache.get_or_call('attr_name', attr.get_attr)

        # If the user does not specify a min/max value then we get it
        # from Maya directly, if Maya doesn't have one, we leave
        # min/max_value as None and pass it to the mmSolver command
        # indicating there is no bound.

        # Minimum Value
        min_value = None
        min_enable = attr_cache.get_or_call(
            'solver_min_enable', lambda: col.get_attribute_min_enable(attr))
        if min_enable is True:
            min_value = attr_cache.get_or_call(
                'solver_min_value', lambda: col.get_attribute_min_value(attr))
        maya_min_exists = attr_cache.get_or_call(
            'maya_min_exists',
            lambda: _get_maya_min_exists_from_attr(node_name, attr_name))
        if maya_min_exists is True:
            maya_min_value = attr_cache.get_or_call(
                'maya_min_value',
                lambda: _get_maya_min_value_from_attr(node_name, attr_name))
            if len(maya_min_value) == 1:
                maya_min_value = maya_min_value[0]
            else:
                msg = 'Cannot handle attributes with multiple '
                msg += 'minimum values; node={0} attr={1}'
                msg = msg.format(repr(node_name), repr(attr_name))
                raise excep.NotValid(msg)
            if min_value is None:
                min_value = maya_min_value
            else:
                min_value = max(min_value, maya_min_value)

        # Maximum Value
        max_value = None
        max_enable = attr_cache.get_or_call(
            'solver_max_enable', lambda: col.get_attribute_max_enable(attr))
        if max_enable is True:
            max_value = attr_cache.get_or_call(
                'solver_max_value', lambda: col.get_attribute_max_value(attr))
        maya_max_exists = attr_cache.get_or_call(
            'maya_max_exists',
            lambda: _get_maya_max_exists_from_attr(node_name, attr_name))
        if maya_max_exists is True:
            maya_max_value = attr_cache.get_or_call(
                'maya_max_value',
                lambda: _get_maya_max_value_from_attr(node_name, attr_name))
            if len(maya_max_value) == 1:
                maya_max_value = maya_max_value[0]
            else:
                msg = 'Cannot handle attributes with multiple '
                msg += 'maximum values; node={0} attr={1}'
                msg = msg.format(repr(node_name), repr(attr_name))
                raise excep.NotValid(msg)
            if max_value is None:
                max_value = maya_max_value
            else:
                max_value = min(max_value, maya_max_value)

        # Scale and Offset
        scale_value = None
        offset_value = None
        attr_type = attr_cache.get_or_call(
            'attribute_type',
            lambda: _get_attribute_type_from_attr(node_name, attr_name))
        if attr_type.endswith('Angle'):
            offset_value = 360.0

        animated = attr_cache.get_or_call('is_animated', attr.is_animated)
        static = attr_cache.get_or_call('is_static', attr.is_static)
        use = False
        if use_animated and animated is True:
            use = True
        if use_static and static is True:
            use = True
        if use is True:
            attrs.append((name, str(min_value), str(max_value),
                          str(offset_value), str(scale_value)))
    return attrs