예제 #1
0
 def make_cylinder(self):
     pm.polyCylinder(r=self.r, h=self.h, sx=self.sx, sy=self.sy)
     pm.move(
         0,
         3,
         0,
         'pCylinder1.scalePivot',
         'pCylinder1.rotatePivot',
         r=True,
     )
예제 #2
0
def create_bind_proxy(jnt):
    if jnt.getChildren():
        name=jnt.name() + "_bindProxy"
         
        distance = jnt.getChildren()[0].translateX.get()
        if not pm.objExists(name):
            proxy = pm.polyCylinder(r=0.25, h=0.5, sx=12, sy=4, sz=4, ax=[1,0,0], rcp=1, cuv=0, ch=0, name=name)[0]
            pm.xform(proxy, piv=[-0.5, 0, 0])
             
            pm.parent(proxy, 'bind_proxy')
             
            pm.delete(pm.parentConstraint(jnt, proxy, mo=False))
            proxy.scale.set(distance, distance, distance)
             
            try:
                jnt.addAttr('iterations', at='long', min=1, max=5, dv=3, k=True)
                jnt.addAttr('bind_proxy', at='message')
            except:
                pass            
                 
        else:
            proxy = pm.PyNode(name)

        
        pm.skinCluster( jnt, proxy, tsb=True)
        proxy.message >> jnt.bind_proxy            
예제 #3
0
	def make_branch(self,h,w):
		print(w)
		i = pm.polyCylinder(height=h,radius=w)
		pm.select(i[0])
		pm.hyperShade(assign=self.branchShader)
		print("Constructed {} {} {}".format(i[0],h,w))
		return i
예제 #4
0
 def drawHelix(self, origin, length, axis,number=None):
     """
     origin: defines the starting point of one end of the helix
     axis: vector defining the spatial direction of the helix
     height: length of the cylinder
     """
     # returns [nt.Transform(u'helix0'), nt.PolyCylinder(u'polyCylinder1')]
     # modify the cylinder length with temp[1].setHeight() and temp[0].setTranslation([0,], space = 'object')
     # so if you want to stretch in one direction only,
     # the origin of a cylinder is it's geometric center
     temp = pc.polyCylinder(axis=axis,radius=(self.helix_diameter/self.unit_scale/2), height=length, name='helix0')[0]
     # set position in the Transform Node
     temp.setTranslation(origin, space='object') 
     
     # apply coloring
     pc.general.sets(self.colorshader, edit=True, forceElement=temp)
     #mypoint = (origin[0],origin[1],origin[2])
     # if number != None:
     #     mynote = str(number)
     # else:
     #     mynote = 'awesome'
     #pc.windows.annotate( temp[0].name(), tx=mynote, p=mypoint ) 
     # set up parent group
     pc.general.parent(temp.name(), self.group.name())
     return temp
예제 #5
0
def create_tower_top(y_position, radius):
    """Create the top of the tower which consists of a cylinder, then some parapets on top to look like a medieval tower

    Args:
        y_position (float): The position in y for this tower section
        radius (float): The radius of this tower section
    """
    tower_top_parts = []

    # create cylinder
    name = pm.polyCylinder(name='towerTopBase#',
                           height=3.0,
                           radius=radius,
                           subdivisionsY=3,
                           subdivisionsCaps=10)[0]

    # move so bottom in correct location compared to previous section
    pm.move(name, y_position, y=True)

    tower_top_parts.append(name)

    # create parapets
    # create cylinder
    name = pm.polyCylinder(name='towerTopParapets#',
                           height=5.0,
                           radius=radius + 0.5,
                           subdivisionsY=2,
                           subdivisionsCaps=10)[0]

    # move so bottom in correct location compared to previous section
    pm.move(name, y_position + 5.0 / 2 + 3.0 / 2, y=True)

    # Extrude the central faces of the tower inwards to make hollowed section
    pm.polyExtrudeFacet(name + '.f[240:399]',
                        name + '.f[420:440]',
                        divisions=2,
                        localTranslateZ=-4.5)

    # Select the even faces on the edge of the tower for extruding
    pm.polyExtrudeFacet(
        [name + '.f[' + str(x) + ']' for x in range(220, 240) if x % 2 == 0],
        localTranslateZ=2)

    tower_top_parts.append(name)

    return pm.group(*tower_top_parts, name='towerTop#')
예제 #6
0
def create_bind_proxy(jnt):
    if jnt.getChildren():
        name=jnt.name() + "_bindProxy"
         
        distance = jnt.getChildren()[0].translateX.get()
        if not pm.objExists(name):
            proxy = pm.polyCylinder(r=0.25, h=0.5, sx=12, sy=4, sz=4, ax=[1,0,0], rcp=1, cuv=0, ch=0, name=name)[0]
            pm.xform(proxy, piv=[-0.5, 0, 0])
             
            pm.parent(proxy, 'bind_proxy')
             
            pm.delete(pm.parentConstraint(jnt, proxy, mo=False))
            proxy.scale.set(distance, distance, distance)
             
            try:
                jnt.addAttr('iterations', at='long', min=1, max=5, dv=3, k=True)
                jnt.addAttr('bind_proxy', at='message')
            except:
                pass            
                 
        else:
            proxy = pm.PyNode(name)

        
        pm.skinCluster( jnt, proxy, tsb=True)
        proxy.message >> jnt.bind_proxy           
#===============================================================================
#     if not joint.getChildren(): #not end joints
#         return
# 
#     if not joint.hasAttr('bind_proxy'): 
#         joint.addAttr('bind_proxy', at='message')
#     
#     name = joint.name() + "_bindProxy"
#      
#     distance = joint.getChildren()[0].translateX.get()
#     if not pm.objExists(name):
#         proxy = pm.polyCylinder(r=0.25, h=0.5, sx=12, sy=4, sz=4, ax=[1,0,0], rcp=1, cuv=0, ch=0, name=name)[0]
#         pm.xform(proxy, piv=[-0.5, 0, 0])
#          
#         pm.delete(pm.parentConstraint(joint, proxy, mo=False))
#         proxy.scale.set(distance, distance, distance)
#         
#     else:
#         proxy = pm.PyNode(name)
#          
#     pm.skinCluster( joint, proxy, tsb=True)
#     
#     proxy.sy.setLocked(False)
#     proxy.sy.set_nonKeyable(True)
#     proxy.sz.setLocked(False)
#     proxy.sz.set_nonKeyable(True)
#     
#     proxy.message >> joint.bind_proxy
#         
#===============================================================================
    return proxy    
