Exemple #1
0
def create_rig_controls(shape=shapes.Plus, driven=[], **kwargs):
	if not driven:
		driven = ls(selection=True, transforms=True)
	assert driven, "Must supply one or more transforms to drive."
	assert len(driven) == len(ls(driven, transforms=True)), \
		"Rig controls can only drive transforms."
	rcs = [RigControl(shape, d, **kwargs) for d in driven]
	select([rc.get_transform() for rc in rcs])
	return rcs
Exemple #2
0
def create_rig_controls(shape=shapes.Plus, driven=[], **kwargs):
    if not driven:
        driven = ls(selection=True, transforms=True)
    assert driven, "Must supply one or more transforms to drive."
    assert len(driven) == len(ls(driven, transforms=True)), \
     "Rig controls can only drive transforms."
    rcs = [RigControl(shape, d, **kwargs) for d in driven]
    select([rc.get_transform() for rc in rcs])
    return rcs
Exemple #3
0
 def split_joints(n=5):
     selection = ls(selection=True)
     if JointSplitter.validate_for_split_joint(selection):
         first_joint = ls(selection=True)[0]
         fj = pm.joint(pm.general.ls(selection=True)[0], query=True, position=True)
         lj = pm.joint(pm.general.ls(selection=True)[1], query=True, position=True)
         fj_vector = dt.Vector(fj[0], fj[1], fj[2])
         lj_vector = dt.Vector(lj[0], lj[1], lj[2])
         new_joint = 0
         pm.select(deselect=True)
         for i in range(0, n - 1):
             split_point = fj_vector.__mul__((n - i - 1.0) / n).__add__(lj_vector.__mul__(i + 1.0) / n)
             new_joint = pm.insertJoint(new_joint if i > 0 else first_joint)
             pm.joint(new_joint, edit=True, component=True, position=split_point)
Exemple #4
0
	def __new__(cls, **kwargs):
		s = super(Custom, cls).__new__(cls, **kwargs)
		transforms = ls(selection=True, transforms=True)
		for t in transforms:
			shapes = t.getShapes()
			if shapes:
				s.extend(shapes)
			elif isinstance(t, nt.Joint):
				s.append(t)
				xform(t, translation=(0, 0, 0))
			else:
				# Delete empty transforms.
				delete(t)
		s.extend([n for n in ls(selection=True, shapes=True) if n not in s])
		return s
Exemple #5
0
 def __new__(cls, **kwargs):
     s = super(Custom, cls).__new__(cls, **kwargs)
     transforms = ls(selection=True, transforms=True)
     for t in transforms:
         shapes = t.getShapes()
         if shapes:
             s.extend(shapes)
         elif isinstance(t, nt.Joint):
             s.append(t)
             xform(t, translation=(0, 0, 0))
         else:
             # Delete empty transforms.
             delete(t)
     s.extend([n for n in ls(selection=True, shapes=True) if n not in s])
     return s
Exemple #6
0
def create_shapes(shape_cls=Plus, snaps=[], **kwargs):
	if not snaps:
		snaps = ls(selection=True, transforms=True)
	if snaps:
		return [shape_cls(snap_to=s) for s in snaps]
	verts = [v for v in ls(selection=True, flatten=True) if isinstance(v, MeshVertex)]
	[verts.extend(e.connectedVertices()) for e in ls(selection=True, flatten=True) \
		if isinstance(e, MeshEdge)]
	if verts:
		verts = uniquify(verts)
		select(verts, replace=True)
		transform = cluster()[1]
		shape = shape_cls(snap_to=transform)
		delete(transform)
		return [shape]
	return [shape_cls()]
Exemple #7
0
    def export_mesh(self, **kwargs):

        format, ext = str(self.format.text()), str(self.formatExt.text())
        format = self.name_pat.sub( \
         lambda m: '%(name)' + m.group(1)[1:], format)
        format = self.frame_pat.sub( \
         lambda m: '%(frame)' + m.group(1)[1:], format)
        path = Path(self.path.text())

        if not self.animation.isChecked() and self.oneFilePerNode.isChecked():
            sel = ls(selection=True)
            for s in sel:
                select(s)
                name = format % dict(name=s.name().replace('|', '')) + ext
                self.write_mesh(path, name, **kwargs)
            select(sel)
        else:

            end, by = self.end.value(), self.by.value()
            frame, renum_frame, renum_by = (self.frame, self.renum_frame,
                                            self.renum_by)

            info('Exporting frames... Press Esc to cancel.')
            self.progress_init(1)
            while (by > 0 and frame <= end) or (by < 0 and frame >= end):

                if self.aborted: return

                setCurrentTime(frame)
                if self.oneFilePerNode.isChecked():
                    sel = ls(selection=True)
                    for s in sel:
                        select(s)
                        name = format % dict(name=s.shortName(),
                                             frame=renum_frame) + ext
                        if not self.write_mesh(path, name):
                            break
                else:
                    name = format % dict(frame=renum_frame) + ext
                    if not self.write_mesh(path, name, **kwargs):
                        break

                # Prepare for the next iteration.
                frame += by
                renum_frame += renum_by
                self.export_count += 1
                self.progress_step()
Exemple #8
0
	def export_mesh(self, **kwargs):
		
		format, ext = str(self.format.text()), str(self.formatExt.text())
		format = self.name_pat.sub( \
			lambda m: '%(name)' + m.group(1)[1:], format)
		format = self.frame_pat.sub( \
			lambda m: '%(frame)' + m.group(1)[1:], format)
		path = Path(self.path.text())
		
		if not self.animation.isChecked() and self.oneFilePerNode.isChecked():
			sel = ls(selection=True)
			for s in sel:
				select(s)
				name = format % dict(name=s.name().replace('|', '')) + ext
				self.write_mesh(path, name, **kwargs)
			select(sel)
		else:
			
			end, by = self.end.value(), self.by.value()
			frame, renum_frame, renum_by = (self.frame, self.renum_frame,
				self.renum_by)
			
			info('Exporting frames... Press Esc to cancel.')
			self.progress_init(1)
			while (by > 0 and frame <= end) or (by < 0 and frame >= end):
				
				if self.aborted: return
				
				setCurrentTime(frame)
				if self.oneFilePerNode.isChecked():
					sel = ls(selection=True)
					for s in sel:
						select(s)
						name = format % dict(name=s.shortName(),
							frame=renum_frame) + ext
						if not self.write_mesh(path, name):
							break
				else:
					name = format % dict(frame=renum_frame) + ext
					if not self.write_mesh(path, name, **kwargs):
						break
				
				# Prepare for the next iteration.
				frame += by
				renum_frame += renum_by
				self.export_count += 1
				self.progress_step()
Exemple #9
0
def createSequenceRenderFile():
    renderFile = open(getRenderCommandFileName(), 'w+')
    for shot in ls(type='shot'):
        renderCommand = createRenderStringFromShot(shot)
        # renderCommands.append(createRenderStringFromShot(shot))
        renderFile.write(renderCommand + '\n')

    renderFile.close()
Exemple #10
0
def create_shapes(shape_cls=Plus, snaps=[], **kwargs):
    if not snaps:
        snaps = ls(selection=True, transforms=True)
    if snaps:
        return [shape_cls(snap_to=s) for s in snaps]
    verts = [
        v for v in ls(selection=True, flatten=True)
        if isinstance(v, MeshVertex)
    ]
    [verts.extend(e.connectedVertices()) for e in ls(selection=True, flatten=True) \
     if isinstance(e, MeshEdge)]
    if verts:
        verts = uniquify(verts)
        select(verts, replace=True)
        transform = cluster()[1]
        shape = shape_cls(snap_to=transform)
        delete(transform)
        return [shape]
    return [shape_cls()]
