# -*- coding: utf-8 -*- """ :author: Jeremy Ernst :description: This module contains the class for defining the bipedal leg component. The biped leg component consists of at minimum, 3 joints: the thigh, calf, and foot. There are also options for 3 twist joints in the upper and lower leg areas as well as having a ball and toe joint (which it does by default). """ import artv2.components.base_components.base_component as base import artv2.utilities.general_utilities as utils import artv2.utilities.error_utilities as errors import artv2.utilities.component_utilities as component_utils class BipedLeg(base.ART_Component): """ This class defines and creates a bipedal leg component. The biped leg component consists of at minimum, 4 joints: the thigh, calf, foot, and ball. There are also options for 3 twist joints in the upper and lower leg areas as well as having a ball and toe joint (which it does by default). """ nice_name = "Biped Leg" category = "Limbs" base_name = "leg" has_sides = True can_overwrite_names = True joint_mover_file = "resources\\rigging_guides\\leg_biped.ma" mirror_table = {"translateX": -1, "translateY": -1, "translateZ": -1, "rotateX": 1, "rotateY": 1, "rotateZ": 1} # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # def _add_metadata(self, network_node, prefix, suffix): """ Method for adding metadata attributes to the network node that are important for the module. For the leg module, these are things like number of toe joints and twist joints. :param (str) network_node: module's network node name to add attributes to. :param (str) prefix: prefix for the module. :param (str) suffix: suffix for the module. """ super(BipedLeg, self)._add_metadata(network_node, prefix, suffix) network_node.unlock() network_node.addAttr("num_thigh_twists", min=0, max=3, dv=0, keyable=False) network_node.addAttr("num_calf_twists", min=0, max=3, dv=0, keyable=False) network_node.addAttr("has_ball_joint", at="bool", dv=True, keyable=False) network_node.num_thigh_twists.set(lock=True) network_node.num_calf_twists.set(lock=True) network_node.has_ball_joint.set(lock=True) network_node.lock() # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @property def num_thigh_twists(self): """ This property holds the number (int) of thigh twist joints that the module will create or has. example usage: .. code-block:: python leg_inst = biped_leg.BipedLeg() leg_inst.num_thigh_twists = 2 :return: Number of thigh twist joints the module has. :rtype: int """ return self.network_node.num_thigh_twists.get() @num_thigh_twists.setter def num_thigh_twists(self, new_number): self.set_twist_joints("num_thigh_twists", new_number, 0, 3, "thigh_twist_0") # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @property def num_calf_twists(self): """ This property holds the number (int) of calf twist joints that the module will create or has. example usage: .. code-block:: python leg_inst = biped_leg.BipedLeg() leg_inst.num_calf_twists = 2 :return: Number of calf twist joints the module has. :rtype: int """ return self.network_node.num_calf_twists.get() @num_calf_twists.setter def num_calf_twists(self, new_number): self.set_twist_joints("num_calf_twists", new_number, 0, 3, "calf_twist_0") # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @property def has_ball_joint(self): """ This property holds a boolean value on whether or not a ball joint will be included in the setup. example usage: .. code-block:: python leg_inst = biped_leg.BipedLeg() leg_inst.has_ball_joint = False :return: bool """ return self.network_node.has_ball_joint.get() @has_ball_joint.setter def has_ball_joint(self, new_value): if isinstance(new_value, bool): self.logger.info("{0}.has_ball_joint: Setting property to {1}".format(self.__class__.__name__, new_value)) ball_mover_data = component_utils.find_mover_data_from_name(self, "ball") toe_mover_data = component_utils.find_mover_data_from_name(self, "toe") if ball_mover_data[1] and ball_mover_data[2] and toe_mover_data[1] and toe_mover_data[2]: utils.set_attribute(self.network_node, "has_ball_joint", new_value) self.change_num_joints(ball_mover_data[2], ball_mover_data[1], new_value) self.change_num_joints(toe_mover_data[2], toe_mover_data[1], new_value) else: self.logger.error("{0}.has_ball_joint: Error. Did not update.".format(self.__class__.__name__)) else: self.logger.warning("{0}.has_ball_joint: {1} is not a boolean value. Must be True/False.".format( self.__class__.__name__, new_value)) errors.raise_error("{0} is not a boolean value! Must be True/False".format(new_value)) return