Exemple #1
0
    def postbuild(self):
        # Group everything
        all_anms = libPymel.ls_root_anms()
        if not isinstance(self.grp_anms, CtrlRoot):
            self.grp_anms = CtrlRoot()
        self.grp_anms.build()
        self.grp_anms.rename('anm_root')
        all_anms.setParent(self.grp_anms)

        all_rigs = libPymel.ls_root_rigs()
        self.grp_rigs = RigNode(name='rigs', _create=True)
        all_rigs.setParent(self.grp_rigs)

        # note: self.grp_jnts is now handled in prebuild
        #all_jnts = libPymel.ls_root_jnts()
        #self.grp_jnts = pymel.createNode('joint', name='jnts')
        #all_jnts.setParent(self.grp_jnts)

        # Ensure self.grp_jnts is constraint to self.grp_anms
        # We use parentConstraint instead of connections in the the animator change self.grp_anms parent
        pymel.delete([child for child in self.grp_jnts.getChildren() if isinstance(child, pymel.nodetypes.Constraint)])
        pymel.parentConstraint(self.grp_anms, self.grp_jnts)

        all_geos = libPymel.ls_root_geos()
        self.grp_geos = RigNode(name='geos', _create=True)
        all_geos.setParent(self.grp_geos)

        # Setup displayLayers
        self.layer_anm = pymel.createDisplayLayer(name='layer_anm', number=1, empty=True)
        pymel.editDisplayLayerMembers(self.layer_anm, self.grp_anms, noRecurse=True)
        self.layer_anm.color.set(17) # Yellow

        self.layer_rig = pymel.createDisplayLayer(name='layer_rig', number=1, empty=True)
        pymel.editDisplayLayerMembers(self.layer_rig, self.grp_rigs, noRecurse=True)
        pymel.editDisplayLayerMembers(self.layer_rig, self.grp_jnts, noRecurse=True)
        self.layer_rig.color.set(13) # Red
        #oLayerRig.visibility.set(0) # Hidden
        self.layer_rig.displayType.set(2) # Frozen

        self.layer_geo = pymel.createDisplayLayer(name='layer_geo', number=1, empty=True)
        pymel.editDisplayLayerMembers(self.layer_geo, self.grp_geos, noRecurse=True)
        self.layer_geo.color.set(12) # Green?
        self.layer_geo.displayType.set(2) # Frozen
    def pre_build(self, create_grp_anm=True, create_display_layers=True, **kwargs):
        super(RigSqueeze, self).pre_build(create_grp_anm=create_grp_anm, create_master_grp=False,
                                          create_display_layers=create_display_layers, **kwargs)

        if create_grp_anm:
            grp_anim_size = CtrlMaster._get_recommended_radius(self)
            self.grp_anm_master = self.build_grp(
                CtrlMaster,
                self.grp_anm_master,
                self.nomenclature.root_anm_master_name,
                size=grp_anim_size
            )

        if create_display_layers:
            pymel.editDisplayLayerMembers(self.layer_anm, self.grp_anm_master, noRecurse=True)

        #
        # Create specific group related to squeeze rig convention
        #
        all_geos = libPymel.ls_root_geos()

        # Build All_Grp
        self.grp_master = self.build_grp(classRig.RigGrp, self.grp_master, self.nomenclature.root_all_name)
        self.grp_model = self.build_grp(classRig.RigGrp, self.grp_model, self.nomenclature.root_model_name)
        self.grp_proxy = self.build_grp(classRig.RigGrp, self.grp_proxy, self.nomenclature.root_proxy_name)
        self.grp_fx = self.build_grp(classRig.RigGrp, self.grp_fx, self.nomenclature.root_fx_name)

        # Parent all groups in the main grp_master
        pymel.parent(self.grp_anm_master, self.grp_master)
        pymel.parent(self.grp_anm, self.grp_anm_master)  # grp_anm is not a Node, but a Ctrl
        self.grp_rig.setParent(self.grp_master)
        self.grp_fx.setParent(self.grp_master)
        self.grp_model.setParent(self.grp_master)
        self.grp_proxy.setParent(self.grp_master)
        self.grp_geo.setParent(self.grp_master)
        '''
        if self.grp_jnt.getParent() is None:
            self.grp_jnt.setParent(self.grp_master)
        '''

        # Lock and hide all attributes we don't want the animator to play with
        libAttr.lock_hide_trs(self.grp_master)
        libAttr.lock_hide_trs(self.grp_rig)
        libAttr.lock_hide_trs(self.grp_fx)
        libAttr.lock_hide_trs(self.grp_model)
        libAttr.lock_hide_trs(self.grp_proxy)
        libAttr.lock_hide_trs(self.grp_geo)
        libAttr.hide_scale(self.grp_anm)

        # Hide some group
        # self.grp_jnt.visibility.set(False)
        self.grp_rig.visibility.set(False)
        self.grp_fx.visibility.set(False)
        self.grp_model.visibility.set(False)

        #
        # Add root ctrl attributes specific to squeeze while preserving existing connections.
        #
        if not self.grp_anm.hasAttr(self.GROUP_NAME_DISPLAY, checkShape=False):
            libAttr.addAttr_separator(self.grp_anm, self.GROUP_NAME_DISPLAY)

        attr_display_mesh_output_attrs = {self.grp_geo.visibility}
        attr_display_proxy_output_attrs = {self.grp_proxy.visibility}
        # attr_display_ctrl_output_attrs = set(
        #     [children.visibility for children in self.grp_anm.getChildren(type='transform')]
        # )

        # In the past, the displayMesh attribute was a boolean and the displayProxy was also a boolean.
        # Now we use an enum. This mean that we need to remap.
        if self.grp_anm.hasAttr(self.ATTR_NAME_DISPLAY_MESH):
            attr_display_mesh = self.grp_anm.attr(self.ATTR_NAME_DISPLAY_MESH)
            if attr_display_mesh.type() == 'short':
                for attr_dst in attr_display_mesh.outputs(plugs=True):
                    attr_display_mesh_output_attrs.add(attr_dst)
                    pymel.disconnectAttr(attr_display_mesh, attr_dst)

        if self.grp_anm.hasAttr(self.ATTR_NAME_DISPLAY_PROXY):
            attr_display_proxy = self.grp_anm.attr(self.ATTR_NAME_DISPLAY_PROXY)
            for attr_dst in attr_display_proxy.outputs(plugs=True):
                attr_display_proxy_output_attrs.add(attr_dst)
                pymel.disconnectAttr(attr_display_proxy, attr_dst)
            attr_display_proxy.delete()

        # Create DisplayMesh attribute
        attr_display_mesh = self._init_attr_display_mesh()

        # Create DisplayCtrl attribute
        attr_display_ctrl = self._init_attr_display_ctrl()

        # Connect DisplayMesh attribute
        for attr_dst in attr_display_mesh_output_attrs:
            if not libAttr.is_connected_to(attr_display_mesh, attr_dst, max_depth=3):
                self.debug("Connecting {} to {}".format(attr_display_mesh, attr_dst))
                attr_proxy_display_inn = libRigging.create_utility_node(
                    'condition',
                    firstTerm=attr_display_mesh,
                    secondTerm=0,
                    colorIfTrueR=True,
                    colorIfFalseR=False
                ).outColorR
                pymel.connectAttr(attr_proxy_display_inn, attr_dst, force=True)

        for attr_dst in attr_display_proxy_output_attrs:
            if not libAttr.is_connected_to(attr_display_mesh, attr_dst, max_depth=3):
                self.debug("Connecting {} to {}".format(attr_display_mesh, attr_dst))
                # attr_proxy_display_inn = libRigging.create_utility_node(
                #     'condition',
                #     firstTerm=attr_display_mesh,
                #     secondTerm=0,
                #     colorIfTrueR=True,
                #     colorIfFalseR=False
                # ).outColorR
                pymel.connectAttr(attr_display_mesh, attr_dst, force=True)