Exemple #11
0
    def __init__(self, *args, **kwargs):
        super(Exporter, self).__init__(*args, **kwargs)
        self.name_pat = re.compile('(%s)')
        self.frame_pat = re.compile('(%[\d\.]*(?:f|d))')
        self.split_pat = re.compile('((?:%s|%[\d\.]*(?:d|f)))')
        self.run_showers = (self.progress, self.status)
        self.run_disablers = (self.reload, self.toolBox, self.exportOptions,
                              self.exportButton)
        [o.hide() for o in self.run_showers]
        self.animation_widgets = ()
        for i in range(1, 3):
            self.animation_widgets += ((self.toolBox.widget(i),
                                        self.toolBox.itemText(i)), )
        self.main_progress = getMainProgressBar()
        self._aborted = False

        # Look at the selection to predict what kind of object the user is going
        # to export and auto-select it in the export type combo box.
        kwargs = dict(selection=True, dagObjects=True)
        jroots = len(
            dict(((j, None) for j in ls(type='joint', **kwargs))).keys())
        cams = len(ls(cameras=True, **kwargs))
        meshes, skins = ls(geometry=True, **kwargs), 0
        del_meshes = []
        for i, m in enumerate(meshes):
            if mel.findRelatedSkinCluster(m):
                skins += 1
                del_meshes.append(i)
        for i in del_meshes:
            del meshes[i]
        if not jroots and not cams and not meshes and not skins:
            comboIndex = 2  # Meshes as default
        else:
            comboIndex = sorted(((i, c) for i, c in enumerate( \
             (jroots, cams, meshes, skins))), key=lambda x: x[1])[-1][0]
        self.exportCombo.setCurrentIndex(comboIndex)
        self.setFromTimeSlider.click()
        self.fix_format()
Exemple #12
0
	def on_loadWeightsButton_clicked(self):
		for mesh in selected():
			sc = mel.findRelatedSkinCluster(mesh)
			if not sc: continue
			sc = ls(sc)[0]
			
			doc = ElementTree(file=path + mesh.nodeName().replace('|', '').replace(':', '.') + '.xml')
			
			influences = [inf.attrib['name'] for inf in doc.findall('//Influence')]
			for i, vtx in enumerate(doc.findall('//Vertex')):
				weights = [(influences[int(w.attrib['influence'])],
					float(w.attrib['value'])) for w in vtx.findall('Weight')]
				skinPercent(sc, '%s.vtx[%d]' % (mesh, i),
					transformValue=weights)
Exemple #13
0
 def get_affected_nodes(self, dagObjects=True, **kwargs):
     """
     Reads the UI's "Affecting: Hierarchy, Selected, All" radios and
     returns the appropriate selection of nodes.
     """
     if self.affectingAllRadio.isChecked():
         nodes = ls(dagObjects=dagObjects, **kwargs)
     else:
         nodes = selected(dagObjects=dagObjects, **kwargs)
         if nodes and self.affectingHierarchyRadio.isChecked():
             nodes += [n for n in \
                 listRelatives(allDescendents=True, **kwargs) \
                 if n not in nodes]
     return nodes
Exemple #14
0
	def __init__(self, *args, **kwargs):
		super(Exporter, self).__init__(*args, **kwargs)
		self.name_pat = re.compile('(%s)')
		self.frame_pat = re.compile('(%[\d\.]*(?:f|d))')
		self.split_pat = re.compile('((?:%s|%[\d\.]*(?:d|f)))')
		self.run_showers = (self.progress, self.status)
		self.run_disablers = (self.reload, self.toolBox, self.exportOptions,
			self.exportButton)
		[o.hide() for o in self.run_showers]
		self.animation_widgets = ()
		for i in range(1, 3):
			self.animation_widgets += ((self.toolBox.widget(i),
				self.toolBox.itemText(i)),)
		self.main_progress = getMainProgressBar()
		self._aborted = False
		
		# Look at the selection to predict what kind of object the user is going
		# to export and auto-select it in the export type combo box.
		kwargs = dict(selection=True, dagObjects=True)
		jroots = len(dict(((j, None) for j in ls(type='joint', **kwargs))).keys())
		cams = len(ls(cameras=True, **kwargs))
		meshes, skins = ls(geometry=True, **kwargs), 0
		del_meshes = []
		for i, m in enumerate(meshes):
			if mel.findRelatedSkinCluster(m):
				skins += 1
				del_meshes.append(i)
		for i in del_meshes:
			del meshes[i]
		if not jroots and not cams and not meshes and not skins:
			comboIndex = 2  # Meshes as default
		else:
			comboIndex = sorted(((i, c) for i, c in enumerate( \
				(jroots, cams, meshes, skins))), key=lambda x: x[1])[-1][0]
		self.exportCombo.setCurrentIndex(comboIndex)
		self.setFromTimeSlider.click()
		self.fix_format()
Exemple #15
0
    def __init__(self, transform, **kwargs):
        """
		Flags:
			- real_world_length: rwl				(unicode, default:None)
				The longest length of the object in the real world (e.g. '11in' for
				a normal 8.5x11" sheet of paper.
			
			- shared_transforms: st				(list, default:None)
				Any number of transforms that share the same nucleus.
		"""

        super(ScaledNCloth, self).__init__()
        self.transform = transform
        self.nucleus = ls(mel.getActiveNucleusNode(0, 1))[0]
        self.shared_transforms = kwargs.pop(
            'st', kwargs.pop('shared_transforms', None))
        self.real_world_length = kwargs.pop(
            'rwl', kwargs.pop('real_world_length', None))
Exemple #16
0
	def __init__(self, transform, **kwargs):
		"""
		Flags:
			- real_world_length: rwl				(unicode, default:None)
				The longest length of the object in the real world (e.g. '11in' for
				a normal 8.5x11" sheet of paper.
			
			- shared_transforms: st				(list, default:None)
				Any number of transforms that share the same nucleus.
		"""
		
		super(ScaledNCloth, self).__init__()
		self.transform = transform
		self.nucleus = ls(mel.getActiveNucleusNode(0, 1))[0]
		self.shared_transforms = kwargs.pop('st',
			kwargs.pop('shared_transforms', None))
		self.real_world_length = kwargs.pop('rwl',
			kwargs.pop('real_world_length', None))
Exemple #17
0
	def insert_bind_joints(self, cls, amount):
		inserted_joints = []
		for bj in self.bind_joints[cls]:
			nj = bj.getChildren()[0] # next joint
			d = nj.attr('t').get() / (amount + 1)
			parent(nj, world=True)
			ij = bj
			for i in range(amount):
				ns = ij.name_sequence + 1
				ij = ls(insertJoint(ij))[0]
				ij.attr('t').set(d)
				ij.__class__ = cls
				ij.name_sequence = ns
				self.name_helper.rename(ij, jt=bj.jtype, s=bj.side,
					ss=bj.side_sequence, n=bj.__name__, ns=ns)
				inserted_joints.append(ij)
			parent(nj, ij)
			self.set_bone_radii(bj)
		self.bind_joints[cls].extend(inserted_joints)
Exemple #18
0
    def on_loadWeightsButton_clicked(self):
        for mesh in selected():
            sc = mel.findRelatedSkinCluster(mesh)
            if not sc: continue
            sc = ls(sc)[0]

            doc = ElementTree(
                file=path +
                mesh.nodeName().replace('|', '').replace(':', '.') + '.xml')

            influences = [
                inf.attrib['name'] for inf in doc.findall('//Influence')
            ]
            for i, vtx in enumerate(doc.findall('//Vertex')):
                weights = [(influences[int(w.attrib['influence'])],
                            float(w.attrib['value']))
                           for w in vtx.findall('Weight')]
                skinPercent(sc,
                            '%s.vtx[%d]' % (mesh, i),
                            transformValue=weights)
