def createFollicleOnMesh(targetSurface, name='follicle'): """ Creates named follicle node on a mesh Keywords mesh -- mesh to attach to name -- base name to use ('follicle' default) Returns [follicleNode,follicleTransform] """ if SEARCH.is_shape(targetSurface): l_shapes = [targetSurface] else: l_shapes = mc.listRelatives(targetSurface, s=True, fullPath=True) if not l_shapes: raise ValueError, "Must have shapes to check." _shape = l_shapes[0] log.debug("_shape: {0}".format(_shape)) _type = VALID.get_mayaType(_shape) #objType = search.returnObjectType(mesh) #assert objType in ['mesh','nurbsSurface'],("'%s' isn't a mesh"%mesh) follicleNode = create((name), 'follicle') """ make the closest point node """ #closestPointNode = createNamedNode((targetObj+'_to_'+mesh),'closestPointOnMesh') #controlSurface = mc.listRelatives(_shape,shapes=True)[0] follicleTransform = mc.listRelatives(follicleNode, p=True, fullPath=True)[0] attributes.doConnectAttr( (_shape + '.worldMatrix[0]'), (follicleNode + '.inputWorldMatrix')) #surface to follicle node if _type == 'mesh': attributes.doConnectAttr( (_shape + '.outMesh'), (follicleNode + '.inputMesh')) #surface mesh to follicle input mesh else: attributes.doConnectAttr( (_shape + '.local'), (follicleNode + '.inputSurface')) #surface mesh to follicle input mesh attributes.doConnectAttr((follicleNode + '.outTranslate'), (follicleTransform + '.translate')) attributes.doConnectAttr((follicleNode + '.outRotate'), (follicleTransform + '.rotate')) attributes.doSetLockHideKeyableAttr(follicleTransform) return [follicleNode, follicleTransform]
def add_follicle(mesh, name='follicle'): """ Creates named follicle node on a mesh :parameters: mesh(str): Surface to attach to name(str): base name for the follicle :returns [newNode, newTransform] """ _str_func = "add_follicle" _node = create(name, 'follicle') if SEARCH.is_shape(mesh): _surface = mesh else: _surface = mc.listRelatives(mesh, shapes=True, fullPath=True)[0] _type = VALID.get_mayaType(_surface) _trans = SEARCH.get_transform(_node) attributes.doConnectAttr( (_surface + '.worldMatrix[0]'), (_node + '.inputWorldMatrix')) #surface to follicle node if _type == 'mesh': attributes.doConnectAttr( (_surface + '.outMesh'), (_node + '.inputMesh')) #surface mesh to follicle input mesh else: attributes.doConnectAttr( (_surface + '.local'), (_node + '.inputSurface')) #surface mesh to follicle input mesh attributes.doConnectAttr((_node + '.outTranslate'), (_trans + '.translate')) attributes.doConnectAttr((_node + '.outRotate'), (_trans + '.rotate')) #ATTR.set_message(_node,'follTrans',_trans) #ATTR.set_message(_trans,'follNode',_node) attributes.doSetLockHideKeyableAttr(_trans) return [_node, _trans] """follicleNode = createNamedNode((name),'follicle')
def duplicate_shape(shape): """ mc.duplicate can't duplicate a shape. This provides for it :parameters: shape(str): shape to dupliate :returns [shape,transform] """ try: _str_func = 'duplicate_shape' _type = VALID.get_mayaType(shape) if _type == 'nurbsCurve': _bfr = mc.duplicateCurve(shape) parentObj = mc.listRelatives(shape, p=True, fullPath=True) mc.delete(mc.parentConstraint(parentObj, _bfr[0])) _l_shapes = mc.listRelatives(_bfr[0], s=True, f=True) return [_bfr[0]] + _l_shapes else: log.debug("|{0}| >> mesh shape assumed...".format(_str_func)) _transform = SEARCH.get_transform(shape) _shapes = mc.listRelatives(_transform, s=True, fullPath=True) _idx = _shapes.index(coreNames.get_long(shape)) _bfr = mc.duplicate(shape) _newShapes = mc.listRelatives(_bfr[0], s=True, fullPath=True) _dupShape = _newShapes[_idx] _newShapes.pop(_idx) mc.delete(_newShapes) return [_bfr[0], _dupShape] except Exception, err: pprint.pprint(vars()) if not SEARCH.is_shape(shape): log.error("|{0}| >> Failure >> Not a shape: {1}".format( _str_func, shape)) raise Exception, "|{0}| >> failed! | err: {1}".format(_str_func, err)
def create_closest_point_node(source=None, targetSurface=None, singleReturn=False): """ Create a closest point on surface node and wire it :parameters: source(str/vector) -- source point or object targetSurface -- surface to check transform, nurbsSurface, curve, mesh supported singleReturn - only return single return if we have :returns node(list) """ try: _str_func = 'create_closest_point_node' _transform = False if VALID.vectorArg(source) is not False: _transform = mc.spaceLocator(n='closest_point_source_loc')[0] POS.set(_transform, source) elif mc.objExists(source): if SEARCH.is_transform(source): _transform = source elif VALID.is_component(source): _transform = mc.spaceLocator( n='{0}_loc'.format(NAMES.get_base(source)))[0] POS.set(_transform, POS.get(source)) else: _transform = SEARCH.get_transform(source) if not _transform: raise ValueError, "Must have a transform" if SEARCH.is_shape(targetSurface): l_shapes = [targetSurface] else: l_shapes = mc.listRelatives(targetSurface, s=True, fullPath=True) if not l_shapes: raise ValueError, "Must have shapes to check." _nodes = [] _locs = [] _types = [] _shapes = [] for s in l_shapes: _type = VALID.get_mayaType(s) if _type not in ['mesh', 'nurbsSurface', 'nurbsCurve']: log.error( "|{0}| >> Unsupported target surface type. Skipping: {1} |{2} " .format(_str_func, s, _type)) continue _loc = mc.spaceLocator()[0] _res_loc = mc.rename( _loc, '{0}_to_{1}_result_loc'.format(NAMES.get_base(source), NAMES.get_base(s))) _locs.append(_res_loc) _types.append(_type) _shapes.append(s) if _type == 'mesh': _node = mc.createNode('closestPointOnMesh') _node = mc.rename( _node, "{0}_to_{1}_closePntMeshNode".format( NAMES.get_base(source), NAMES.get_base(s))) ATTR.connect((_transform + '.translate'), (_node + '.inPosition')) ATTR.connect((s + '.worldMesh'), (_node + '.inMesh')) ATTR.connect((s + '.worldMatrix'), (_node + '.inputMatrix')) _pos = ATTR.get(_node, 'position') ATTR.connect((_node + '.position'), (_res_loc + '.translate')) _nodes.append(_node) elif _type == 'nurbsSurface': closestPointNode = mc.createNode('closestPointOnSurface') closestPointNode = mc.rename( closestPointNode, "{0}_to_{1}_closePntSurfNode".format( NAMES.get_base(source), NAMES.get_base(s))) mc.connectAttr((_transform + '.translate'), (closestPointNode + '.inPosition')) #attributes.doSetAttr(closestPointNode,'inPositionX',_point[0]) #attributes.doSetAttr(closestPointNode,'inPositionY',_point[1]) #attributes.doSetAttr(closestPointNode,'inPositionZ',_point[2]) ATTR.connect((s + '.worldSpace'), (closestPointNode + '.inputSurface')) ATTR.connect((closestPointNode + '.position'), (_res_loc + '.translate')) _nodes.append(closestPointNode) elif _type == 'nurbsCurve': _node = mc.createNode('nearestPointOnCurve') _node = mc.rename( _node, "{0}_to_{1}_nearPntCurveNode".format( NAMES.get_base(source), NAMES.get_base(s))) p = [] distances = [] mc.connectAttr((_transform + '.translate'), (_node + '.inPosition')) mc.connectAttr((s + '.worldSpace'), (_node + '.inputCurve')) ATTR.connect((_node + '.position'), (_res_loc + '.translate')) _nodes.append(_node) if not singleReturn: return _locs, _nodes, _shapes, _types _l_distances = [] pos_base = POS.get(_transform) for i, n in enumerate(_nodes): p2 = POS.get(_locs[i]) _l_distances.append(get_distance_between_points(pos_base, p2)) if not _l_distances: raise ValueError, "No distance value found" closest = min(_l_distances) _idx = _l_distances.index(closest) for i, n in enumerate(_nodes): if i != _idx: mc.delete(n, _locs[i]) return _locs[_idx], _nodes[_idx], _shapes[_idx], _types[_idx] except Exception, err: cgmGen.cgmExceptCB(Exception, err)
def get_closest_point(source=None, targetSurface=None, loc=False): """ Get the closest point on a target surface/curve/mesh to a given point or object. Evaluates to all sub shapes to get closest point for multi shape targets. :parameters: source(str/vector) -- source point or object targetSurface -- surface to check transform, nurbsSurface, curve, mesh supported loc -- whether to loc point found :returns position, distance, shape (list) """ _str_func = 'get_closest_point' _point = False if VALID.vectorArg(source) is not False: _point = source elif mc.objExists(source): _point = POS.get(source) if not _point: raise ValueError, "Must have point of reference" _loc = mc.spaceLocator(n='get_closest_point_loc')[0] POS.set(_loc, _point) if SEARCH.is_shape(targetSurface): _shapes = [targetSurface] elif VALID.is_component(targetSurface): _shapes = mc.listRelatives(VALID.get_component(targetSurface)[1], s=True, fullPath=True) else: _shapes = mc.listRelatives(targetSurface, s=True, fullPath=True) if not _shapes: log.error("|{0}| >> No shapes found. Skipping: {1}".format( _str_func, targetSurface)) mc.delete(_loc) return False _l_res_positions = [] _l_res_shapes = [] _l_res_distances = [] for s in _shapes: _type = VALID.get_mayaType(s) if _type not in ['mesh', 'nurbsSurface', 'nurbsCurve']: log.error( "|{0}| >> Unsupported target surface type. Skipping: {1} |{2} | {3}" .format(_str_func, s, _type)) _l_res_positions.append(False) continue if _type == 'mesh': _node = mc.createNode('closestPointOnMesh') ATTR.connect((_loc + '.translate'), (_node + '.inPosition')) ATTR.connect((s + '.worldMesh'), (_node + '.inMesh')) ATTR.connect((s + '.worldMatrix'), (_node + '.inputMatrix')) _pos = ATTR.get(_node, 'position') _tmpLoc = mc.spaceLocator(n='tmp')[0] ATTR.connect((_node + '.position'), (_tmpLoc + '.translate')) _l_res_positions.append(POS.get(_tmpLoc)) mc.delete(_node) mc.delete(_tmpLoc) elif _type == 'nurbsSurface': closestPointNode = mc.createNode('closestPointOnSurface') ATTR.set(closestPointNode, 'inPositionX', _point[0]) ATTR.set(closestPointNode, 'inPositionY', _point[1]) ATTR.set(closestPointNode, 'inPositionZ', _point[2]) ATTR.connect((s + '.worldSpace'), (closestPointNode + '.inputSurface')) _l_res_positions.append(ATTR.get(closestPointNode, 'position')) mc.delete(closestPointNode) elif _type == 'nurbsCurve': _node = mc.createNode('nearestPointOnCurve') p = [] distances = [] mc.connectAttr((_loc + '.translate'), (_node + '.inPosition')) mc.connectAttr((s + '.worldSpace'), (_node + '.inputCurve')) p = [ mc.getAttr(_node + '.positionX'), mc.getAttr(_node + '.positionY'), mc.getAttr(_node + '.positionZ') ] _l_res_positions.append(p) mc.delete(_node) mc.delete(_loc) if not _l_res_positions: raise ValueError, "No positions found" for p in _l_res_positions: if p: _l_res_distances.append(get_distance_between_points(_point, p)) else: _l_res_distances.append('no') closest = min(_l_res_distances) _idx = _l_res_distances.index(closest) _pos = _l_res_positions[_idx] if not _pos: return False #raise ValueError,"Failed to find point" if loc: _loc = mc.spaceLocator(n='get_closest_point_loc')[0] POS.set(_loc, _pos) return _pos, _l_res_distances[_idx], _shapes[_idx]
def get_normalized_uv(mesh, uValue, vValue): """ uv Values from many functions need to be normalized to be correct when using those values for other functions The calculcaion for doing so is size = maxV - minV sum = rawV + minV normalValue = sum / size :parameters: mesh(string) | Surface to normalize to uValue(float) | uValue to normalize vValue(float) | vValue to normalize :returns Dict ------------------------------------------------------------------ 'uv'(double2) | point from which we cast 'uValue'(float) | normalized uValue 'vValue'(float) | normalized vValue :raises: Exception | if reached """ _str_func = 'get_normalized_uv' try: try: #Validation ---------------------------------------------------------------- reload(VALID) _mesh = VALID.objString(mesh, 'nurbsSurface', calledFrom=_str_func) #log.debug("|{0}| >> mesh arg: {1} | validated: {2}".format(_str_func,mesh,_mesh)) if not SEARCH.is_shape(_mesh): shape = mc.listRelatives(_mesh, shapes=True)[0] log.debug( "|{0}| >> Transform provided. using first shape: {1}". format(_str_func, shape)) else: shape = _mesh uMin = ATTR.get(shape, 'mnu') uMax = ATTR.get(shape, 'mxu') vMin = ATTR.get(shape, 'mnv') vMax = ATTR.get(shape, 'mxv') """uMin = mi_shape.mnu uMax = mi_shape.mxu vMin = mi_shape.mnv vMax = mi_shape.mxv""" except Exception, error: raise Exception, "Validation failure | {0}".format(error) try: #Calculation ---------------------------------------------------------------- uSize = uMax - uMin vSize = vMax - vMin uSum = uMin + uValue vSum = vMin + vValue uNormal = uSum / uSize vNormal = vSum / vSize except Exception, error: raise Exception, "Calculation |{0}".format(error)
def get_closest_point_data_from_mesh(mesh=None, targetObj=None, targetPoint=None): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Returns pertinent info of the closest point of a mesh to a target object - position, normal, parameterU,parameterV,closestFaceIndex,closestVertexIndex ARGUMENTS: targetObj(string) mesh(string) RETURNS: closestPointInfo(dict) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ _str_func = 'get_closest_point_data_from_mesh' _point = False if targetObj is not None: _point = POS.get(targetObj) elif targetPoint: _point = targetPoint if not _point: raise ValueError, "Must have point of reference" _loc = mc.spaceLocator()[0] POS.set(_loc, _point) _shape = False if SEARCH.is_shape(mesh): if VALID.get_mayaType(mesh) == 'mesh': _shape = mesh else: raise ValueError, "Must be a mesh shape" else: _shape = SEARCH.get_nonintermediateShape(mesh) _shapes = mc.listRelatives(mesh, s=True, fullPath=True) """_meshes = [] for s in _shapes: if VALID.get_mayaType(s) == 'mesh': _meshes.append(s) if len(_meshes) > 1: _shape = _meshes[0]""" if not _shape: log.error("|{0}| >> Shapes...".format(_str_func)) for s in _shapes: print "{0} : {1}".format(s, VALID.get_mayaType(s)) raise ValueError, "Must have a mesh shape by now" """ make the closest point node """ _node = mc.createNode('closestPointOnMesh') """ to account for target objects in heirarchies """ ATTR.connect((targetObj + '.translate'), (_node + '.inPosition')) ATTR.connect((_shape + '.worldMesh'), (_node + '.inMesh')) ATTR.connect((_shape + '.matrix'), (_node + '.inputMatrix')) _u = mc.getAttr(_node + '.parameterU') _v = mc.getAttr(_node + '.parameterV') #_norm = get_normalized_uv(_shape, _u,_v) _res = {} _res['shape'] = _shape _res['position'] = ATTR.get(_node, 'position') _res['normal'] = ATTR.get(_node, 'normal') _res['parameterU'] = _u _res['parameterV'] = _v #_res['normalizedU'] = _norm[0] #_res['normalizedV'] = _norm[1] _res['closestFaceIndex'] = mc.getAttr(_node + '.closestFaceIndex') _res['closestVertexIndex'] = mc.getAttr(_node + '.closestVertexIndex') mc.delete([_node, _loc]) return _res
def shapeParent_in_place(obj, shapeSource, keepSource=True, replaceShapes=False, snapFirst=False): """ Shape parent a curve in place to a obj transform :parameters: obj(str): Object to modify shapeSource(str): Curve to shape parent keepSource(bool): Keep the curve shapeParented as well replaceShapes(bool): Whether to remove the obj's original shapes or not snapFirst(bool): whether to snap source to obj before transfer :returns success(bool) """ _str_func = 'shapeParent_in_place' l_shapes = VALID.listArg(shapeSource) obj = VALID.mNodeString(obj) log.debug( "|{0}| >> obj: {1} | shapeSource: {2} | keepSource: {3} | replaceShapes: {4}" .format(_str_func, obj, shapeSource, keepSource, replaceShapes)) if replaceShapes: _l_objShapes = mc.listRelatives(obj, s=True, fullPath=True) if _l_objShapes: log.debug("|{0}| >> Removing obj shapes...| {1}".format( _str_func, _l_objShapes)) mc.delete(_l_objShapes) mc.select(cl=True) #mc.refresh() for c in l_shapes: try: _shapeCheck = SEARCH.is_shape(c) if not _shapeCheck and not mc.listRelatives( c, f=True, shapes=True, fullPath=True): raise ValueError, "Has no shapes" if coreNames.get_long(obj) == coreNames.get_long(c): raise ValueError, "Cannot parentShape self" if VALID.get_mayaType(c) == 'nurbsCurve': mc.ls(['%s.ep[*]' % (c)], flatten=True) #This is for a really weird bug in 2016 where offset curve shapes don't work right unless they're components are queried. if _shapeCheck: _dup_curve = duplicate_shape(c)[0] log.debug("|{0}| >> shape duplicate".format(_str_func)) if snapFirst: SNAP.go(_dup_curve, obj) else: log.debug("|{0}| >> regular duplicate".format(_str_func)) _dup_curve = mc.duplicate(c)[0] for child in TRANS.children_get(_dup_curve, True): mc.delete(child) if snapFirst: SNAP.go(_dup_curve, obj) _l_parents = SEARCH.get_all_parents(obj) ATTR.set_standardFlags(_dup_curve, lock=False, visible=True, keyable=True) _dup_curve = parent_set(_dup_curve, False) copy_pivot(_dup_curve, obj) #piv_pos = mc.xform(obj, q=True, ws=True, rp = True) #mc.xform(_dup_curve,ws=True, rp = piv_pos) pos = mc.xform(obj, q=True, os=True, rp=True) curveScale = mc.xform(_dup_curve, q=True, s=True, r=True) objScale = mc.xform(obj, q=True, s=True, r=True) #account for freezing #mc.makeIdentity(_dup_curve,apply=True,translate =True, rotate = True, scale=False) # make our zero out group #group = rigging.groupMeObject(obj,False) group = create_at(obj, 'null') _dup_curve = mc.parent(_dup_curve, group)[0] # zero out the group mc.xform(group, ws=True, t=pos) #mc.xform(group,roo = 'xyz', p=True) mc.xform(group, ra=[0, 0, 0], p=False) mc.xform(group, ro=[0, 0, 0], p=False) mc.makeIdentity(_dup_curve, apply=True, translate=True, rotate=True, scale=False) #main scale fix baseMultiplier = [0, 0, 0] baseMultiplier[0] = (curveScale[0] / objScale[0]) baseMultiplier[1] = (curveScale[1] / objScale[1]) baseMultiplier[2] = (curveScale[2] / objScale[2]) mc.setAttr(_dup_curve + '.sx', baseMultiplier[0]) mc.setAttr(_dup_curve + '.sy', baseMultiplier[1]) mc.setAttr(_dup_curve + '.sz', baseMultiplier[2]) #parent scale fix if _l_parents: _l_parents.reverse() multiplier = [ baseMultiplier[0], baseMultiplier[1], baseMultiplier[2] ] for p in _l_parents: scaleBuffer = mc.xform(p, q=True, s=True, r=True) multiplier[0] = ((multiplier[0] / scaleBuffer[0])) multiplier[1] = ((multiplier[1] / scaleBuffer[1])) multiplier[2] = ((multiplier[2] / scaleBuffer[2])) mc.setAttr(_dup_curve + '.sx', multiplier[0]) mc.setAttr(_dup_curve + '.sy', multiplier[1]) mc.setAttr(_dup_curve + '.sz', multiplier[2]) _dup_curve = parent_set(_dup_curve, False) mc.delete(group) #freeze for parent shaping mc.makeIdentity(_dup_curve, apply=True, translate=True, rotate=True, scale=True) shape = mc.listRelatives(_dup_curve, f=True, shapes=True, fullPath=True) mc.parent(shape, obj, add=True, shape=True) mc.delete(_dup_curve) if not keepSource: mc.delete(c) except Exception, err: cgmGEN.cgmExceptCB(Exception, err, msg=vars())