예제 #7
0
파일: util.py 프로젝트: Mikfr83/fossil
def makeFakeBone():
    ''' Used by polySkeleton '''
    bone = polyCylinder()[0]
    bone.ty.set(1)
    makeIdentity(bone, t=True, apply=True)
    xform(bone, ws=True, piv=(0, 0, 0))
    #scale -r -p -1.19209e-07cm 2cm -1.78814e-07cm 0.0229933 0.0229933 0.0229933 ;
    scale( bone.vtx[20:39], (0, 0, 0), r=True, p=(0, 2, 0) )
    return bone
예제 #8
0
 def _create_instance_pole(self, instance_name):
     # Create pole
     c = pm.polyCylinder(name=self.pole_name,
                         height=self.plant_height,
                         radius=self.pole_radius,
                         subdivisionsHeight=20)
     pm.move(self.pole_name, [0, self.plant_height / 2.0, 0])
     self._mark_stage_completed(instance_name, "stem")
     return c
def randPrims(numPrims, maxSize, minX, maxX, minY, maxY, minZ, maxZ, minSize=0.1): 
	prims = []
	
	for m in range(numPrims):
	# roll a random whole number between 0 to 4:
		p = random.randrange(0,5)
		if p == 0:
	# roll a random number between 0 and max sizes for all parameters
			radiusSphere = random.uniform(minSize, maxSize)
			x = random.uniform(minX, maxX)
			y = random.uniform(minY, maxY)
			z = random.uniform(minZ, maxZ)
			# store the object in a variable temporarily so it's easier to append it to the list
			n = pm.polySphere(r=radiusSphere)[0]
			pm.move(n, x, y, z)
			prims.append(n) 
		# create elif statements in case we roll 1, 2, 3 or 4
		elif p == 1:
			volCube = random.uniform(minSize, maxSize)
			x = random.uniform(minX, maxX)
			y = random.uniform(minY, maxY)
			z = random.uniform(minZ, maxZ)
			n = pm.polyCube(w=volCube, h=volCube, d=volCube)[0]
			pm.move(n, x, y, z)
			prims.append(n)
		elif p == 2:
			radiusCyl = random.uniform(minSize, maxSize)
			heightCyl = random.uniform(minSize, maxSize)
			x = random.uniform(minX, maxX)
			y = random.uniform(minY, maxY)
			z = random.uniform(minZ, maxZ)
			n = pm.polyCylinder(h=heightCyl, r=radiusCyl)[0]
			pm.move(n, x, y, z)
			prims.append(n)
		elif p == 3:
			radiusCone = random.uniform(minSize, maxSize)
			heightCone = random.uniform(minSize, maxSize)
			x = random.uniform(minX, maxX)
			y = random.uniform(minY, maxY)
			z = random.uniform(minZ, maxZ)
			n = pm.polyCone(h=heightCone, r=radiusCone)[0]
			pm.move(n, x, y, z)
			prims.append(n)
		elif p == 4:
			widthPlane = random.uniform(minSize, maxSize)
			heightPlane = random.uniform(minSize, maxSize)
			x = random.uniform(minX, maxX)
			y = random.uniform(minY, maxY)
			z = random.uniform(minZ, maxZ)
			n = pm.polyPlane(h=heightPlane, w=widthPlane)[0]
			pm.move(n, x, y, z)
			prims.append(n)
			
	return prims
예제 #10
0
    def make_proxy_wheel(obj, wheel_name, cutout=False):
        tolerance = .5
        sel = pm.selected()
        bb = obj.getBoundingBox()
        radius = max(bb.depth(), bb.width(), bb.height())/2
        height = min(bb.depth(), bb.width(), bb.height())
        
        axis = [0,1,0]
        if bb.height() - bb.width() > tolerance: # allow for a tolerance of difference
            axis = [1,0,0]
        if bb.width() - bb.depth() > tolerance:
            axis = [0,0,1]
        #print axis, bb.depth(), bb.width(), bb.height()
        cylinder = pm.polyCylinder(n=wheel_name, axis=axis, height=height, radius=radius, sc=True)
        pm.xform(cylinder, t=bb.center())
        
        cylinder_shape = cylinder[0].getShape()
        bevel_edges = cylinder_shape.e[0:39]
        pm.polyBevel(bevel_edges, com=0, fraction=0.4, offsetAsFraction=1, 
                     autoFit=1, segments=4, worldSpace=1, uvAssignment=0, 
                     smoothingAngle=30, fillNgons=1, mergeVertices=1, 
                     mergeVertexTolerance=0.0001, miteringAngle=180, angleTolerance=180, ch=1)
        pm.polyExtrudeFacet(cylinder_shape.f[180:219], ltz=-0.16, lsx=0.2, lsy=0.2)
        light_faces_indexes = [224, 225, 228, 229, 232, 233, 244, 245, 248, 249, 252, 253]

        dark_faces = [face for face in cylinder_shape.f[:] if face.index() not in light_faces_indexes]
        dark_lambert = pm.shadingNode("blinn", n="dark_shader", asShader=True)
        dark_lambert.color.set([.16, .16, .16])
        dark_lambert.eccentricity.set(0.5)
        dark_lambert.specularColor.set([.16, .16, .16])
        
        dark_set = pm.sets( renderable=True, noSurfaceShader=True, empty=True, name="dark_shaderSG" )
        dark_lambert.outColor.connect(dark_set.surfaceShader)
        pm.sets(dark_set, forceElement=dark_faces)      
          
        light_faces = [cylinder_shape.f[index] for index in light_faces_indexes]
        light_lambert = pm.shadingNode("lambert", n="light_shader", asShader=True)
        light_lambert.color.set([.7, .7, .7])
        light_set = pm.sets( renderable=True, noSurfaceShader=True, empty=True, name="light_shaderSG" )
        light_lambert.outColor.connect(light_set.surfaceShader)
        pm.sets(light_set, forceElement=light_faces)      
        
        if cutout:
            if "r_" == wheel_name[:2]:
                pm.delete(cylinder_shape.f[200:219])
            if "l_" == wheel_name[:2]:
                pm.delete(cylinder_shape.f[180:199])
            
        pm.select(sel,r=True)
        return cylinder[0]