Exemple #3
0
    def pre_build(self):
        super(RigSqueeze, self).pre_build(create_master_grp=False)
        
        #
        # Create specific group related to squeeze rig convention
        #
        all_geos = libPymel.ls_root_geos()

        # Build All_Grp
        self.grp_master = self.build_grp(classRig.RigGrp, self.grp_master, self.nomenclature.root_all_name)
        self.grp_model = self.build_grp(classRig.RigGrp, self.grp_model, self.nomenclature.root_model_name)
        self.grp_proxy = self.build_grp(classRig.RigGrp, self.grp_proxy, self.nomenclature.root_proxy_name)
        self.grp_fx = self.build_grp(classRig.RigGrp, self.grp_fx, self.nomenclature.root_fx_name)

        # Parent all groups in the main grp_master
        pymel.parent(self.grp_anm, self.grp_master) # grp_anm is not a Node, but a Ctrl
        self.grp_rig.setParent(self.grp_master)
        self.grp_fx.setParent(self.grp_master)
        self.grp_model.setParent(self.grp_master)
        self.grp_proxy.setParent(self.grp_master)
        self.grp_geo.setParent(self.grp_master)
        '''
        if self.grp_jnt.getParent() is None:
            self.grp_jnt.setParent(self.grp_master)
        '''

        # Lock and hide all attributes we don't want the animator to play with
        libAttr.lock_hide_trs(self.grp_master)
        libAttr.lock_hide_trs(self.grp_rig)
        libAttr.lock_hide_trs(self.grp_fx)
        libAttr.lock_hide_trs(self.grp_model)
        libAttr.lock_hide_trs(self.grp_proxy)
        libAttr.lock_hide_trs(self.grp_geo)
        libAttr.hide_scale(self.grp_anm)

        # Hide some group
        # self.grp_jnt.visibility.set(False)
        self.grp_rig.visibility.set(False)
        self.grp_fx.visibility.set(False)
        self.grp_model.visibility.set(False)

        #
        # Add root ctrl attributes specific to squeeze
        #
        if not self.grp_anm.hasAttr(self.GROUP_NAME_DISPLAY, checkShape=False):
            libAttr.addAttr_separator(self.grp_anm, self.GROUP_NAME_DISPLAY)

        # Display Mesh
        if not self.grp_anm.hasAttr(self.ATTR_NAME_DISPLAY_MESH, checkShape=False):
            attr_displayMesh = libAttr.addAttr(self.grp_anm, longName=self.ATTR_NAME_DISPLAY_MESH, at='short', k=True,
                                               hasMinValue=True, hasMaxValue=True, minValue=0, maxValue=1, defaultValue=1)
        else:
            attr_displayMesh = self.grp_anm.attr(self.ATTR_NAME_DISPLAY_MESH)

        # Display Ctrl
        if not self.grp_anm.hasAttr(self.ATTR_NAME_DISPLAY_CTRL, checkShape=False):
            attr_displayCtrl = libAttr.addAttr(self.grp_anm, longName=self.ATTR_NAME_DISPLAY_CTRL, at='short', k=True,
                                               hasMinValue=True, hasMaxValue=True, minValue=0, maxValue=1, defaultValue=1)
        else:
            attr_displayCtrl = self.grp_anm.attr(self.ATTR_NAME_DISPLAY_CTRL)

        # Display Proxy
        if not self.grp_anm.hasAttr(self.ATTR_NAME_DISPLAY_PROXY, checkShape=False):
            attr_displayProxy = libAttr.addAttr(self.grp_anm, longName=self.ATTR_NAME_DISPLAY_PROXY, at='short', k=True,
                                               hasMinValue=True, hasMaxValue=True, minValue=0, maxValue=1, defaultValue=0)
        else:
            attr_displayProxy = self.grp_anm.attr(self.ATTR_NAME_DISPLAY_PROXY)

        pymel.connectAttr(attr_displayMesh, self.grp_geo.visibility, force=True)
        pymel.connectAttr(attr_displayProxy, self.grp_proxy.visibility, force=True)
        for child in self.grp_anm.getChildren():
            pymel.connectAttr(attr_displayCtrl, child.visibility, force=True)
    def pre_build(self, create_master_grp=False, create_grp_jnt=True, create_grp_anm=True,
                  create_grp_rig=True, create_grp_geo=True, create_display_layers=True, create_grp_backup=False,
                  create_layer_jnt=False):
        # Hack: Invalidate any cache before building anything.
        # This ensure we always have fresh data.
        self._clear_cache()

        # Look for a root joint
        if create_grp_jnt:
            # For now, we will determine the root jnt by it's name used in each rig. Not the best solution,
            # but currently the safer since we want to support multiple deformation layer
            if not libPymel.is_valid_PyNode(self.grp_jnt):
                # self.grp_jnt = next(iter(libPymel.ls_root(type='joint')), None)
                if cmds.objExists(self.nomenclature.root_jnt_name):
                    self.grp_jnt = pymel.PyNode(self.nomenclature.root_jnt_name)
                else:
                    self.warning("Could not find any root joint, master ctrl will not drive anything")
                    # self.grp_jnt = pymel.createNode('joint', name=self.nomenclature.root_jnt_name)

        # Create the master grp
        if create_master_grp:
            self.grp_master = self.build_grp(RigGrp, self.grp_master, self.name + '_' + self.nomenclature.type_rig)

        # Create grp_anm
        if create_grp_anm:
            grp_anim_size = CtrlRoot._get_recommended_radius(self)
            self.grp_anm = self.build_grp(CtrlRoot, self.grp_anm, self.nomenclature.root_anm_name, size=grp_anim_size)

        # Create grp_rig
        if create_grp_rig:
            self.grp_rig = self.build_grp(RigGrp, self.grp_rig, self.nomenclature.root_rig_name)

        # Create grp_geo
        if create_grp_geo:
            all_geos = libPymel.ls_root_geos()
            self.grp_geo = self.build_grp(RigGrp, self.grp_geo, self.nomenclature.root_geo_name)
            # if all_geos:
            #    all_geos.setParent(self.grp_geo)

        if create_grp_backup:
            self.grp_backup = self.build_grp(RigGrp, self.grp_backup, self.nomenclature.root_backup_name)

        # Parent all grp on the master grp
        if self.grp_master:
            if self.grp_jnt:
                self.grp_jnt.setParent(self.grp_master.node)
            if self.grp_anm:
                self.grp_anm.setParent(self.grp_master.node)
            if self.grp_rig:
                self.grp_rig.setParent(self.grp_master.node)
            if self.grp_geo:
                self.grp_geo.setParent(self.grp_master.node)
            if self.grp_backup:
                self.grp_backup.setParent(self.grp_master.node)

        # Setup displayLayers
        if create_display_layers:
            if not pymel.objExists(self.nomenclature.layer_anm_name):
                self.layer_anm = pymel.createDisplayLayer(name=self.nomenclature.layer_anm_name, number=1, empty=True)
                self.layer_anm.color.set(17)  # Yellow
            else:
                self.layer_anm = pymel.PyNode(self.nomenclature.layer_anm_name)
            pymel.editDisplayLayerMembers(self.layer_anm, self.grp_anm, noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_rig_name):
                self.layer_rig = pymel.createDisplayLayer(name=self.nomenclature.layer_rig_name, number=1, empty=True)
                self.layer_rig.color.set(13)  # Red
                # self.layer_rig.visibility.set(0)  # Hidden
                self.layer_rig.displayType.set(2)  # Frozen
            else:
                self.layer_rig = pymel.PyNode(self.nomenclature.layer_rig_name)
            pymel.editDisplayLayerMembers(self.layer_rig, self.grp_rig, noRecurse=True)
            pymel.editDisplayLayerMembers(self.layer_rig, self.grp_jnt, noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_geo_name):
                self.layer_geo = pymel.createDisplayLayer(name=self.nomenclature.layer_geo_name, number=1, empty=True)
                self.layer_geo.color.set(12)  # Green?
                self.layer_geo.displayType.set(2)  # Frozen
            else:
                self.layer_geo = pymel.PyNode(self.nomenclature.layer_geo_name)
            pymel.editDisplayLayerMembers(self.layer_geo, self.grp_geo, noRecurse=True)

            if create_layer_jnt:
                if not pymel.objExists(self.nomenclature.layer_jnt_name):
                    self.layer_jnt = pymel.createDisplayLayer(name=self.nomenclature.layer_jnt_name, number=1,
                                                              empty=True)
                    self.layer_jnt.color.set(1)  # Black?
                    self.layer_jnt.visibility.set(0)  # Hidden
                    self.layer_jnt.displayType.set(2)  # Frozen
                else:
                    self.layer_jnt = pymel.PyNode(self.nomenclature.layer_jnt_name)
                pymel.editDisplayLayerMembers(self.layer_jnt, self.grp_jnt, noRecurse=True)