Exemple #19
0
    def on_runButton_clicked(self):
        self._nodes = self.get_affected_nodes()
        if not self._nodes:
            return error('No affected nodes to manipulate.')

        # Filter-out shape nodes from the list, but only if their
        # parents are also in the list, because they will get renamed
        # automatically.
        for n in [n for n in ls(self._nodes, geometry=True) \
         if n.getParent(1) in self._nodes]:
            del self._nodes[self._nodes.index(n)]

        undoInfo(openChunk=True)
        if self.searchReplaceRadio.isChecked():
            self.search_replace_names()
        else:
            self.assign_new_names()
        undoInfo(closeChunk=True)

        self.display_renamed_nodes()
Exemple #20
0
	def on_runButton_clicked(self):
		self._nodes = self.get_affected_nodes()
		if not self._nodes:
			return error('No affected nodes to manipulate.')
		
		# Filter-out shape nodes from the list, but only if their
		# parents are also in the list, because they will get renamed
		# automatically.
		for n in [n for n in ls(self._nodes, geometry=True) \
			if n.getParent(1) in self._nodes]:
			del self._nodes[self._nodes.index(n)]
		
		undoInfo(openChunk=True)
		if self.searchReplaceRadio.isChecked():
			self.search_replace_names()
		else:
			self.assign_new_names()
		undoInfo(closeChunk=True)
		
		self.display_renamed_nodes()
Exemple #21
0
 def insert_bind_joints(self, cls, amount):
     inserted_joints = []
     for bj in self.bind_joints[cls]:
         nj = bj.getChildren()[0]  # next joint
         d = nj.attr('t').get() / (amount + 1)
         parent(nj, world=True)
         ij = bj
         for i in range(amount):
             ns = ij.name_sequence + 1
             ij = ls(insertJoint(ij))[0]
             ij.attr('t').set(d)
             ij.__class__ = cls
             ij.name_sequence = ns
             self.name_helper.rename(ij,
                                     jt=bj.jtype,
                                     s=bj.side,
                                     ss=bj.side_sequence,
                                     n=bj.__name__,
                                     ns=ns)
             inserted_joints.append(ij)
         parent(nj, ij)
         self.set_bone_radii(bj)
     self.bind_joints[cls].extend(inserted_joints)
Exemple #22
0
    def on_exportButton_clicked(self):

        if not ls(selection=True):
            return error('Nothing is currently selected.')

        # Load the objExport plug-in if it hasn't been already.
        kwargs = {}
        if self.formatExt.text() == '.obj':
            mll = 'objExport.mll'
            if not pluginInfo(mll, query=True, loaded=True):
                try:
                    loadPlugin(mll)
                    info('Loaded plug-in: ' + mll)
                except:
                    return error('Failed loading plug-in: ' + mll)
            #kwargs = dict(force=True, constructionHistory=False,
            #	channels=False, constraints=False, expressions=True,
            #	shader=False, preserveReferences=False, type='OBJexport')
            options = dict(groups=self.groups,
                           ptgroups=self.pointGroups,
                           materials=self.materials,
                           smoothing=self.smoothing,
                           normals=self.normals)
            options = ';'.join('%s=%d' % (k, cb.isChecked()) \
             for k, cb in options.items())
            kwargs = dict(exportSelected=True,
                          type='OBJexport',
                          force=True,
                          options=options)
        elif self.exportCombo.currentIndex() == 2:  # mesh
            return error('Unsupported extension: %s.' % self.formatExt.text())

        # Validate the output path.
        output_path = Path(self.path.text())
        if not output_path.exists():
            output_path = Path(self.set_path(workspace.getPath()))
            if not output_path.exists():
                return

        # Validate the frame range.
        start, end, by = self.start.value(), self.end.value(), self.by.value()
        remainder = (end - start) % by
        if remainder:
            click_result = confirmDialog(title='Confirm',
             message=os.linesep.join(( \
             'The end frame will not be exported because',
             'the "by frame" overshoots it by %.2f.' % remainder)),
             button=('OK', 'Cancel'), cancelButton='Cancel',
             defaultButton='OK', dismissString='Cancel')
            if click_result == 'Cancel':
                return

        # Validate the format.
        format = str(self.format.text())
        try:
            format % (start + by)
        except TypeError:
            return error('Invalid format: "%s". ' % format + \
             'Click the \'...\' tool button for help.' % format)

        # Disable UI elements while running.
        [o.show() for o in self.run_showers]
        [o.setEnabled(False) for o in self.run_disablers]

        # Set the range.
        if self.renumFrames.isChecked():
            renum_start = self.renumStart.value()
            self.renum_by = self.renumBy.value()
        else:
            renum_start = start
            self.renum_by = by
        self.frame, self.renum_frame = start, renum_start

        # Set loop vars.
        self.aborted = False
        self.export_count = 0
        self.copy_and_replace_all = False

        # Call the appropriate export function.
        (self.export_skeleton, self.export_camera, self.export_mesh,
         self.export_skin_weights)[self.exportCombo.currentIndex()](**kwargs)

        self.main_progress.endProgress()

        # Enable UI elements back.
        [o.hide() for o in self.run_showers]
        [o.setEnabled(True) for o in self.run_disablers]

        # Report results.
        if self.aborted:
            msg = 'Aborted with %s exported'
        else:
            msg = 'Successfully exported %s'
        plural = self.export_count != 1 and 's' or ''
        frames = '%d frame' % self.export_count + plural
        result(msg % frames + ' to: %s.' % output_path)
Exemple #23
0
    def export_skin_weights(self):

        format, ext = str(self.format.text()), str(self.formatExt.text())
        format = self.name_pat.sub( \
         lambda m: '%(name)' + m.group(1)[1:], format)
        path = Path(self.path.text())

        # Validate selection.
        sel = selected()
        if not sel:
            error('Selection is empty.')

        # Find the skin cluster.
        sc = mel.findRelatedSkinCluster(sel[0])
        skin_cluster = None
        for s in sel:
            sc = mel.findRelatedSkinCluster(s)
            if sc:
                skin_cluster = ls(sc)[0]
                break
        if not skin_cluster:
            error('No skin cluster found.')

        for mesh in sel:

            mesh_element = Element('Mesh', name=mesh)
            xml_tree = ElementTree(mesh_element)

            sc = mel.findRelatedSkinCluster(mesh)
            if not sc: continue
            sc = ls(sc)[0]

            influences = sc.influenceObjects()
            inf_tag = SubElement(mesh_element, 'Influences')
            for i, inf in enumerate(influences):
                SubElement(inf_tag, 'Influence', index=str(i), name=inf)
            #joints = ls(ios, type='joint')
            #if len(joints) < len(ios):
            #	error('Remove non-joint influences before exporting to Massive.')

            # TODO: progress bar

            name = format % dict(name=mesh.name().replace('|', '') \
             .replace(':', '.')) + ext
            with open(path / name, 'w') as f:

                #f.write(os.linesep + '# influences')
                #for i, inf in enumerate(ios):
                #	if inf in influences:
                #		inf_index = influences.index(j)
                #	else:
                #		influences += (inf,)
                #		inf_index = len(influences)
                #f.write('%sdeformer %d %s' % (os.linesep, i, inf))

                #f.write(os.linesep)

                vertices = SubElement(mesh_element, 'Vertices')

                #f.write(os.linesep + '# weights')
                for i, vtx in enumerate(mesh.vtx):
                    vertex = SubElement(vertices,
                                        'Vertex',
                                        pos=str(vtx.getPosition()))
                    #f.write('%s%d: ' % (os.linesep, vi))
                    for ii, inf in enumerate(influences):
                        weight_val = skinPercent(sc,
                                                 '%s.vtx[%d]' % (mesh, i),
                                                 transform=inf,
                                                 query=True)
                        if weight_val:
                            SubElement(vertex,
                                       'Weight',
                                       influence=str(ii),
                                       value=str(weight_val))
                            #f.write(' %d %f' % (ii, weight_val))

                #f.write(os.linesep + ':')
                rough_string = tostring(xml_tree.getroot(), 'utf-8')
                reparsed = minidom.parseString(rough_string)
                f.write(reparsed.toprettyxml(indent='\t'))