예제 #11
0
def line_generator(source_lines, source_verts, gen_bones, settings):
    lines = []
    for i in range(len(source_lines)):
        line = source_lines[i]
        vert1 = source_verts[line.vertex1]
        vert2 = source_verts[line.vertex2]
        dx = vert2.x - vert1.x
        dy = vert2.y - vert1.y
        dz = vert2.z - vert1.z
        dist = math.sqrt(dx**2 + dy**2 + dz**2)

        poly_transform, poly_cylinder = pm.polyCylinder(
            n="Line" + str(i),
            h=dist,
            r=settings.line_radius,
            sa=settings.line_resolution)
        poly_transform.translate.set(
            (dx / 2 + vert1.x, dy / 2 + vert1.y, dz / 2 + vert1.z))
        phi = math.degrees(math.atan2(dz, -dx))
        theta = math.degrees(math.acos(dy / dist))
        poly_transform.setRotationOrder('XZY', True)
        poly_transform.rotate.set([0, phi, theta])
        poly_shape = poly_transform.getShape()

        if settings.use_palette:
            sg = "paletteSG" + str(line.colour)
            pm.sets(sg, edit=True, forceElement=poly_transform)
        pm.polySoftEdge(a=180)
        if settings.use_rigging:
            pm.select(d=True)
            cluster = pm.skinCluster(gen_bones[vert1.bone],
                                     gen_bones[vert2.bone],
                                     poly_shape,
                                     tsb=True)
            if vert1.bone != vert2.bone:
                pm.select(poly_shape.vtx[:3])
                pm.skinPercent(cluster,
                               transformValue=[(gen_bones[vert1.bone], 1),
                                               (gen_bones[vert2.bone], 0)])
                pm.select(d=True)
                pm.select(poly_shape.vtx[3:])
                pm.skinPercent(cluster,
                               transformValue=[(gen_bones[vert1.bone], 0),
                                               (gen_bones[vert2.bone], 1)])
        lines.append(poly_shape)
    pm.select(d=True)
    return lines
예제 #12
0
def makeArrow():
    '''
    Creates an arrow, with the base vert of 60 and tip of 60.
    '''
    arrow = polyCylinder(r=1, h=10, sx=20, sy=2, sz=1, ax=[0, 1, 0])[0]
    scale(arrow.vtx[40:59], [1.75, 0, 1.75])
    arrow.ty.set(5)
    makeIdentity(arrow, apply=True, t=True, r=True, s=True, n=False)
    xform(arrow, piv=(0, 0, 0), ws=True)
    delete(arrow, ch=True)

    jnt = joint(None)
    jnt.drawStyle.set(2)
    arrow.getShape().setParent(jnt, add=True, shape=True)
    delete(arrow)

    return jnt
예제 #13
0
def create_shapes(*args):
    print('This will create shapes')
    num = slider1.getValue()
    print('Number of shapes to be created:', num)

    i = 0
    while i < num:
        value = float(i) / num
        angle = random.randint(0, 359)
        radius = random.uniform(0.5, 2)
        height = random.uniform(0.5, 1)
        x, y, z = pm.pointOnCurve('curve1', pr=value, turnOnPercentage=True)

        x1 = random.uniform(x - 3, x + 3)
        y1 = random.uniform(y - 3, y + 3)
        z1 = random.uniform(z - 3, z + 3)

        shape = options.getValueArray4()
        j = random.randint(0, 3)
        if shape[j] == True:
            if j == 0:
                figure = pm.polyTorus(r=radius, sr=0.25)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 1:
                figure = pm.polyCone(sx=1, sy=1.5, sz=0.5, r=radius, h=height)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 2:
                figure = pm.polySphere(r=radius)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 3:
                figure = pm.polyCylinder(r=radius, h=height)
                pm.move(x1, y1, z1, figure)
                i += 1
            pm.select(figure)
            pm.rotate(angle, 0, 0, r=True)
            pm.select(clear=True)
예제 #14
0
def axisWidget(parentUnder=BLANK):
    ''' Makes colored object represent the 3 axes (as a child of the selection if possible).
    
    Can take an object to be the parent, or None for no parent.
    '''

    sel = selected()

    info = {
        'x': [[1, 0, 0], [1, 0, 0, 1]],
        'y': [[0, 1, 0], [1, 1, 0, 1]],
        'z': [[0, 0, 1], [0, 0, 1, 1]],
    }

    cyls = []
    for name, (axis, color) in info.items():
        cyl = polyCylinder(radius=.1, axis=axis)[0]
        cyl.t.set(axis)

        polyColorPerVertex(cyl, r=color[0], g=color[1], b=color[2])
        cyl.displayColors.set(True)
        cyls.append(cyl)

    obj = polyUnite(cyls, ch=False)[0]

    if parentUnder is not None:
        try:
            if parentUnder is BLANK:
                if sel:
                    obj.setParent(sel[0])
            else:
                obj.setParent(parentUnder)

            obj.t.set(0, 0, 0)
            obj.r.set(0, 0, 0)
        except Exception:
            pass

    return obj
예제 #15
0
def create_tower_section(y_position, height, radius):
    """Create a main tower section

    Args:
        y_position (float): The position in y for this tower section
        height (float): The height of this tower section
        radius (float): The radius of this tower section

    Returns:
        str: The name of the tower section
    """
    # create cylinder
    name = pm.polyCylinder(name='towerSection#',
                           height=height,
                           radius=radius,
                           subdivisionsY=3,
                           subdivisionsCaps=5)[0]

    # move so bottom in correct location compared to previous section
    pm.move(name, y_position, y=True)

    return name