Exemple #5
0
    def pre_build(self, create_master_grp=False, create_grp_jnt=True, create_grp_anm=True,
                  create_grp_rig=True, create_grp_geo=True, create_display_layers=True, create_grp_backup=False):
        # Hack: Invalidate any cache before building anything.
        # This ensure we always have fresh data.
        try:
            del self._cache
        except AttributeError:
            pass

        # Look for a root joint
        if create_grp_jnt:
            # For now, we will determine the root jnt by it's name used in each rig. Not the best solution,
            # but currently the safer since we want to support multiple deformation layer
            if not libPymel.is_valid_PyNode(self.grp_jnt):
                # self.grp_jnt = next(iter(libPymel.ls_root(type='joint')), None)
                if cmds.objExists(self.nomenclature.root_jnt_name):
                    self.grp_jnt = pymel.PyNode(self.nomenclature.root_jnt_name)
                else:
                    self.warning("Could not find any root joint, master ctrl will not drive anything")
                    # self.grp_jnt = pymel.createNode('joint', name=self.nomenclature.root_jnt_name)

        # Ensure all joints have segmentScaleComprensate deactivated.
        # This allow us to scale adequately and support video game rigs.
        # If for any mean stretch and squash are necessary, implement
        # them on a new joint chains parented to the skeletton.
        # TODO: Move elsewere?
        all_jnts = libPymel.ls(type='joint')
        for jnt in all_jnts:
            jnt.segmentScaleCompensate.set(False)

        # Create the master grp
        if create_master_grp:
            self.grp_master = self.build_grp(RigGrp, self.grp_master, self.name + '_' + self.nomenclature.type_rig)

        # Create grp_anm
        if create_grp_anm:
            grp_anim_size = CtrlRoot._get_recommended_radius(self)
            self.grp_anm = self.build_grp(CtrlRoot, self.grp_anm, self.nomenclature.root_anm_name, size=grp_anim_size)


        # Create grp_rig
        if create_grp_rig:
            self.grp_rig = self.build_grp(RigGrp, self.grp_rig, self.nomenclature.root_rig_name)

        # Create grp_geo
        if create_grp_geo:
            all_geos = libPymel.ls_root_geos()
            self.grp_geo = self.build_grp(RigGrp, self.grp_geo, self.nomenclature.root_geo_name)
            #if all_geos:
            #    all_geos.setParent(self.grp_geo)

        if create_grp_backup:
            self.grp_backup = self.build_grp(RigGrp, self.grp_backup, self.nomenclature.root_backup_name)

        #Parent all grp on the master grp
        if self.grp_master:
            if self.grp_jnt:
                self.grp_jnt.setParent(self.grp_master.node)
            if self.grp_anm:
                self.grp_anm.setParent(self.grp_master.node)
            if self.grp_rig:
                self.grp_rig.setParent(self.grp_master.node)
            if self.grp_geo:
                self.grp_geo.setParent(self.grp_master.node)
            if self.grp_backup:
                self.grp_backup.setParent(self.grp_master.node)

        # Setup displayLayers
        if create_display_layers:
            if not pymel.objExists(self.nomenclature.layer_anm_name):
                self.layer_anm = pymel.createDisplayLayer(name=self.nomenclature.layer_anm_name, number=1, empty=True)
                self.layer_anm.color.set(17)  # Yellow
            else:
                self.layer_anm = pymel.PyNode(self.nomenclature.layer_anm_name)
            pymel.editDisplayLayerMembers(self.layer_anm, self.grp_anm, noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_rig_name):
                self.layer_rig = pymel.createDisplayLayer(name=self.nomenclature.layer_rig_name, number=1, empty=True)
                self.layer_rig.color.set(13)  # Red
                # self.layer_rig.visibility.set(0)  # Hidden
                self.layer_rig.displayType.set(2)  # Frozen
            else:
                self.layer_rig = pymel.PyNode(self.nomenclature.layer_rig_name)
            pymel.editDisplayLayerMembers(self.layer_rig, self.grp_rig, noRecurse=True)
            pymel.editDisplayLayerMembers(self.layer_rig, self.grp_jnt, noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_geo_name):
                self.layer_geo = pymel.createDisplayLayer(name=self.nomenclature.layer_geo_name, number=1, empty=True)
                self.layer_geo.color.set(12)  # Green?
                self.layer_geo.displayType.set(2)  # Frozen
            else:
                self.layer_geo = pymel.PyNode(self.nomenclature.layer_geo_name)
            pymel.editDisplayLayerMembers(self.layer_geo, self.grp_geo, noRecurse=True)