Exemple #24
0
	def __init__(self, root_cls=None, *args, **kwargs):
		"""
		Flags:
			- bone_radius: br				(int, default:1)
				Sets all joints' bone radii. This flag only works if -vary_bone_radius
				is False.
			
			- nhpat								(string, default:<nt>_<s><ss>_<n><ns>)
				Establishes a naming convention where 'nt' is the node type
				(drive or bind joint), 's' in the side, 'ss' is the side sequence,
				'n' is the name and 'ns' is the name sequence.
			
			- long_bone_radius: lbr		(float, default:2.0)
				Sets -vary_bone_radius' maximum range. This flag only works if
				-vary_bone_radius is True.
			
			- short_bone_radius: sbr		(float, default:0.5)
				Sets -vary_bone_radius' minimum range. This flag only works if
				-vary_bone_radius is True.
			
			- test_bone_radius: tebr		(bool, default:False)
				Tests the bone radius settings without continuing the
				rigging process.
			
			- tip_bone_radius: tbr			(float, default:0.25)
				Sets all tip joints' bone radii. This flag only works if -vary_bone_radius
				is True.
		"""
		
		# Find the joint-chain's root joint.
		joints = ls(selection=True, type='joint')
		roots = []
		for j in joints:
			while True:
				pj = j.listRelatives(parent=True, type='joint')
				if pj:
					j = pj[0]
				elif j not in roots:
					roots.append(j)
					break
				
		assert len(roots), 'Selection requires at least one joint.'
		
		# Vary bone radius.
		self._short_bone_radius = kwargs.pop('sbr',
			kwargs.pop('short_bone_radius', self._short_bone_radius))
		self._long_bone_radius = kwargs.pop('lbr',
			kwargs.pop('long_bone_radius', self._long_bone_radius))
		self._tip_bone_radius = kwargs.pop('tbr',
			kwargs.pop('tip_bone_radius', self._tip_bone_radius))
		for r in roots:
			self.set_bone_length_range(r)
			self.set_bone_radii(r)
		test_bone_radius = kwargs.pop('tebr',
			kwargs.pop('test_bone_radius', False))
		if test_bone_radius: return
		
		if not issubclass(root_cls, CharacterJoint):
			raise TypeError("%s class must be a subclass of %s." \
				% (root_cls.__name__, CharacterJoint))
		
		# NameHelper segments establish a naming convention for this character.
		self.name_helper = kwargs.pop('nh', kwargs.pop('name_helper', None))
		if not self.name_helper:
			self.name_helper = NameHelper()
		
		# In order to distinguish the character's left and right sides, first we need to
		# define the character's front axis.
		self.front = kwargs.pop('front', 'z')
		
		for jdict in [self.drive_joints, self.bind_joints]:
			jdict[root_cls] = []
		for i, root in enumerate(roots):
			# Clean-up the joint chain by freezing rotate and scale
			makeIdentity(root, apply=True, rotate=True, scale=True)
			
			# Recurse through the entire joint chain, assigning the appropriate
			# CharacterJoint class to each joint.
			self.drive_joints[root_cls].append(root_cls(root, self,
				jdict=self.drive_joints, *args, **kwargs))
			self.bind_joints[root_cls].append(root_cls(root.duplicate()[0],
				self, jdict=self.bind_joints, *args, **kwargs))
		
		# Recursion added joints to the lists backwards, so reverse it to
		# keep the joints in a top-down relationship.
		for jdict in [self.drive_joints, self.bind_joints]:
			[jdict[cls].reverse() for cls in jdict.keys()]
		
		# Change the name of the joints to something they would not use
		# to prevent any naming conflicts in the future.
		roots.extend(self.bind_joints[root_cls])
		function_on_hierarchy(roots, rename, 'FooJoint#')
		
		# Name joints.
		for cls, dj_list in self.drive_joints.items():
			for i, dj in enumerate(dj_list):
				while True:
					self.rename_part(dj)
					if len(ls(dj.nodeName())) == 1:
						bj = self.bind_joints[cls][i]
						dj.bind_joint = bj
						bj.drive_joint = dj
						bj.side_sequence = dj.side_sequence
						self.rename_part(bj)
						break
					dj.side_sequence += 1
Exemple #25
0
    def export_camera(self):

        start, end = self.start.value(), self.end.value()
        path = Path(self.path.text())

        # Validate the selection.
        sel = ls(selection=True, dagObjects=True, cameras=True)
        if not ls(selection=True):
            return error('No cameras in selection.')

        # Associate the camera shapes with their parents.
        cams = dict((s, s.getParent()) for s in sel)

        # Pull-out only the attributes that are checked.
        shape_atts = []
        for cb in self.cameraChannelsLayout.findChildren(QCheckBox):
            if cb.isChecked():
                [shape_atts.extend(str(cb.property(n).toString()).split('|')) \
                 for n in cb.dynamicPropertyNames() if n == 'shortName']
        cam_atts = (cb.objectName() for cb \
         in self.translation.findChildren(QCheckBox) if cb.isChecked())
        attributes = (shape_atts, cam_atts)

        # Enable any locked or non-keyable channels.
        for shape, cam in cams.items():
            for i, obj in enumerate((shape, cam)):
                for att in attributes[i]:
                    obj.attr(att).set('locked', False)
                    obj.attr(att).set('keyable', True)

        # Initialize the progress bar.
        lc = len(cams)
        self.progress_init(lc + lc * len([
            x
            for x in (self.createStandIn.isChecked(), self.oneFile.isChecked()
                      and self.oneFilePerNode.isChecked) if x
        ]))

        # Bake the keys to the camera shape.
        frame_range = self.animation.isChecked() and (start, end) or (start, )
        for shape, cam in cams.items():
            if self.aborted: return

            info('Baking keys to %s: %d-%d...' % \
             ((shape,) + frame_range))
            bakeResults(shape,
                        time=frame_range,
                        simulation=True,
                        attribute=shape_atts)
            info('%s keys %d-%d baked.' % ((shape, ) + frame_range))

            self.progress_step()

        # Disable the cycle check warning.
        cycleCheck(evaluation=False)

        # Create a null stand-in for the camera and bake keys to it.
        #mel.source('channelBoxCommand.mel')
        if self.createStandIn.isChecked():
            for cam in cams.values():
                if self.aborted: return

                stand_in = Transform(name='standInNull')
                parentConstraint(cam, stand_in, name='nullParentConstraint')
                info('Baking keys to the stand-in null...')
                bakeResults(stand_in,
                            time=frame_range,
                            shape=True,
                            simulation=True,
                            attribute=cam_atts)
                info('Null keys baked.')

                # If the camera is a child, parent it to the world.
                if cam.firstParent2():
                    cam.setParent(world=True)

                # Break existing connections between the rotate or translate
                # attributes.
                for att in cam_atts:
                    if connectionInfo(cam, isExactDestination=True):
                        disconnectAttr(
                            connectionInfo(cam, getExactDestination=True))
                        #mel.CBdeleteConnection(getExactDestination=True)

                # Constrain the camera to the null.
                parentConstraint(stand_in, cam, name='cameraParentConstraint')

                # Bake the camera translate/rotate keys.
                info('Baking keys to the camera...')
                bakeResults(cam,
                            time=frame_range,
                            disableImplicitControl=True,
                            simulation=True,
                            attribute=cam_atts)
                info('Transform keys baked.')

                self.progress_step()

        # Remove excess elements unless optimize has been disabled.
        if self.optimize.isChecked():
            info('Optimizing scene...')
            delete([s for s in ls(dagObjects=True) if s not in cams.keys() + \
             cams.values() + ls(selection=True, type='animCurve')])

        # Save-out the cameras.
        kwargs = dict(force=True,
                      constructionHistory=False,
                      channels=True,
                      constraints=False,
                      expressions=False,
                      shader=False,
                      type='mayaAscii')
        ext = str(self.formatExt.text())
        if self.oneFile.isChecked():
            if self.oneFilePerNode.isChecked():
                for cam in cams.values():
                    if self.aborted: return
                    select(cam)
                    exportSelected(path / cam.name() + ext, **kwargs)
                    self.progress_step()
            else:
                select(cams.values())
                exportSelected(path / 'camera' + ext, **kwargs)
        else:
            error('Not implemented yet. Coming soon...')