예제 #16
0
def create_bind_proxy(jnt):
    name = jnt.name() + "_bindProxy"

    if not pm.objExists(name):
        proxy = pm.polyCylinder(r=0.25, h=1, sx=30, sy=10, sz=0, ax=[1, 0, 0], rcp=0, cuv=0, ch=0, name=name)[0]
        pm.xform(proxy, piv=[-0.5, 0, 0])

        pm.parent(proxy, "bind_proxy")

        pm.delete(pm.parentConstraint(jnt, proxy, mo=False))

        distance = jnt.length.get()
        proxy.scale.set(distance, distance, distance)

    else:
        proxy = pm.PyNode(name)

    if not proxy.hasAttr("bind_joint"):
        proxy.addAttr("bind_joint", at="message")

    jnt.message >> proxy.bind_joint

    return proxy
예제 #17
0
def extendPipe( jointLength=1 ):

	defaultLength = 3.0
	currJnt = ''
	name = ''
	root = ''

	newJnts = []

	for sel in pm.selected():
		sel.select()
		# for now, there's no branching, so we find the deepest joint
		try:
			currJnt = sel
			name = currJnt.split('_')[0]
			root = pm.nt.Joint( '%s_Jnt0' % name )

		except:
			raise "select an object on the pipe that you want to extend"


		# naming
		#----------
		num = int(currJnt.extractNum())

		try:
			twoPrev = int(currJnt.getParent().getParent().extractNum())
		except:
			twoPrev = num-2

		try:
			prev =	int(currJnt.getParent().extractNum())
		except:
			prev = num-1

		curr = num
		new = int(currJnt.nextUniqueName().extractNum())

		print "extending from", currJnt, new

		branchNum = len(currJnt.getChildren())
		#print '%s has %s children' % (currJnt, branchNum)
		if branchNum:
			print "new segment is a branching joint"
			currJnt.addAttr( 'pipeLengthInBtwn%s' % branchNum, min=0 )
			#currJnt.attr( 'pipeLengthInBtwn%s' % branchNum ).showInChannelBox(1)

		#print twoPrev, prev, curr, new

		rigGrp = '%s_RigGrp' % name
		geoGrp = '%s_GeoGrp' % name

		# new skeletal joint
		#---------------------

		if new>1:
			prevJnt = pm.nt.Joint( '%s_Jnt%s' % (name, prev) )
			pos = 2*currJnt.getTranslation(ws=1) - prevJnt.getTranslation(ws=1)
		else:
			prevJnt = None
			pos = currJnt.getTranslation(ws=1) + [0,defaultLength,0]

		newJnt = pm.joint( p=pos, n= '%s_Jnt%s' % (name, new) )
		# re-orient the last created joint, which is considered our current joint
		pm.joint( currJnt, e=1, zeroScaleOrient=1, secondaryAxisOrient='yup', orientJoint='xyz')



		# pymel method: NEEDS FIXING
		#currJnt.setZeroScaleOrient(1)
		#currJnt.setSecondaryAxisOrient('yup') # Flag secondaryAxisOrient can only be used in conjunction with orientJoint flag.
		#currJnt.setOrientJoint('xyz')
		newJnt.scale.lock()

		newJnt.addAttr( 'pipeLength',
			defaultValue=jointLength, min=.0001 )
		newJnt.pipeLength.showInChannelBox(1)

		newJnt.addAttr( 'pipeLengthInBtwn0', min=0 )
		#newJnt.attr( 'pipeLengthInBtwn0' ).showInChannelBox(1)

		newJnt.addAttr( 'pipeLeadIn', dv=0, min=0 )
		newJnt.pipeLeadIn.showInChannelBox(1)

		newJnt.addAttr( 'radiusMultiplier', dv=1, min=0 )
		newJnt.radiusMultiplier.showInChannelBox(1)
		newJnt.displayHandle = 1

		newJnt.radius.showInChannelBox(0)

		# bend hierarchy
		#-----------------

		trans = pm.group( empty=1, n='%s_Elbow%s' % (name, new))
		trans.rotateOrder = 1

		pm.aimConstraint( 	currJnt, trans,
							aimVector = [0, -1, 0],
			 				upVector = [-1, 0, 0]
							)
		pm.pointConstraint( newJnt, trans )

		trans.setParent( rigGrp )

		# keep the end joint oriented along the joint chain so that it can be slid back
		# and forth to change the length of the current pipe segment
		pm.delete( pm.orientConstraint( trans, newJnt ) )

		# Main Pipe
		#------------
		pipe, pipeHist = pm.polyCylinder( height = 1, radius=1,
							name = '%s_Geo%s' % (name, new) )
		pipeHist = pipeHist.rename( '%s_GeoHist%s' % (name, new)  )

		pipe.setPivots( [0, -.5, 0], r=1 )


		root.globalPipeRadius >> pipe.sx
		root.globalPipeRadius >> pipe.sz

		pipeHist.createUVs = 3   # normalize and preserve aspect ratio
		root.subdivisionsAxis >> pipeHist.subdivisionsAxis


		# Pipe Connectors
		#-------------
		pipeConn1, pipeConnHist1 = pm.polyCylinder( height = .1, radius=1,
							name = '%s_Connector1AGeo%s' % (name, new) )
		pipeConnHist1 = pipeConnHist1.rename( '%s_Connector1AHist%s' % (name, new)  )
		pipeConn1.setPivots( [0, -.05, 0], r=1 )
		pipeConn1.setParent( pipe, relative=True )
		pipeConn1.rotate.lock()
		root.subdivisionsAxis >> pipeConnHist1.subdivisionsAxis


		pipeConn2, pipeConnHist2 = pm.polyCylinder( height = .1, radius=1,
							name = '%s_Connector2AGeo%s' % (name, new) )
		pipeConnHist2 = pipeConnHist2.rename( '%s_Connector2AHist%s' % (name, new)  )
		pipeConn2.setPivots( [0, .05, 0], r=1 )
		pipeConn2.setParent( pipe, relative=True )
		pipeConn2.rotate.lock()
		root.subdivisionsAxis >> pipeConnHist2.subdivisionsAxis

		pipeConn1, pipeConnHist1 = pm.polyCylinder( height = .1, radius=1,
							name = '%s_Connector1BGeo%s' % (name, new) )
		pipeConnHist1 = pipeConnHist1.rename( '%s_Connector1BHist%s' % (name, new)  )
		pipeConn1.setPivots( [0, -.05, 0], r=1 )
		pipeConn1.setParent( pipe, relative=True )
		pipeConn1.rotate.lock()
		pipeConn1.visibility = 0
		root.subdivisionsAxis >> pipeConnHist1.subdivisionsAxis


		pipeConn2, pipeConnHist2 = pm.polyCylinder( height = .1, radius=1,
							name = '%s_Connector2BGeo%s' % (name, new) )
		pipeConnHist2 = pipeConnHist2.rename( '%s_Connector2BHist%s' % (name, new)  )
		pipeConn2.setPivots( [0, .05, 0], r=1 )
		pipeConn2.setParent( pipe, relative=True )
		pipeConn2.rotate.lock()
		pipeConn2.visibility = 0
		root.subdivisionsAxis >> pipeConnHist2.subdivisionsAxis


		pipe.setParent( geoGrp )


		#constraints
		pm.pointConstraint( currJnt, pipe )
		aim = pm.aimConstraint( newJnt, pipe )
		aim.offsetZ = -90



		# convert the previous pipe joint into a bendy joint
		if new > 1:
			currElbow = pm.PyNode('%s_Elbow%s' % (name, curr) )
			pipeLoc = pm.spaceLocator( n= '%s_PipeDummy%s' % (name, new) )
			pipeLoc.hide()

			tweak = pm.group(n='%s_ElbowTweak%s' % (name, new))
			tweak.rotateOrder = 2
			#tweak.translate = currElbow.translate.get()
			tweak.setParent( currElbow, r=1 )
			pm.aimConstraint( 	prevJnt, tweak,
							aimVector = [1, 0, 0],
			 				upVector = [0, -1, 0],
							skip=['z', 'x'] )


			# Pipe Joint
			#------------
			pipeJnt, pipeJntHist = pm.polyCylinder( height = 1, radius=1,
								name = '%s_JntGeo%s' % (name, new),
								subdivisionsAxis = 20,
								subdivisionsHeight = 30 )
			pipeJnt.setParent( geoGrp )
			pipeJnt.sy = jointLength
			pipeJnt.visibility = 0
			pipeJntHist = pipeJntHist.rename( '%s_JntGeoHist%s' % (name, new)  )
			pipeJntHist.createUVs = 3   # normalize and preserve aspect ratio

			root.subdivisionsAxis >> pipeJntHist.subdivisionsAxis
			root.subdivisionsJoint >> pipeJntHist.subdivisionsHeight

			# constraints
			pm.parentConstraint( pipeLoc, pipeJnt )
			pipeJnt.translate.lock()
			pipeJnt.rotate.lock()
			#pipeJnt.scale.lock()


			aim = pm.PyNode('%s_Elbow%s_aimConstraint1' % (name, curr))
			aim.setWorldUpType( 2 )
			aim.setWorldUpObject( newJnt )

			bend, bendHandle = pm.nonLinear( '%s_JntGeo%s' % (name, new),
				type='bend' )
			bendHandle = pm.nt.Transform(bendHandle).rename( '%s_BendHandle%s' % (name, new) )
			bendHandle.sx =.5
			bendHandle.hide()

			bend.rename( '%s_Bend%s' % (name, new) )

			pm.parentConstraint( '%s_ElbowTweak%s' % (name, new), bendHandle )

			aim = '%s_ElbowTweak%s_aimConstraint1' % (name, new)
			#aim.worldUpType.set( 1 )
			pm.aimConstraint( aim, e=1, worldUpType='object', worldUpObject=newJnt )

			bendHandle.setParent(rigGrp)

			expr = """
	float $v1[];
	$v1[0] = %(name)s_Elbow%(twoPrev)s.translateX - %(name)s_Elbow%(prev)s.translateX;
	$v1[1] = %(name)s_Elbow%(twoPrev)s.translateY - %(name)s_Elbow%(prev)s.translateY;
	$v1[2] = %(name)s_Elbow%(twoPrev)s.translateZ - %(name)s_Elbow%(prev)s.translateZ;

	float $v2[];
	$v2[0] = %(name)s_Elbow%(curr)s.translateX - %(name)s_Elbow%(prev)s.translateX;
	$v2[1] = %(name)s_Elbow%(curr)s.translateY - %(name)s_Elbow%(prev)s.translateY;
	$v2[2] = %(name)s_Elbow%(curr)s.translateZ - %(name)s_Elbow%(prev)s.translateZ;
	float $mag = sqrt ( $v2[0]*$v2[0] + $v2[1]*$v2[1] + $v2[2]*$v2[2] );
	float $angleData[] = `angleBetween -v1 $v1[0] $v1[1] $v1[2] -v2 $v2[0] $v2[1] $v2[2] `;
	float $angle = $angleData[3];

	if ( !equivalentTol($angle,180.0, 0.1) )
	{
	float $jointDeg = 180 - $angle;
	float $jointRad = -1 * deg_to_rad( $jointDeg );
	%(name)s_Bend%(curr)s.curvature = $jointRad/2;

	%(name)s_ElbowTweak%(curr)s.rotateZ = $jointDeg/2;
	%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s = %(name)s_Jnt%(prev)s.pipeLength;
	float $pipeLength = %(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s;

	float $centerAngleRad = deg_to_rad(90 -$angle/2);
	float $delta = 0;
	float $pipeLengthRatio = 1;

	if ($centerAngleRad > 0.0) {
		float $radius = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s/ $centerAngleRad;
		$delta = $radius - ($radius * cos( $centerAngleRad ));
		$pipeLengthRatio = .5 * $pipeLength / ( $radius * sin( $centerAngleRad ) );
		$pipeLength *= $pipeLengthRatio;
	}
	%(name)s_PipeDummy%(curr)s.translateX = -1*$delta;

	%(name)s_BendHandle%(curr)s.scaleX = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s;
	%(name)s_BendHandle%(curr)s.scaleY = %(name)s_BendHandle%(curr)s.scaleX;
	%(name)s_BendHandle%(curr)s.scaleZ = %(name)s_BendHandle%(curr)s.scaleX;

	%(name)s_JntGeo%(curr)s.scaleY = $pipeLength * (1.0+%(name)s_Jnt%(curr)s.pipeLeadIn);
	%(name)s_JntGeo%(curr)s.scaleX = %(name)s_Jnt0.globalPipeRadius + %(name)s_Jnt0.globalJointRadius;
	%(name)s_JntGeo%(curr)s.scaleZ = %(name)s_JntGeo%(curr)s.scaleX;
	%(name)s_JntGeo%(curr)s.visibility = 1;
	%(name)s_Connector1BGeo%(curr)s.visibility=1;
	%(name)s_Connector2BGeo%(curr)s.visibility=1;
	}
	else
	{
	%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s = 0;
	%(name)s_JntGeo%(curr)s.scaleY = 0;
	%(name)s_JntGeo%(curr)s.visibility = 0;
	%(name)s_Connector1BGeo%(curr)s.visibility=0;
	%(name)s_Connector2BGeo%(curr)s.visibility=0;
	}
	%(name)s_Connector1AGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * (1/%(name)s_Geo%(curr)s.scaleY);
	%(name)s_Connector2AGeo%(curr)s.scaleY = %(name)s_Connector1AGeo%(curr)s.scaleY;
	%(name)s_Connector1AGeo%(curr)s.translateY = -.5 + %(name)s_Connector1AHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset;
	%(name)s_Connector2AGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1AHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset;
	%(name)s_Connector1AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector1AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;

	%(name)s_Connector1BGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * (1/%(name)s_Geo%(curr)s.scaleY);
	%(name)s_Connector2BGeo%(curr)s.scaleY = %(name)s_Connector1BGeo%(curr)s.scaleY;
	%(name)s_Connector1BGeo%(curr)s.translateY = -.5 + %(name)s_Connector1BHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset - .1*%(name)s_Connector1BGeo%(curr)s.scaleY;
	%(name)s_Connector2BGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1BHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset + .1*%(name)s_Connector1BGeo%(curr)s.scaleY;
	%(name)s_Connector1BGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector1BGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2BGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2BGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;

	%(name)s_Geo%(curr)s.scaleY = $mag - .5*%(name)s_Jnt%(curr)s.pipeLengthInBtwn0 - .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s;
	normalize($v2);
	%(name)s_Geo%(curr)s_pointConstraint1.offsetX = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[0];
	%(name)s_Geo%(curr)s_pointConstraint1.offsetY = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[1];
	%(name)s_Geo%(curr)s_pointConstraint1.offsetZ = .5*%(name)s_Jnt%(prev)s.pipeLengthInBtwn%(branch)s * $v2[2];
	""" % { 	'twoPrev' : prev,
				'prev' : 	curr,
				'curr'	: 	new,
				'new'	:	new+1,
				'name': 	name,
				'branch':	branchNum

			}
			#print expr
			print 'editing %s_PipeExpr%s' % (name, new)
			#expression( '%s_PipeExpr%s' % (name, curr), e=1, s=expr, ae=1  )
			pm.expression( s=expr, ae=1, n = '%s_PipeExpr%s' % (name, new)  )


		# special case for first joint
		else:
			expr = """
	float $x = %(newJnt)s.tx;
	float $y = %(newJnt)s.ty;
	float $z = %(newJnt)s.tz;
	float $mag = sqrt ( $x*$x + $y*$y + $z*$z );
	%(name)s_Geo%(curr)s.sy = $mag - .5*%(newJnt)s.pipeLengthInBtwn0;

	%(name)s_Connector1AGeo%(curr)s.scaleY = %(name)s_Jnt0.globalConnectorThickness * 1/%(name)s_Geo%(curr)s.scaleY;
	%(name)s_Connector2AGeo%(curr)s.scaleY = %(name)s_Connector1AGeo%(curr)s.scaleY;
	%(name)s_Connector1AGeo%(curr)s.translateY = -.5 + %(name)s_Connector1AHist%(curr)s.height/2 + .1*%(name)s_Jnt0.globalConnectorOffset;
	%(name)s_Connector2AGeo%(curr)s.translateY = 0.5 - %(name)s_Connector1AHist%(curr)s.height/2 - .1*%(name)s_Jnt0.globalConnectorOffset;
	%(name)s_Connector1AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector1AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2AGeo%(curr)s.scaleX = 1 + %(name)s_Jnt0.globalConnectorRadius;
	%(name)s_Connector2AGeo%(curr)s.scaleZ = 1 + %(name)s_Jnt0.globalConnectorRadius;
		""" % { 'newJnt': newJnt,
				'curr'	: 	new,
				'name': 	name
			}
			print 'creating %s_PipeExpr1' % (name)
			pm.expression( s=expr, ae=1, n = '%s_PipeExpr1' % (name))

		'''
		expr = """
	%(pipeJnt)s.scaleX = %(root)s.globalPipeRadius + %(root)s.globalJointRadius;
	%(pipeJnt)s.scaleZ = %(pipeJnt)s.scaleX;
	""" % {	'pipeJnt': pipeJnt,
			'root' : '%s_Jnt0' % (name) }

		print 'creating %s_PipeExpr%s' % (name, new)
		expression( s=expr, ae=1, n = '%s_PipeExpr%s' % (name, new))
		'''

		pipe.translate.lock()
		pipe.rotate.lock()
		#pipe.scale.lock()
		newJnts.append( newJnt )
	pm.select(newJnts)