Exemple #6
0
    def pre_build(self, create_grp_jnt=True, create_grp_anm=True, create_grp_rig=True, create_grp_geo=True, create_display_layers=True):
        # Ensure we got a root joint
        # If needed, parent orphan joints to this one
        if create_grp_jnt:
            if not libPymel.is_valid_PyNode(self.grp_jnt):
                self.grp_jnt = next(iter(libPymel.ls_root(type='joint')), None)
                '''
                if cmds.objExists(self.nomenclature.root_jnt_name):
                    self.grp_jnt = pymel.PyNode(self.nomenclature.root_jnt_name)
                else:
                    self.grp_jnt = pymel.createNode('joint', name=self.nomenclature.root_jnt_name)
                '''
            #all_root_jnts.setParent(self.grp_jnt)

        # Ensure all joinst have segmentScaleComprensate deactivated.
        # This allow us to scale adequately and support video game rigs.
        # If for any mean stretch and squash are necessary, implement them on a new joint chains parented to the skeletton.
        # TODO: Move elsewere?
        all_jnts = libPymel.ls(type='joint')
        for jnt in all_jnts:
            jnt.segmentScaleCompensate.set(False)

        # Create grp_anm
        if create_grp_anm:
            if not isinstance(self.grp_anm, CtrlRoot):
                self.grp_anm = CtrlRoot()
            if not self.grp_anm.is_built():
                grp_anm_size = CtrlRoot._get_recommended_radius(self)
                self.grp_anm.build(self, size=grp_anm_size)
            self.grp_anm.rename(self.nomenclature.root_anm_name)

        # Create grp_rig
        if create_grp_rig:
            if not isinstance(self.grp_rig, Node):
                self.grp_rig = Node()
            if not self.grp_rig.is_built():
                self.grp_rig.build(self)
                self.grp_rig.rename(self.nomenclature.root_rig_name)

        # Create grp_geo
        if create_grp_geo:
            all_geos = libPymel.ls_root_geos()
            if not isinstance(self.grp_geo, Node):
                self.grp_geo = Node()
            if not self.grp_geo.is_built():
                self.grp_geo.build(self)
                self.grp_geo.rename(self.nomenclature.root_geo_name)
            #if all_geos:
            #    all_geos.setParent(self.grp_geo)

        # Setup displayLayers
        if create_display_layers:
            if not pymel.objExists(self.nomenclature.layer_anm_name):
                self.layer_anm = pymel.createDisplayLayer(name=self.nomenclature.layer_anm_name, number=1, empty=True)
                pymel.editDisplayLayerMembers(self.layer_anm, self.grp_anm, noRecurse=True)
                self.layer_anm.color.set(17)  # Yellow

            if not pymel.objExists(self.nomenclature.layer_rig_name):
                self.layer_rig = pymel.createDisplayLayer(name=self.nomenclature.layer_rig_name, number=1, empty=True)
                pymel.editDisplayLayerMembers(self.layer_rig, self.grp_rig, noRecurse=True)
                pymel.editDisplayLayerMembers(self.layer_rig, self.grp_jnt, noRecurse=True)
                self.layer_rig.color.set(13)  # Red
                #self.layer_rig.visibility.set(0)  # Hidden
                self.layer_rig.displayType.set(2)  # Frozen

            if not pymel.objExists(self.nomenclature.layer_geo_name):
                self.layer_geo = pymel.createDisplayLayer(name=self.nomenclature.layer_geo_name, number=1, empty=True)
                pymel.editDisplayLayerMembers(self.layer_geo, self.grp_geo, noRecurse=True)
                self.layer_geo.color.set(12)  # Green?
                self.layer_geo.displayType.set(2)  # Frozen