Exemple #26
0
    def __init__(self, driver=shapes.Plus, driven=None, **kwargs):

        # Driver
        if not isinstance(driver, shapes.Shape) and issubclass(
                driver, shapes.Shape):
            driver = driver()
        assert isinstance(driver, shapes.Shape), \
         ("Parameter 'driver' must be an instance or subclass of %s." %
          shapes.Shape.__name__)
        self._driver = driver
        self._transform = driver.get_transform()
        self._shapes = self._transform.getShapes()

        # Driven
        if not driven:
            driven = ls(selection=True, transforms=True)
            assert len(
                driven
            ) == 1, "Parameter 'driven' requires exactly one transform."
            driven = driven[0]
        self._driven = driven

        # Face Axis
        face_x = kwargs.pop('fx', kwargs.pop('faceX', False))
        face_y = kwargs.pop('fy', kwargs.pop('faceY', False))
        face_z = kwargs.pop('fz', kwargs.pop('faceZ', False))
        face_sum = sum([face_x, face_y, face_z])
        if not face_sum:
            face_x = True
            face_sum = 1
        else:
            assert face_sum == 1, "Rig control can only face one axis."
        rotate(self._transform, [face_z and 90 or 0, 0, face_x and -90 or 0])
        select(self._transform)
        FreezeTransformations()

        # Constraints
        do_parent_constraint = kwargs.pop(
            'pc', kwargs.pop('parentConstraint', False))
        do_point_constraint = kwargs.pop('xc',
                                         kwargs.pop('pointConstraint', False))
        do_orient_constraint = kwargs.pop(
            'oc', kwargs.pop('orientConstraint', False))
        do_scale_constraint = kwargs.pop('sc',
                                         kwargs.pop('scaleConstraint', False))
        if do_parent_constraint or do_point_constraint or do_orient_constraint or \
         do_scale_constraint:
            self._buffer = Transform()
            snap(self._buffer, self._driven, scale=True)
            select(self._buffer)
            parent(self._transform, self._buffer)
            if do_parent_constraint:
                parentConstraint(self._transform, self._driven)
            else:
                if do_point_constraint:
                    pointConstraint(self._transform, self._driven)
                if do_orient_constraint:
                    orientConstraint(self._transform, self._driven)
            if do_scale_constraint:
                scaleConstraint(self._transform, self._driven)
        elif isinstance(self._driven, Joint):
            # Parent the drivers directly underneath the driven joint.
            parent(self._driver, self._driven, relative=True, shape=True)
            delete(self._transform)
            self._transform = self._driven
        elif isinstance(self._driven, IkHandle):
            self._buffer = self._transform
            self._transform = self._driven
            snap(self._ebuffer, self._transform)
            parent(self._transform, self._buffer)
            parent(self._driver, self._transform, relative=True, shape=True)
        else:
            # Parent the drivers underneath a new buffered transform.
            self._buffer = self._driven
            parent(self._transform, self._buffer)
            parent(self._buffer.getShapes(),
                   self._transform,
                   relative=True,
                   shape=True)
            # Pop the shape nodes out and back in to reorder the driven shape(s) to
            # the top. This way, the Outliner icons for this transform will reflect the
            # appropriate first-child shape node.
            parent(self._driver, self._buffer, relative=True, shape=True)
            parent(self._driver, self._transform, relative=True, shape=True)
        if self._buffer:
            select(self._transform)
            ResetTransformations()
            for trs in 'trs':
                for xyz in 'xyz':
                    self._buffer.attr(trs + xyz).lock()

        if isinstance(self._driven, IkHandle):
            self.__class__ = IkRigControl
            self.__init__()
