def addSurfaceConstraintToBnd(bnd, surface): ''' ''' secDrv = bnd.getParent() matrix = secDrv.getMatrix(worldSpace=True) # create additional nulls gc = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_gc')) gc_offset = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_gc_offset')) acs = pm.group(em=True, n=bnd.nodeName().replace('_bnd', '_acs')) # point constraint first to get precise position to secDrv pm.pointConstraint(secDrv, gc) # geometry constraint to surface pm.geometryConstraint(surface, gc) # normal constraint, using secDrv-Y as up pm.normalConstraint(surface, gc, aim=(0,0,1), u=(0,1,0), wuo=secDrv, wut='objectrotation', wu=(0,1,0)) # ensure that gc_offset stores offset to secDrv gc_offset.setMatrix(matrix, worldSpace=True) acs.setMatrix(matrix, worldSpace=True) # hierarchy secDrv | gc | gc_offset | acs | bnd
def contextPress(self): button = cmds.draggerContext(_dragOnMeshContext, query=True, button=True) # left : 1, middle: 2 if button == 1: self.mainGrp = pm.group(em=True) pm.parent(self.mainGrp, self.growSel) # create trans self.currentTrans = list() self.consGrp = list() for i in range(0, self.copyNum): currentTrans = pm.duplicate(self.initTrans, rr=1)[0] # type: str self.currentTrans.append(currentTrans) consGrp = pm.group(em=1, name='dragOnMesh#') pm.parent(consGrp, self.mainGrp) pm.parent(currentTrans, consGrp) consGrp.scale.set(self.scaList[i] * self.secondSca, self.scaList[i] * self.secondSca, self.scaList[i] * self.secondSca) currentTrans.rotate.set(0, self.rotateList[i] + self.secondRotate, 0) self.consGrp.append(consGrp) pm.geometryConstraint(self.growSel, consGrp, weight=1) pm.normalConstraint(self.growSel, consGrp, weight=1, aimVector=(0, 1, 0), upVector=(0, 0, 1), worldUpType="scene") vpX, vpY, _ = cmds.draggerContext(self.context, q=True, anchorPoint=True) sourcePoint, direction = getIntersect(vpX, vpY) hitPoint = getPoints(self.growSel, sourcePoint, direction) for consGrp in self.consGrp: if hitPoint: consGrp.translate.set(hitPoint) else: consGrp.translate.set(sourcePoint) if hitPoint: self.dragInitPos = vpX, vpY, _ updateView() elif button == 2: pressPosition = cmds.draggerContext(self.context, query=True, anchorPoint=True) self.mouseX = pressPosition[0] self.currentTransRotXYZ = list() for each in self.currentTrans: self.currentTransRotXYZ.append(each.rotate.get())
def addRigJnt(surf, n, names, rotOrder): """Make geoConstrained rig joint, follicle and ClosestPointOnSurface. User moves joint around and follicle follows, to preserve params. At rig time, connection is removed and joint is parented under foll""" # need the transform if isinstance(surf, pmc.nt.NurbsSurface): surf = surf.getTransform() elif not hasattr(surf, "layeredTexture"): pmc.warning("addRigJnt input requires a nurbs surface") return rcu.displayTextures() # pmc.joint freaks out if selection is not perfect. # just clear it pmc.select(clear=True) grp = surf.getParent() # make radius dependent on size of the surface - 1/2 its square "side length" jnt = pmc.joint(n=n.format(type=names["joint"]), radius=surf.area()**.5 / 2) jnt.setParent(grp) pmc.geometryConstraint(surf, jnt) cpos = pmc.nt.ClosestPointOnSurface(n=n.format(type="CPOS")) # cpos uses .ws, posi uses .local # before rigging, may have wierd results if xformed # but rigging inputs worldspace position to CPOS and it works out surf.ws.connect(cpos.inputSurface) jnt.translate.connect(cpos.inPosition) # ctrl should only be oriented according to normal, not U and V #ax = mu.getAxisForVector(self.follVec) ctrlGrp, posi = su.fakeFollicle(surf, name=n.format(type="stat{0}"), local=True, axes=rotOrder[0], rotOrder=rotOrder)[0:2] ctrlGrp.setParent(surf.sCtrlsGrp.get()) # follicles are percent based ONLY, the fuckers. # so the surface is normalized 0-1 in both u and v cpos.parameterU.connect(posi.u) cpos.parameterV.connect(posi.v) # so surf can find its jnts later jnt.message.connect(surf.unriggedJnts, nextAvailable=True) setupJntLimits(surf, jnt, posi, n) jnt.addAttr("mirror", at="message") pmc.select(jnt) return jnt
def placeOnObject(src, dest, orient=False, keep=False): """ Moves & Orients Object in XYZ to Closest Point in dest """ geo_const = pm.geometryConstraint(dest, src) if not keep: pm.delete(geo_const) if orient: nrm_const = pm.normalConstraint(dest, src, wu=(0, 1, 0), wut="vector", u=(0, 1, 0), aim=(0, 1, 0)) if not keep: pm.delete(nrm_const)
def shrinkWrap(cls, verts, mesh, progBar='', *args, **kwargs): ''' ''' scaleFactor = 1 loc = pm.spaceLocator() pm.geometryConstraint(mesh, loc) pm.progressBar(progBar, edit=True, isInterruptable=True, maxValue=len(verts), vis=True) if verts: tmpPos = verts[0].getPosition(space='world') if len(tmpPos) == 4: scaleFactor = 1 / tmpPos[3] for vert in verts: if pm.progressBar(progBar, query=True, isCancelled=True): pm.progressBar(progBar, edit=True, vis=False) break else: currentVert = ((vert.split('.')[1]).lstrip('vtx[')).rstrip(']') vertPos = pm.pointPosition(vert, w=True) pm.move(loc, [vertPos[0], vertPos[1], vertPos[2]], ws=True) locPos = pm.pointPosition(loc) pm.move(vert, [locPos[0], locPos[1], locPos[2]], ws=True) pm.progressBar(progBar, edit=True, step=1) pm.progressBar(progBar, edit=True, vis=False) pm.progressBar(progBar, edit=True, endProgress=True) pm.delete(loc) pm.select(vert.split('.')[0], r=True) pm.delete(ch=True)
def shrinkWrap(cls, verts, mesh, progBar='', *args, **kwargs): ''' ''' scaleFactor = 1 loc = pm.spaceLocator() pm.geometryConstraint(mesh, loc) pm.progressBar(progBar, edit=True, isInterruptable=True, maxValue = len(verts), vis=True) if verts: tmpPos = verts[0].getPosition(space='world') if len(tmpPos)==4: scaleFactor = 1/tmpPos[3] for vert in verts: if pm.progressBar(progBar, query=True, isCancelled=True): pm.progressBar(progBar, edit=True, vis=False) break else: currentVert = ((vert.split('.')[1]).lstrip('vtx[')).rstrip(']') vertPos = pm.pointPosition(vert, w=True) pm.move(loc, [vertPos[0], vertPos[1], vertPos[2] ], ws=True) locPos = pm.pointPosition(loc) pm.move(vert, [locPos[0], locPos[1], locPos[2] ], ws=True) pm.progressBar(progBar, edit=True, step=1) pm.progressBar(progBar, edit=True, vis=False) pm.progressBar(progBar, edit=True, endProgress=True) pm.delete(loc) pm.select(vert.split('.')[0], r=True) pm.delete(ch=True)
def snapToGround(self, *args): groundPlaneObject = pm.textFieldButtonGrp( self.widgets['groundplaneTextField'], q=True, tx=True) list = pm.ls(sl=True, tr=True) for x in list: locator = pm.spaceLocator() group = pm.group(locator) pm.delete(pm.parentConstraint(x, group, mo=False)) Xparent = x.getParent() pm.parent(x, locator) pm.transformLimits(locator, tx=[0, 0], etx=[1, 1]) pm.transformLimits(locator, tz=[0, 0], etz=[1, 1]) pm.delete(pm.geometryConstraint(groundPlaneObject, locator, w=1)) pm.parent(x, Xparent) pm.delete(group)
def create_handle(name=Vars.PLUGIN_NAME, camera="", light="", geometry=""): """ Handle creation master method. Params are accepted, no params means creating from selection. :param name : string, Optional. Handle name. :param camera : string, Optional. Camera name. :param light : string, Optional. Light name. :param geometry : string, Optional. Geometry to constraint to. :return Parameter dictionary {handle, node, camera, light, geo} """ # Get from selection ? if not any((camera, light, geometry)): camera, light, geometry = get_data_from_selection() # Store snap position before creating everything otherwise component_pos = get_components_pos() # Snap to component, or to cam if there's geo, otherwise at root if component_pos != (0, 0, 0): snap_pos = component_pos elif camera and geometry: snap_pos = pmc.PyNode(camera).getTranslation(ws=True) else: snap_pos = (0, 0, 0) # Create Sol Handle s_node = pmc.createNode(Vars.PLUGIN_NAME, n='{}Shape#'.format(name)) # Connect root world matrix and set position on component s_trans = s_node.getParent() s_trans.worldMatrix.connect(s_node.selfMatrix) s_trans.setTranslation(snap_pos, ws=True) # Add Parameters s_trans.addAttr("_", at='enum', en='Controls', k=1) s_trans.addAttr('normalReflectionBlend', at='double', min=0, max=1, dv=1, k=1) s_trans.addAttr('distance', at='double', dv=10, k=1) s_trans.addAttr('lightRoll', at='double', dv=0, k=1) s_trans.addAttr('drawMode', at='long', min=0, max=3, dv=2, k=1) s_trans.addAttr('normalLength', at='double', min=0, dv=3, k=1) # Set and connect parameters pmc.setAttr(s_trans.name() + '._', lock=1) s_trans.normalReflectionBlend.connect(s_node.normalReflectionBlend, f=1) s_trans.distance.connect(s_node.distance, f=1) s_trans.lightRoll.connect(s_node.lightRoll, f=1) s_trans.drawMode.connect(s_node.drawMode, f=1) s_trans.normalLength.connect(s_node.normalLength, f=1) # Connect Camera and light c_node = change_handle_camera(s_node, camera) # TODO : disconnected, here, might be useful ? _, l_node, disconnected = change_handle_light(s_node, light) # TODO : if l_node, create parameters from typelight settings... # Constrain to geometry if geometry: g_node = pmc.PyNode(geometry) pmc.geometryConstraint(g_node, s_trans) pmc.normalConstraint(g_node, s_trans, aimVector=(0, 1, 0)) else: g_node = None # Select node and return data pmc.select(s_trans, r=True) return Vars.HANDLE_DATA( handle=s_trans, node=s_node, camera=c_node, light=l_node, geometry=g_node )
def buildSurfaceFollow(joints, groupOrigin, surface=None, controlSpec={}): groupOrigin = dt.Vector(groupOrigin) container = util.parentGroup(joints[0]) container.setParent(lib.getNodes.mainGroup()) mainCtrl = controllerShape.build( util.trimName(joints[0].getParent()) + 'Surface_ctrl', controlSpec['main'], type=controllerShape.ControlType.TRANSLATE) mainCtrl = nodeApi.RigController.convert(mainCtrl) mainCtrl.setParent(container) xform(mainCtrl, ws=True, t=groupOrigin) core.dagObj.lockScale(mainCtrl) core.dagObj.zero(mainCtrl) subControls = [] locs = [] offsets = [] for i, j in enumerate(joints): loc = spaceLocator() locs.append(loc) core.dagObj.matchTo(loc, j) geometryConstraint(surface, loc) objUp, worldObjUp = getUpVectors(j) normalConstraint(surface, loc, wuo=mainCtrl, wut='objectrotation', upVector=objUp, worldUpVector=worldObjUp) offsetCtrl = controllerShape.build( util.trimName(j) + 'Offset_ctrl', controlSpec['offset'], type=controllerShape.ControlType.TRANSLATE) core.dagObj.matchTo(offsetCtrl, loc) offsets.append(offsetCtrl) offsetCtrl.setParent(loc) core.dagObj.zero(offsetCtrl) subCtrl = controllerShape.build( util.trimName(j) + '_ctrl', controlSpec['manual'], type=controllerShape.ControlType.TRANSLATE) subControls.append(subCtrl) core.dagObj.matchTo(subCtrl, loc) subCtrl.setParent(mainCtrl) core.dagObj.zero(subCtrl) pointConstraint(subCtrl, loc) core.dagObj.lockRot(subCtrl) core.dagObj.lockScale(subCtrl) core.dagObj.lockScale(offsetCtrl) loc.setParent(subCtrl) space.add(offsetCtrl, loc, spaceName='surface') mainCtrl.subControl[str(i)] = subCtrl mainCtrl.subControl[str(i) + '_offset'] = offsetCtrl constraints = util.constrainAtoB(joints, offsets) mainCtrl.container = container return mainCtrl, constraints
def copyNum_changed(self, copyNum, rotate, randomRotate, secondRotate, sca, randomSca, secondSca): if not cmds.objExists(self.initTrans): return cmds.setAttr('{}.visibility'.format(self.initTrans), True) pm.delete(self.mainGrp) self.copyNum = copyNum self.rotate = rotate self.randomRotate = randomRotate self.secondRotate = secondRotate self.sca = sca self.randomSca = randomSca self.secondSca = secondSca if randomRotate == 0: self.rotateList = [rotate for i in range(copyNum)] else: rotateMin = rotate - randomRotate rotateMax = rotate + randomRotate getDev = abs(randomRotate) * 2 / copyNum self.rotateList = [ random.randrange(rotateMin, rotateMax + getDev, getDev) for i in range(0, copyNum) ] if randomSca == 0: self.scaList = [sca for i in range(0, copyNum)] else: scaMin = int(sca * 100 * (1 - randomSca)) scaMax = int(sca * 100 * (1 + randomSca)) getDev = int(abs(randomSca) * 200 / copyNum) self.scaList = [ random.randrange(scaMin, scaMax + getDev, getDev) / 100.00 for i in range(0, copyNum) ] self.mainGrp = pm.group(em=True) pm.parent(self.mainGrp, self.growSel) # create trans self.currentTrans = list() self.consGrp = list() for i in range(0, self.copyNum): currentTrans = pm.duplicate(self.initTrans, rr=1)[0] # type: str self.currentTrans.append(currentTrans) consGrp = pm.group(em=1, name='dragOnMesh#') pm.parent(consGrp, self.mainGrp) pm.parent(currentTrans, consGrp) consGrp.scale.set(self.scaList[i] * self.secondSca, self.scaList[i] * self.secondSca, self.scaList[i] * self.secondSca) currentTrans.rotate.set(0, self.rotateList[i] + self.secondRotate, 0) self.consGrp.append(consGrp) pm.geometryConstraint(self.growSel, consGrp, weight=1) pm.normalConstraint(self.growSel, consGrp, weight=1, aimVector=(0, 1, 0), upVector=(0, 0, 1), worldUpType="scene") vpX, vpY, _ = self.dragEndPos sourcePoint, direction = getIntersect(vpX, vpY) hitPoint = getPoints(self.growSel, sourcePoint, direction) if hitPoint: if self.copyNum == 1: self.consGrp[0].translate.set(hitPoint) else: endX, endY, _ = self.dragInitPos numLen = self.copyNum - 1.0 devX = (endX - vpX) / numLen devY = (endY - vpY) / numLen for i in range(self.copyNum): finX, finY = endX - i * devX, endY - i * devY sourcePoint, direction = getIntersect(finX, finY) hitPoint = getPoints(self.growSel, sourcePoint, direction) self.consGrp[i].translate.set(hitPoint) updateView()