예제 #18
0
        s.callback = None
        s.ids = ids = []
        kwargs["e"] = ("PostSceneRead", s._changed)
        ids.append(pmc.scriptJob(**kwargs))
        kwargs["e"] = ("NewSceneOpened", s._changed)
        ids.append(pmc.scriptJob(**kwargs))

    def _changed(s):
        """ Scene changed. Update everyone """
        with _print_exc():
            callback = s.callback
            scene = pmc.system.sceneName() or ""
            if callback: callback(scene)

    def kill(s): [pmc.scriptJob(kill=id_) for id_ in s.ids]


if __name__ == '__main__':
    #Test!
    def changed_selection(sel):
        print "Selection changed to:", sel
    def changed_tool(tool):
        print "Tool changed to:", tool
    def changed_scene(name):
        print "Scene changed to:", name
    pmc.system.newFile(force=True)
    xform, shape = pmc.polyCylinder() # Create a cylinder
    Selection(kws=True, type="transform").callback = changed_selection
    Tool(kws=True).callback = changed_tool
    Scene(ro=True).callback = changed_scene
예제 #19
0
def lcRetopoBasicUI(dockable=False, asChildLayout=False, *args, **kwargs):
    """ """
    global lct_cfg
    global prefix

    ci = 0  # color index iterator
    windowName = 'lcRetopoBasic'
    shelfCommand = 'import lct.src.{0}.{0} as {1}\nreload({1})\n{1}.{0}UI()'.format(
        windowName, prefix)
    commandString = 'import lct.src.{0}.{0} as {1}\nreload({1})\n{1}.{0}UI(asChildLayout=True)'.format(
        windowName, prefix)
    icon = os.path.join(basePath, 'lcRetopoBasic.png')
    winWidth = 205
    winHeight = height

    if pm.window(windowName, ex=True):
        pm.deleteUI(windowName)

    if not asChildLayout:
        lcUI.UI.lcToolbox_child_popout(prefix + '_columnLayout_main',
                                       windowName, height, commandString,
                                       iconPath, lct_cfg)
        mainWindow = lcUI.lcWindow(prefix=prefix,
                                   windowName=windowName,
                                   width=winWidth,
                                   height=winHeight,
                                   icon=icon,
                                   shelfCommand=shelfCommand,
                                   annotation=annotation,
                                   dockable=dockable,
                                   menuBar=True)
        mainWindow.create()

    pm.columnLayout(prefix + '_columnLayout_main')

    # SETUP
    pm.button(l='Setup for Retopo',
              bgc=colorWheel.getColorRGB(ci),
              w=200,
              h=25,
              annotation='Setup a high res mesh for retopology',
              command=lambda *args: rtb_setup_live_mesh(highresListDropdown))
    ci += 1

    # List
    pm.rowColumnLayout(nc=3, cw=([1, 25], [2, 150], [3, 25]))
    pm.symbolButton(
        h=25,
        image=os.path.join(iconPath, 'reloadMeshList.png'),
        annotation='Reload the list of high res meshes',
        command=lambda *args: rtb_highres_list_populate(highresListDropdown))
    highresListDropdown = pm.optionMenu(
        prefix + '_optionMenu_highres_list',
        w=150,
        h=23,
        bgc=[0.5, 0.5, 0.5],
        annotation='List of high res meshes in the scene')
    highresListDropdown.changeCommand(
        lambda *args: rtb_choose_active(highresListDropdown))
    remove_mesh_button = pm.symbolButton(
        h=25,
        image=os.path.join(iconPath, 'removeMeshFromList.png'),
        annotation=
        'Remove current high res mesh from the list and return it to a normal state',
        command=lambda *args: rtb_remove(highresListDropdown))
    popup_remove_mesh = pm.popupMenu(parent=remove_mesh_button)
    pm.menuItem(l='Remove all live meshes',
                parent=popup_remove_mesh,
                command=lambda *args: rtb_remove_all(highresListDropdown))
    pm.setParent(prefix + '_columnLayout_main')

    # Scale
    pm.rowColumnLayout(nc=4, cw=([1, 50], [2, 100], [3, 25], [4, 25]))
    pm.picture(prefix + '_picture_layer_mesh',
               image=os.path.join(iconPath, 'meshLayering.png'),
               annotation='Drag slider to change mesh layering')
    pm.floatSlider(
        prefix + '_floatSlider_layer_mesh',
        h=25,
        step=0.01,
        min=0,
        max=1,
        v=lct_cfg.get('lcRetopoBasicLayering'),
        dragCommand=lambda *args: rtb_scale_layer_mesh(highresListDropdown))
    button_xray = pm.symbolButton(
        prefix + '_symbolButton_xray',
        h=25,
        image=os.path.join(iconPath, 'toggleXray.png'),
        bgc=[0.27, 0.27, 0.27],
        annotation='Toggle Mesh X-Ray',
        command=lambda *args: rtb_toggle_xray(highresListDropdown, 'active'))
    popup_xray = pm.popupMenu(parent=button_xray)
    pm.menuItem(l='xRay on/off all',
                parent=popup_xray,
                command=lambda *args: rtb_toggle_xray(highresListDropdown))

    button_hide = pm.symbolButton(
        prefix + '_symbolButton_hide',
        h=25,
        image=os.path.join(iconPath, 'hideMesh.png'),
        bgc=[0.27, 0.27, 0.27],
        annotation='Hide/Show Current High-Res',
        command=lambda *args: rtb_toggle_hide(highresListDropdown, 'active'))
    popup_hide = pm.popupMenu(parent=button_hide)
    pm.menuItem(
        l='Hide/Show all',
        parent=popup_hide,
        command=lambda *args: rtb_toggle_hide(highresListDropdown, 'all'))
    pm.menuItem(
        l='Hide/Show others',
        parent=popup_hide,
        command=lambda *args: rtb_toggle_hide(highresListDropdown, 'others'))
    pm.setParent(prefix + '_columnLayout_main')

    # Shader
    pm.rowColumnLayout(nc=3, cw=([1, 50], [2, 100], [3, 50]))
    pm.picture(image=os.path.join(iconPath, 'shaderOpacity.png'),
               enable=False,
               annotation='Drag slider to change shader transparency')
    pm.floatSlider(prefix + '_floatSlider_topo_trans',
                   h=25,
                   step=0.1,
                   min=0,
                   max=1,
                   v=lct_cfg.get('lcRetopoBasicShader'),
                   dragCommand=lambda *args: rtb_update_topo_transparency())
    pm.symbolButton(
        h=25,
        image=os.path.join(iconPath, 'assignShader.png'),
        bgc=[0.27, 0.27, 0.27],
        annotation=
        'Create and/or assign a semi-transparent shader to selected low res mesh',
        command=lambda *args: rtb_create_retopo_shader())
    pm.setParent(prefix + '_columnLayout_main')
    pm.separator(style='in', h=5)

    # Relax and Shrinkwrap
    pm.rowColumnLayout(nc=2)
    pm.button(
        l='Relax',
        bgc=colorWheel.getColorRGB(ci),
        w=100,
        h=25,
        annotation='Relax selected verts and shrink-wrap them to the live mesh',
        command=lambda *args: rtb_vert_ops(highresListDropdown,
                                           operation='relax'))
    ci += 1
    pm.button(l='Shrink-Wrap',
              bgc=colorWheel.getColorRGB(ci),
              w=100,
              h=25,
              annotation='Shrink-wrap selected verts to the live mesh',
              command=lambda *args: rtb_vert_ops(highresListDropdown,
                                                 operation='shrink'))
    ci += 1
    pm.setParent(prefix + '_columnLayout_main')

    # PROG Bar
    pm.progressBar(prefix + '_progress_control',
                   en=False,
                   w=202,
                   isInterruptable=True)
    pm.separator(style='in', h=5)

    # Tool List
    pm.gridLayout(nrc=[1, 5], cwh=[40, 40])
    ##1
    pm.symbolButton(prefix + '_symbolButton_select_mode',
                    image='selectByComponent.png',
                    c=lambda *args: rtb_toggle_select_mode(),
                    annotation='Toggle Object/Component Modes')
    ##2
    create_mesh = pm.symbolButton(
        image='polyCylinder.png',
        c=lambda *args: pm.polyCylinder(
            r=1, h=2, sx=8, sy=1, sz=1, ax=(0, 1, 0), rcp=0, cuv=3, ch=1),
        annotation='Create Poly Cylinder')
    popup_create_mesh = pm.popupMenu(parent=create_mesh)
    pm.menuItem(l='polyPlane',
                parent=popup_create_mesh,
                command=lambda *args: pm.polyPlane(
                    w=2, h=2, sx=1, sy=1, ax=(0, 1, 0), cuv=2, ch=1))
    pm.menuItem(l='polyCube',
                parent=popup_create_mesh,
                command=lambda *args: pm.polyCube(
                    w=2, h=2, d=2, sx=1, sy=1, ax=(0, 1, 0), cuv=2, ch=1))
    ##3
    pm.symbolButton(image='polyUnite.png',
                    command=lambda *args: lcGeometry.Geometry.merge_and_weld(),
                    annotation='Combine and Weld')
    ##4
    button_zeroX = pm.symbolButton(image=os.path.join(iconPath, 'zeroX.png'),
                                   command=lambda *args: rtb_zero('x'),
                                   annotation='Zero to world axis')
    popup_zeroX = pm.popupMenu(parent=button_zeroX)
    pm.menuItem(l='Zero X',
                parent=popup_zeroX,
                command=lambda *args: rtb_zero('x'))
    pm.menuItem(l='Zero Y',
                parent=popup_zeroX,
                command=lambda *args: rtb_zero('y'))
    pm.menuItem(l='Zero Z',
                parent=popup_zeroX,
                command=lambda *args: rtb_zero('z'))
    ##5
    pm.symbolButton(image='modelToolkit.png',
                    c=lambda *args: pm.mel.eval('ToggleModelingToolkit'),
                    annotation='Modeling Toolkit')

    #
    if not asChildLayout:
        mainWindow.show()
        pm.window(mainWindow.mainWindow, edit=True, h=winHeight, w=winWidth)
    else:
        pm.setParent('..')
        pm.setParent('..')

    # edit menus
    optionsMenu, helpMenu = lcUI.UI.lcToolbox_child_menu_edit(
        asChildLayout, windowName)

    pm.menuItem(parent=optionsMenu, divider=True, dividerLabel=windowName)
    pm.menuItem(parent=optionsMenu,
                l='Remove all live meshes',
                command=lambda *args: rtb_remove_all(highresListDropdown))

    # populate drowpdowns
    rtb_highres_list_populate(highresListDropdown)

    # restore interface selections
    highresListDropdown.setSelect(lct_cfg.get('lcRetopoBasicListItem'))
    rtb_choose_active(highresListDropdown)

    # vertex animation cache in viewport 2.0 must be disabled or the mesh will not update properly
    if pm.objExists('hardwareRenderingGlobals'):
        pm.PyNode('hardwareRenderingGlobals').vertexAnimationCache.set(0)
    rtb_init_select_mode()
    if not pm.scriptJob(ex=lct_cfg.get('lcRetopoBasicScriptJob')
                        ) or lct_cfg.get('lcRetopoBasicScriptJob') == 0:
        jobNum = pm.scriptJob(
            e=["SelectModeChanged", lambda *args: rtb_init_select_mode()],
            protected=True)
        lct_cfg.set('lcRetopoBasicScriptJob', jobNum)
예제 #20
0
                    s.canvas.paint(s.cache_all) # Clear canvas
                    s.canvas.paint(canvas, GREEN)
                    pmc.refresh() # Update display
        except KeyError:
            print "Joint missing from cache."

    def selection_changed(s, sel):
        """ Selection has been changed """
        if s.controlling_rig: # We were controlling the rig
            s.controlling_rig = False
            s.deactivate_rig()

        if s.making_selection: # We are in the process of making a selection
            s.making_selection = False # Reset
            s.controlling_rig = True # We are now controlling the rig

    def make_selection(s, joint):
        """ select control object """
        pmc.select(joint, r=True) # TODO: make this more sophisticated
        s.making_selection = True # We are ready for this change
        s.picker.unset() # Return to previous tool

if __name__ == '__main__':
    # Testing
    pmc.system.newFile(force=True)
    xform, shape = pmc.polyCylinder(sy=5) # Create a cylinder and joints
    jnt1, jnt2, jnt3 = pmc.joint(p=(0,-1,0)), pmc.joint(p=(0,0,0)), pmc.joint(p=(0,1,0))
    sk = pmc.skinCluster(jnt1, xform, mi=1) # Bind them to the cylinder
    Control([xform])
    pmc.select(clear=True)