Exemple #27
0
 def saveFile(self, type=0):
     #So this function needs to look into the proper component folder (if it exists), find the Working folder (if it exists, if not make it)
     #Then save an iteration of this file.
     project = self.getSelectedProject()
     if project!="None":
         if windows.optionMenu("partOptionMenu", q=True, v=True)!="None":
             part_index = int(windows.optionMenu("partOptionMenu", q=True, v=True).split(":")[0]) - 1
             part_directory, part_name, part_numname = project.modelingComponents[part_index]
             if os.path.isdir(part_directory):
                 #part_name = project.modelingComponents[part_index][1]
                 
                 working_dir = os.path.join(part_directory, "Working")
                 qa_dir = os.path.join(part_directory, "QA")
                 publish_dir = os.path.join(part_directory, "Publish")
                 
                 if os.path.isdir(working_dir)==False:
                     os.makedirs(working_dir)
                 if os.path.isdir(qa_dir)==False:
                     os.makedirs(qa_dir)
                 if os.path.isdir(publish_dir)==False:
                     os.makedirs(publish_dir)
                 
                 #If save type is 0 (which is a regular work file incremental save)
                 #Save format: part_modeler_v001.mb
                 if type==0:
                     if self.username!="":
                         files = glob.glob(working_dir+"/*")
                         if len(files)>0:
                             highest_num=0
                             for file in files:
                                 if os.path.isfile(file):
                                     filenum = int(os.path.split(file)[1].split(".")[0][-3:])
                                     if filenum>highest_num:
                                         highest_num = filenum
                             else:
                                 highest_num+=1
                                 num = ("0"*max(0,3-len(str(highest_num)))+str(highest_num))
                                 print("Num: " + num)
                         else:
                             num = "001"
                         
                         if num=="001":
                             if windows.confirmDialog(title = "Save Part File?", message = "Save the first version of this part? You will not be prompted when saving new versions after this.", button = ['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No')=='Yes':
                                 file_name = os.path.join(working_dir , part_name + "_" + self.username + "_" + "v" + num + ".mb")
                                 system.saveAs(file_name)
                         else:
                             file_name = os.path.join(working_dir , part_name + "_" + self.username + "_" + "v" + num + ".mb")
                             system.saveAs(file_name)
                     else:
                         windows.confirmDialog(title="No username entered.", message="Please enter a valid username to save with.",button="Dismiss")
                 
                 #If the save file is type 1, its a publish attempt 
                 elif type==1:
                     if windows.confirmDialog(title = "Publish File", message = "Publish this scene file?", button = ['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No')=='Yes':
                         file_name = os.path.join(publish_dir, part_name + "_publish.mb")
                         if os.path.isfile(file_name):
                             ctime = os.path.getctime(file_name)
                             moveFolder = os.path.join(publish_dir,"_old",time.strftime("%b%d_%Y %H-%M-%S",time.localtime(ctime)))
                             if not os.path.isdir(moveFolder):
                                 os.makedirs(moveFolder)
                             shutil.move(file_name, moveFolder)
                         #Save the current file, then move on to cleaning up this file in preparation for publishing
                         current_filename = system.sceneName()
                         system.saveAs(current_filename)
                         #Clean up all references
                         reference_files = []
                         references = general.ls(type = "reference")
                         if len(references)>0:
                             for reference in references:
                                 if "sharedReferenceNode"!=reference:
                                     reference_files.append(system.referenceQuery(reference, filename=True))
                             else:
                                 for file in reference_files:
                                     system.FileReference(pathOrRefNode = file).remove()
                         general.select(clear = True)
                         general.select(general.ls(geometry = True))
                         layerName = os.path.split(system.sceneName())[1].split("_")[0].replace(" ", "_")
                         general.createDisplayLayer(name = layerName)
                         system.saveAs(file_name)
                         system.openFile(current_filename, f = True)
                 #If its type 2, its a QA submit
                 elif type==2:
                     if windows.confirmDialog(title = "Submit for QA", message = "Submit this scene file for QA?", button = ['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No')=='Yes':
                         _time = time.strftime("%b%d_%Y_%H-%M-%S", time.localtime(time.time()))
                         file_name = os.path.join(qa_dir, part_name + "_%s_%s.mb"%(self.username,_time))
                         _files = glob.glob(qa_dir+"/*.mb")
                         if len(_files)>0:
                             found=False
                             for i in _files:
                                 if file_name == i:
                                     found=True
                                     if windows.confirmDialog(title = "Overwrite?", message = "A QA file with this name already exists.  Overwrite it?", button = ['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No')=='Yes': 
                                         current_filename = system.sceneName()
                                         system.saveAs(file_name)
                                         system.saveAs(current_filename)
                                         
                                 else:
                                     _folder = os.path.join(qa_dir,os.path.split(i)[1].split(".")[0])
                                     os.makedirs(_folder)
                                     shutil.move(i, _folder)
                             else:
                                 if found==False:
                                     current_filename = system.sceneName()
                                     system.saveAs(file_name)
                                     system.saveAs(current_filename)
                         else:
                             current_filename = system.sceneName()
                             system.saveAs(file_name)
                             system.saveAs(current_filename)
             else:
                 windows.confirmDialog(title = "Part Not Found", message = "The selected part folder cannot be found.", button=["Dismiss"])
Exemple #28
0
	def on_exportButton_clicked(self):
		
		if not ls(selection=True):
			return error('Nothing is currently selected.')
		
		# Load the objExport plug-in if it hasn't been already.
		kwargs = {}
		if self.formatExt.text() == '.obj':
			mll = 'objExport.mll'
			if not pluginInfo(mll, query=True, loaded=True):
				try:
					loadPlugin(mll)
					info('Loaded plug-in: ' + mll)
				except:
					return error('Failed loading plug-in: ' + mll)
			#kwargs = dict(force=True, constructionHistory=False,
			#	channels=False, constraints=False, expressions=True,
			#	shader=False, preserveReferences=False, type='OBJexport')
			options = dict(groups=self.groups, ptgroups=self.pointGroups,
				materials=self.materials, smoothing=self.smoothing,
				normals=self.normals)
			options = ';'.join('%s=%d' % (k, cb.isChecked()) \
				for k, cb in options.items())
			kwargs = dict(exportSelected=True, type='OBJexport', force=True,
				options=options)
		elif self.exportCombo.currentIndex() == 2:  # mesh
			return error('Unsupported extension: %s.' % self.formatExt.text())
		
		# Validate the output path.
		output_path = Path(self.path.text())
		if not output_path.exists():
			output_path = Path(self.set_path(workspace.getPath()))
			if not output_path.exists():
				return
		
		# Validate the frame range.
		start, end, by = self.start.value(), self.end.value(), self.by.value()
		remainder = (end - start) % by
		if remainder:
			click_result = confirmDialog(title='Confirm',
				message=os.linesep.join(( \
				'The end frame will not be exported because',
				'the "by frame" overshoots it by %.2f.' % remainder)),
				button=('OK', 'Cancel'), cancelButton='Cancel',
				defaultButton='OK', dismissString='Cancel')
			if click_result == 'Cancel':
				return
		
		# Validate the format.
		format = str(self.format.text())
		try:
			format % (start + by)
		except TypeError:
			return error('Invalid format: "%s". ' % format + \
				'Click the \'...\' tool button for help.' % format)
		
		# Disable UI elements while running.
		[o.show() for o in self.run_showers]
		[o.setEnabled(False) for o in self.run_disablers]
		
		# Set the range.
		if self.renumFrames.isChecked():
			renum_start = self.renumStart.value()
			self.renum_by = self.renumBy.value()
		else:
			renum_start = start
			self.renum_by = by
		self.frame, self.renum_frame = start, renum_start
		
		# Set loop vars.
		self.aborted = False
		self.export_count = 0
		self.copy_and_replace_all = False
		
		# Call the appropriate export function.
		(self.export_skeleton, self.export_camera, self.export_mesh,
			self.export_skin_weights)[self.exportCombo.currentIndex()](**kwargs)
		
		self.main_progress.endProgress()
		
		# Enable UI elements back.
		[o.hide() for o in self.run_showers]
		[o.setEnabled(True) for o in self.run_disablers]
		
		# Report results.
		if self.aborted:
			msg = 'Aborted with %s exported'
		else:
			msg = 'Successfully exported %s'
		plural = self.export_count != 1 and 's' or ''
		frames = '%d frame' % self.export_count + plural
		result(msg % frames + ' to: %s.' % output_path)
 def performSlice(self):
     #Make sure theres a gizmo, otherwise theres no point in doing anything
     if general.objExists("WaffleSliceGizmo"):
         #Get the step size and step count from the appropriate sliders
         step_size = windows.floatSliderGrp("stepSizeSlider", q = True, v = True)
         step_count = int(windows.floatSliderGrp("stepCountSlider", q = True, v = True))
         #Get the axes filter from the radio buttons
         axes = windows.radioButtonGrp("axesRadioButtonGrp", q = True, sl = True)
         #Iterate through the selected objects and create an array of sliceable ones
         sliceArray = []
         for child in general.ls(sl = True):
             if (child!="WaffleSliceGizmo"):
                 #Make sure the selection is either a transform or mesh
                 if (general.objectType(child)=="transform" or general.objectType(child)=="mesh"):
                     sliceArray.append(child)
         else:
             #If anything was added to the array, then move forwards with the waffle slice
             if len(sliceArray)>0:
                 #Create the slicing proxies that will push the proper transforms and rotates into the slice arguments
                 general.group(n = "slice_proxy_x", em = True)
                 general.xform("slice_proxy_x", t=[general.getAttr("WaffleSliceGizmo.translateX"),
                                              general.getAttr("WaffleSliceGizmo.translateY"),
                                              general.getAttr("WaffleSliceGizmo.translateZ"),]
                                              , ro = [general.getAttr("WaffleSliceGizmo.rotateX"),
                                              general.getAttr("WaffleSliceGizmo.rotateY"),
                                              general.getAttr("WaffleSliceGizmo.rotateZ"),]
                                              ,ws = True)
                 general.group(n = "slice_proxy_y", em = True)
                 general.xform("slice_proxy_y", t=[general.getAttr("WaffleSliceGizmo.translateX"),
                                              general.getAttr("WaffleSliceGizmo.translateY"),
                                              general.getAttr("WaffleSliceGizmo.translateZ"),]
                                              , ro = [general.getAttr("WaffleSliceGizmo.rotateX"),
                                              general.getAttr("WaffleSliceGizmo.rotateY"),
                                              general.getAttr("WaffleSliceGizmo.rotateZ"),]
                                              ,ws = True)
                 general.rotate("slice_proxy_y", (90, 0, 0), r = True, os = True)
                 general.parent("slice_proxy_x", "WaffleSliceGizmo")
                 general.parent("slice_proxy_y", "WaffleSliceGizmo")
                 #Iterate through the list of objects
                 for child in sliceArray:
                     #Move the slicers by half of the total distance they're going to need to slice through
                     general.move("slice_proxy_x", [0,0,(-1*((step_size*step_count)/2))] , r = True, ls = True)#, z = True)
                     general.move("slice_proxy_y", [0, (-1*((step_size*step_count)/2)),0], r = True, ls = True)#, y = True)
                     #Get the options for x, y, or both
                     #Do the slices, and for each iteration, bump each proxy forwards by their allotted amount
                     for i in range(step_count):
                         if (axes == 1 or axes == 3):
                             general.move("slice_proxy_x", [0, 0, step_size] , r = True, ls = True)#, z = True)
                             pos = general.xform("slice_proxy_x", ws = True, q = True, t = True)
                             rot = general.xform("slice_proxy_x", ws = True, q = True, ro = True)
                             modeling.polyCut(child, ro = rot , pc = pos)
                             general.delete(child, ch = True)
                             
                         if (axes == 2 or axes == 3):
                             general.move("slice_proxy_y", [0, step_size, 0], r = True, ls = True)#, y = True)
                             pos = general.xform("slice_proxy_y", ws = True, q = True, t = True)
                             rot = general.xform("slice_proxy_y", ws = True, q = True, ro = True)
                             modeling.polyCut(child, ro = rot , pc = pos)
                             general.delete(child, ch = True)
                     else:
                         #Reset the position of the proxies after each object so they dont fly off into the distance
                         general.xform("slice_proxy_x", t=[general.getAttr("WaffleSliceGizmo.translateX"),
                                                      general.getAttr("WaffleSliceGizmo.translateY"),
                                                      general.getAttr("WaffleSliceGizmo.translateZ"),]
                                                      , ws = True)
                         general.xform("slice_proxy_y", t=[general.getAttr("WaffleSliceGizmo.translateX"),
                                                      general.getAttr("WaffleSliceGizmo.translateY"),
                                                      general.getAttr("WaffleSliceGizmo.translateZ"),]
                                                      , ws = True)
                         
                 else:
                     #Clean up the slice proxies
                     general.delete("slice_proxy_x")
                     general.delete("slice_proxy_y")
     else:
         print("No slice gizmo")
Exemple #30
0
	def export_skin_weights(self):
		
		format, ext = str(self.format.text()), str(self.formatExt.text())
		format = self.name_pat.sub( \
			lambda m: '%(name)' + m.group(1)[1:], format)
		path = Path(self.path.text())
		
		# Validate selection.
		sel = selected()
		if not sel:
			error('Selection is empty.')
		
		# Find the skin cluster.
		sc = mel.findRelatedSkinCluster(sel[0])
		skin_cluster = None
		for s in sel:
			sc = mel.findRelatedSkinCluster(s)
			if sc:
				skin_cluster = ls(sc)[0]
				break
		if not skin_cluster:
			error('No skin cluster found.')
		
		for mesh in sel:
			
			mesh_element = Element('Mesh', name=mesh)
			xml_tree = ElementTree(mesh_element)
			
			sc = mel.findRelatedSkinCluster(mesh)
			if not sc: continue
			sc = ls(sc)[0]
			
			influences = sc.influenceObjects()
			inf_tag = SubElement(mesh_element, 'Influences')
			for i, inf in enumerate(influences):
				SubElement(inf_tag, 'Influence', index=str(i), name=inf)
			#joints = ls(ios, type='joint')
			#if len(joints) < len(ios):
			#	error('Remove non-joint influences before exporting to Massive.')
			
			# TODO: progress bar
			
			name = format % dict(name=mesh.name().replace('|', '') \
				.replace(':', '.')) + ext
			with open(path / name, 'w') as f:
				
				#f.write(os.linesep + '# influences')
				#for i, inf in enumerate(ios):
				#	if inf in influences:
				#		inf_index = influences.index(j)
				#	else:
				#		influences += (inf,)
				#		inf_index = len(influences)
					#f.write('%sdeformer %d %s' % (os.linesep, i, inf))
				
				#f.write(os.linesep)
				
				vertices = SubElement(mesh_element, 'Vertices')
				
				#f.write(os.linesep + '# weights')
				for i, vtx in enumerate(mesh.vtx):
					vertex = SubElement(vertices, 'Vertex', pos=str(vtx.getPosition()))
					#f.write('%s%d: ' % (os.linesep, vi))
					for ii, inf in enumerate(influences):
						weight_val = skinPercent(sc, '%s.vtx[%d]' % (mesh, i),
							transform=inf, query=True)
						if weight_val:
							SubElement(vertex, 'Weight', influence=str(ii),
								value=str(weight_val))
							#f.write(' %d %f' % (ii, weight_val))
				
				
				
				#f.write(os.linesep + ':')
				rough_string = tostring(xml_tree.getroot(), 'utf-8')
				reparsed = minidom.parseString(rough_string)
				f.write(reparsed.toprettyxml(indent='\t'))
Exemple #31
0
    def __init__(self, root_cls=None, *args, **kwargs):
        """
		Flags:
			- bone_radius: br				(int, default:1)
				Sets all joints' bone radii. This flag only works if -vary_bone_radius
				is False.
			
			- nhpat								(string, default:<nt>_<s><ss>_<n><ns>)
				Establishes a naming convention where 'nt' is the node type
				(drive or bind joint), 's' in the side, 'ss' is the side sequence,
				'n' is the name and 'ns' is the name sequence.
			
			- long_bone_radius: lbr		(float, default:2.0)
				Sets -vary_bone_radius' maximum range. This flag only works if
				-vary_bone_radius is True.
			
			- short_bone_radius: sbr		(float, default:0.5)
				Sets -vary_bone_radius' minimum range. This flag only works if
				-vary_bone_radius is True.
			
			- test_bone_radius: tebr		(bool, default:False)
				Tests the bone radius settings without continuing the
				rigging process.
			
			- tip_bone_radius: tbr			(float, default:0.25)
				Sets all tip joints' bone radii. This flag only works if -vary_bone_radius
				is True.
		"""

        # Find the joint-chain's root joint.
        joints = ls(selection=True, type='joint')
        roots = []
        for j in joints:
            while True:
                pj = j.listRelatives(parent=True, type='joint')
                if pj:
                    j = pj[0]
                elif j not in roots:
                    roots.append(j)
                    break

        assert len(roots), 'Selection requires at least one joint.'

        # Vary bone radius.
        self._short_bone_radius = kwargs.pop(
            'sbr', kwargs.pop('short_bone_radius', self._short_bone_radius))
        self._long_bone_radius = kwargs.pop(
            'lbr', kwargs.pop('long_bone_radius', self._long_bone_radius))
        self._tip_bone_radius = kwargs.pop(
            'tbr', kwargs.pop('tip_bone_radius', self._tip_bone_radius))
        for r in roots:
            self.set_bone_length_range(r)
            self.set_bone_radii(r)
        test_bone_radius = kwargs.pop('tebr',
                                      kwargs.pop('test_bone_radius', False))
        if test_bone_radius: return

        if not issubclass(root_cls, CharacterJoint):
            raise TypeError("%s class must be a subclass of %s." \
             % (root_cls.__name__, CharacterJoint))

        # NameHelper segments establish a naming convention for this character.
        self.name_helper = kwargs.pop('nh', kwargs.pop('name_helper', None))
        if not self.name_helper:
            self.name_helper = NameHelper()

        # In order to distinguish the character's left and right sides, first we need to
        # define the character's front axis.
        self.front = kwargs.pop('front', 'z')

        for jdict in [self.drive_joints, self.bind_joints]:
            jdict[root_cls] = []
        for i, root in enumerate(roots):
            # Clean-up the joint chain by freezing rotate and scale
            makeIdentity(root, apply=True, rotate=True, scale=True)

            # Recurse through the entire joint chain, assigning the appropriate
            # CharacterJoint class to each joint.
            self.drive_joints[root_cls].append(
                root_cls(root, self, jdict=self.drive_joints, *args, **kwargs))
            self.bind_joints[root_cls].append(
                root_cls(root.duplicate()[0],
                         self,
                         jdict=self.bind_joints,
                         *args,
                         **kwargs))

        # Recursion added joints to the lists backwards, so reverse it to
        # keep the joints in a top-down relationship.
        for jdict in [self.drive_joints, self.bind_joints]:
            [jdict[cls].reverse() for cls in jdict.keys()]

        # Change the name of the joints to something they would not use
        # to prevent any naming conflicts in the future.
        roots.extend(self.bind_joints[root_cls])
        function_on_hierarchy(roots, rename, 'FooJoint#')

        # Name joints.
        for cls, dj_list in self.drive_joints.items():
            for i, dj in enumerate(dj_list):
                while True:
                    self.rename_part(dj)
                    if len(ls(dj.nodeName())) == 1:
                        bj = self.bind_joints[cls][i]
                        dj.bind_joint = bj
                        bj.drive_joint = dj
                        bj.side_sequence = dj.side_sequence
                        self.rename_part(bj)
                        break
                    dj.side_sequence += 1
Exemple #32
0
	def export_camera(self):
		
		start, end = self.start.value(), self.end.value()
		path = Path(self.path.text())
		
		# Validate the selection.
		sel = ls(selection=True, dagObjects=True, cameras=True)
		if not ls(selection=True):
			return error('No cameras in selection.')
		
		# Associate the camera shapes with their parents.
		cams = dict((s, s.getParent()) for s in sel)
		
		# Pull-out only the attributes that are checked.
		shape_atts = []
		for cb in self.cameraChannelsLayout.findChildren(QCheckBox):
			if cb.isChecked():
				[shape_atts.extend(str(cb.property(n).toString()).split('|')) \
					for n in cb.dynamicPropertyNames() if n == 'shortName']
		cam_atts = (cb.objectName() for cb \
			in self.translation.findChildren(QCheckBox) if cb.isChecked())
		attributes = (shape_atts, cam_atts)
		
		# Enable any locked or non-keyable channels.
		for shape, cam in cams.items():
			for i, obj in enumerate((shape, cam)):
				for att in attributes[i]:
					obj.attr(att).set('locked', False)
					obj.attr(att).set('keyable', True)
		
		# Initialize the progress bar.
		lc = len(cams)
		self.progress_init(lc + lc * len([x for x in (self.createStandIn.isChecked(),
			self.oneFile.isChecked() and self.oneFilePerNode.isChecked) if x]))
		
		# Bake the keys to the camera shape.
		frame_range = self.animation.isChecked() and (start, end) or (start,)
		for shape, cam in cams.items():
			if self.aborted: return
			
			info('Baking keys to %s: %d-%d...' % \
				((shape,) + frame_range))
			bakeResults(shape, time=frame_range, simulation=True,
				attribute=shape_atts)
			info('%s keys %d-%d baked.' % ((shape,) + frame_range))
			
			self.progress_step()
		
		# Disable the cycle check warning.
		cycleCheck(evaluation=False)
		
		# Create a null stand-in for the camera and bake keys to it.
		#mel.source('channelBoxCommand.mel')
		if self.createStandIn.isChecked():
			for cam in cams.values():
				if self.aborted: return
				
				stand_in = Transform(name='standInNull')
				parentConstraint(cam, stand_in, name='nullParentConstraint')
				info('Baking keys to the stand-in null...')
				bakeResults(stand_in, time=frame_range, shape=True,
					simulation=True, attribute=cam_atts)
				info('Null keys baked.')
				
				# If the camera is a child, parent it to the world.
				if cam.firstParent2():
					cam.setParent(world=True)
				
				# Break existing connections between the rotate or translate
				# attributes.
				for att in cam_atts:
					if connectionInfo(cam, isExactDestination=True):
						disconnectAttr(connectionInfo(cam,
							getExactDestination=True))
						#mel.CBdeleteConnection(getExactDestination=True)
				
				# Constrain the camera to the null.
				parentConstraint(stand_in, cam, name='cameraParentConstraint')
				
				# Bake the camera translate/rotate keys.
				info('Baking keys to the camera...')
				bakeResults(cam, time=frame_range, disableImplicitControl=True,
					simulation=True, attribute=cam_atts)
				info('Transform keys baked.')
				
				self.progress_step()
				
		# Remove excess elements unless optimize has been disabled.
		if self.optimize.isChecked():
			info('Optimizing scene...')
			delete([s for s in ls(dagObjects=True) if s not in cams.keys() + \
				cams.values() + ls(selection=True, type='animCurve')])
		
		# Save-out the cameras.
		kwargs = dict(force=True, constructionHistory=False, channels=True,
			constraints=False, expressions=False, shader=False,
			type='mayaAscii')
		ext = str(self.formatExt.text())
		if self.oneFile.isChecked():
			if self.oneFilePerNode.isChecked():
				for cam in cams.values():
					if self.aborted: return
					select(cam)
					exportSelected(path / cam.name() + ext, **kwargs)
					self.progress_step()
			else:
				select(cams.values())
				exportSelected(path / 'camera' + ext, **kwargs)
		else:
			error('Not implemented yet. Coming soon...')
Exemple #33
0
	def __init__(self, driver=shapes.Plus, driven=None, **kwargs):
		
		# Driver
		if not isinstance(driver, shapes.Shape) and issubclass(driver, shapes.Shape):
			driver = driver()
		assert isinstance(driver, shapes.Shape), \
			("Parameter 'driver' must be an instance or subclass of %s." %
			 shapes.Shape.__name__)
		self._driver = driver
		self._transform = driver.get_transform()
		self._shapes = self._transform.getShapes()
		
		# Driven
		if not driven:
			driven = ls(selection=True, transforms=True)
			assert len(driven) == 1, "Parameter 'driven' requires exactly one transform."
			driven = driven[0]
		self._driven = driven
		
		# Face Axis
		face_x = kwargs.pop('fx', kwargs.pop('faceX', False))
		face_y = kwargs.pop('fy', kwargs.pop('faceY', False))
		face_z = kwargs.pop('fz', kwargs.pop('faceZ', False))
		face_sum = sum([face_x, face_y, face_z])
		if not face_sum:
			face_x = True
			face_sum = 1
		else:
			assert face_sum == 1, "Rig control can only face one axis."
		rotate(self._transform, [face_z and 90 or 0, 0, face_x and -90 or 0])
		select(self._transform)
		FreezeTransformations()
		
		# Constraints
		do_parent_constraint = kwargs.pop('pc', kwargs.pop('parentConstraint', False))
		do_point_constraint = kwargs.pop('xc', kwargs.pop('pointConstraint', False))
		do_orient_constraint = kwargs.pop('oc', kwargs.pop('orientConstraint', False))
		do_scale_constraint = kwargs.pop('sc', kwargs.pop('scaleConstraint', False))
		if do_parent_constraint or do_point_constraint or do_orient_constraint or \
			do_scale_constraint:
			self._buffer = Transform()
			snap(self._buffer, self._driven, scale=True)
			select(self._buffer)
			parent(self._transform, self._buffer)
			if do_parent_constraint:
				parentConstraint(self._transform, self._driven)
			else:
				if do_point_constraint:
					pointConstraint(self._transform, self._driven)
				if do_orient_constraint:
					orientConstraint(self._transform, self._driven)
			if do_scale_constraint:
				scaleConstraint(self._transform, self._driven)
		elif isinstance(self._driven, Joint):
			# Parent the drivers directly underneath the driven joint.
			parent(self._driver, self._driven, relative=True, shape=True)
			delete(self._transform)
			self._transform = self._driven
		elif isinstance(self._driven, IkHandle):
			self._buffer = self._transform
			self._transform = self._driven
			snap(self._ebuffer, self._transform)
			parent(self._transform, self._buffer)
			parent(self._driver, self._transform, relative=True, shape=True)
		else:
			# Parent the drivers underneath a new buffered transform.
			self._buffer = self._driven
			parent(self._transform, self._buffer)
			parent(self._buffer.getShapes(), self._transform, relative=True, shape=True)
			# Pop the shape nodes out and back in to reorder the driven shape(s) to
			# the top. This way, the Outliner icons for this transform will reflect the
			# appropriate first-child shape node.
			parent(self._driver, self._buffer, relative=True, shape=True)
			parent(self._driver, self._transform, relative=True, shape=True)
		if self._buffer:
			select(self._transform)
			ResetTransformations()
			for trs in 'trs':
				for xyz in 'xyz':
					self._buffer.attr(trs + xyz).lock()
		
		if isinstance(self._driven, IkHandle):
			self.__class__ = IkRigControl
			self.__init__()