Exemple #7
0
    def pre_build(self,
                  create_master_grp=False,
                  create_grp_jnt=True,
                  create_grp_anm=True,
                  create_grp_rig=True,
                  create_grp_geo=True,
                  create_display_layers=True,
                  create_grp_backup=False):
        # Hack: Invalidate any cache before building anything.
        # This ensure we always have fresh data.
        try:
            del self._cache
        except AttributeError:
            pass

        # Look for a root joint
        if create_grp_jnt:
            # For now, we will determine the root jnt by it's name used in each rig. Not the best solution,
            # but currently the safer since we want to support multiple deformation layer
            if not libPymel.is_valid_PyNode(self.grp_jnt):
                # self.grp_jnt = next(iter(libPymel.ls_root(type='joint')), None)
                if cmds.objExists(self.nomenclature.root_jnt_name):
                    self.grp_jnt = pymel.PyNode(
                        self.nomenclature.root_jnt_name)
                else:
                    self.warning(
                        "Could not find any root joint, master ctrl will not drive anything"
                    )
                    # self.grp_jnt = pymel.createNode('joint', name=self.nomenclature.root_jnt_name)

        # Ensure all joints have segmentScaleComprensate deactivated.
        # This allow us to scale adequately and support video game rigs.
        # If for any mean stretch and squash are necessary, implement
        # them on a new joint chains parented to the skeletton.
        # TODO: Move elsewere?
        all_jnts = libPymel.ls(type='joint')
        for jnt in all_jnts:
            jnt.segmentScaleCompensate.set(False)

        # Create the master grp
        if create_master_grp:
            self.grp_master = self.build_grp(
                RigGrp, self.grp_master,
                self.name + '_' + self.nomenclature.type_rig)

        # Create grp_anm
        if create_grp_anm:
            grp_anim_size = CtrlRoot._get_recommended_radius(self)
            self.grp_anm = self.build_grp(CtrlRoot,
                                          self.grp_anm,
                                          self.nomenclature.root_anm_name,
                                          size=grp_anim_size)

        # Create grp_rig
        if create_grp_rig:
            self.grp_rig = self.build_grp(RigGrp, self.grp_rig,
                                          self.nomenclature.root_rig_name)

        # Create grp_geo
        if create_grp_geo:
            all_geos = libPymel.ls_root_geos()
            self.grp_geo = self.build_grp(RigGrp, self.grp_geo,
                                          self.nomenclature.root_geo_name)
            #if all_geos:
            #    all_geos.setParent(self.grp_geo)

        if create_grp_backup:
            self.grp_backup = self.build_grp(
                RigGrp, self.grp_backup, self.nomenclature.root_backup_name)

        #Parent all grp on the master grp
        if self.grp_master:
            if self.grp_jnt:
                self.grp_jnt.setParent(self.grp_master.node)
            if self.grp_anm:
                self.grp_anm.setParent(self.grp_master.node)
            if self.grp_rig:
                self.grp_rig.setParent(self.grp_master.node)
            if self.grp_geo:
                self.grp_geo.setParent(self.grp_master.node)
            if self.grp_backup:
                self.grp_backup.setParent(self.grp_master.node)

        # Setup displayLayers
        if create_display_layers:
            if not pymel.objExists(self.nomenclature.layer_anm_name):
                self.layer_anm = pymel.createDisplayLayer(
                    name=self.nomenclature.layer_anm_name,
                    number=1,
                    empty=True)
                self.layer_anm.color.set(17)  # Yellow
            else:
                self.layer_anm = pymel.PyNode(self.nomenclature.layer_anm_name)
            pymel.editDisplayLayerMembers(self.layer_anm,
                                          self.grp_anm,
                                          noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_rig_name):
                self.layer_rig = pymel.createDisplayLayer(
                    name=self.nomenclature.layer_rig_name,
                    number=1,
                    empty=True)
                self.layer_rig.color.set(13)  # Red
                # self.layer_rig.visibility.set(0)  # Hidden
                self.layer_rig.displayType.set(2)  # Frozen
            else:
                self.layer_rig = pymel.PyNode(self.nomenclature.layer_rig_name)
            pymel.editDisplayLayerMembers(self.layer_rig,
                                          self.grp_rig,
                                          noRecurse=True)
            pymel.editDisplayLayerMembers(self.layer_rig,
                                          self.grp_jnt,
                                          noRecurse=True)

            if not pymel.objExists(self.nomenclature.layer_geo_name):
                self.layer_geo = pymel.createDisplayLayer(
                    name=self.nomenclature.layer_geo_name,
                    number=1,
                    empty=True)
                self.layer_geo.color.set(12)  # Green?
                self.layer_geo.displayType.set(2)  # Frozen
            else:
                self.layer_geo = pymel.PyNode(self.nomenclature.layer_geo_name)
            pymel.editDisplayLayerMembers(self.layer_geo,
                                          self.grp_geo,
                                          noRecurse=True)