def findFurthestPointInRangeFromObject(mesh,obj,axis = 'z+', pierceDepth = 4, vector = False, maxDistance = 1000): """ Find the furthest point in range on an axis. Useful for getting to the outershell of a mesh """ try: _str_funcName = 'findFurthestPointInRangeFromObject' log.debug(">>> %s >> "%_str_funcName + "="*75) if len(mc.ls(mesh))>1: raise StandardError,"findFurthestPointInRangeFromObject>>> More than one mesh named: %s"%mesh #>>>First cast to get our initial range d_firstcast = findMeshIntersectionFromObjectAxis(mesh, obj, axis = axis, vector=vector, maxDistance = maxDistance) if not d_firstcast.get('hit'): raise StandardError,"findFurthestPointInRangeFromObject>>> first cast failed to hit" baseDistance = distance.returnDistanceBetweenPoints(distance.returnWorldSpacePosition(obj),d_firstcast['hit']) log.debug("findFurthestPointInRangeFromObject>>>baseDistance: %s"%baseDistance) castDistance = baseDistance + pierceDepth log.debug("findFurthestPointInRangeFromObject>>>castDistance: %s"%castDistance) l_positions = [] d_castReturn = findMeshIntersectionFromObjectAxis(mesh, obj, axis=axis, maxDistance = castDistance, singleReturn=False) or {} log.debug("2nd castReturn: %s"%d_castReturn) if d_castReturn.get('hits'): closestPoint = distance.returnFurthestPoint(distance.returnWorldSpacePosition(obj),d_castReturn.get('hits')) or False d_castReturn['hit'] = closestPoint return d_castReturn except StandardError,error: for kw in [mesh,obj,axis,pierceDepth,vector,maxDistance]: log.debug("%s"%kw) raise StandardError, "%s >> error: %s"%(_str_funcName,error)
def findMeshIntersectionFromObjectAxis(mesh, obj, axis = 'z+', vector = False, maxDistance = 1000, singleReturn = True): """ Find mesh intersections for an object's axis """ try: _str_funcName = 'findMeshIntersectionFromObjectAxis' log.debug(">>> %s >> "%_str_funcName + "="*75) if len(mc.ls(mesh))>1: raise StandardError,"findMeshIntersectionFromObjectAxis>>> More than one mesh named: %s"%mesh if not vector or type(vector) not in [list,tuple]: d_matrixVectorIndices = {'x':[0,1,2], 'y': [4,5,6], 'z' : [8,9,10]} matrix = mc.xform(obj, q=True, matrix=True, worldSpace=True) #>>> Figure out our vector if axis not in dictionary.stringToVectorDict.keys(): log.error("findMeshIntersectionFromObjectAxis axis arg not valid: '%s'"%axis) return False if list(axis)[0] not in d_matrixVectorIndices.keys(): log.error("findMeshIntersectionFromObjectAxis axis arg not in d_matrixVectorIndices: '%s'"%axis) return False vector = [matrix[i] for i in d_matrixVectorIndices.get(list(axis)[0])] if list(axis)[1] == '-': for i,v in enumerate(vector): vector[i]=-v if singleReturn: return findMeshIntersection(mesh, distance.returnWorldSpacePosition(obj), rayDir=vector, maxDistance = maxDistance) else: return findMeshIntersections(mesh, distance.returnWorldSpacePosition(obj), rayDir=vector, maxDistance = maxDistance) except StandardError,error: log.error(">>> %s >> mesh: %s | obj: %s | axis %s | vector: %s | error: %s"%(_str_funcName,mesh,obj,axis,vector,error)) return None
def gatherInfluenceData(self, dagPath, components): """ Get the influence data """ weights = self.__getCurrentWeights(dagPath, components) influencePaths = OM.MDagPathArray() numInfluences = self.fn.influenceObjects(influencePaths) numComponentsPerInfluence = weights.length() / numInfluences self.progressBar_start(stepMaxValue=influencePaths.length(), statusMessage='Calculating....', interruptableState=False) _d_influenceData = {} for i in range(influencePaths.length()): _k = str(i) influenceName = influencePaths[i].partialPathName() influenceWithoutNamespace = names.getBaseName(influenceName) _d_influenceData[_k] = {'name': influenceWithoutNamespace, 'position':distance.returnWorldSpacePosition(influenceName)} # store weights by influence & not by namespace so it can be imported with different namespaces. self.progressBar_iter(status = 'Getting {0}...data'.format(influenceName)) self._d_data['weights'][_k] = \ [weights[jj*numInfluences+i] for jj in range(numComponentsPerInfluence)] self._d_data['influences']['data'] = _d_influenceData self.progressBar_end()
def finalize(self): """ Press action. Clears buffers. """ #Clean our lists... self.l_created = lists.returnListNoDuplicates(self.l_created) self.l_return = lists.returnListNoDuplicates(self.l_return) if self._createMode in ['curve','jointChain','group','follicle'] and self.l_return: if self._createMode == 'group': bufferList = [] for i,o in enumerate(self.l_created): buffer = rigging.groupMeObject(o,False) bufferList.append(buffer) try:mc.delete(o) except:pass self.l_created = bufferList elif self._createMode =='follicle': if self.mode == 'midPoint': log.warning("Mid point mode doesn't work with follicles") return bufferList = [] for o in self.l_created: mesh = attributes.doGetAttr(o,'cgmHitTarget') if mc.objExists(mesh): uv = distance.returnClosestUVToPos(mesh,distance.returnWorldSpacePosition(o)) log.info("uv: {0}".format(uv)) follicle = nodes.createFollicleOnMesh(mesh) log.info("follicle: {0}".format(follicle)) attributes.doSetAttr(follicle[0],'parameterU',uv[0]) attributes.doSetAttr(follicle[0],'parameterV',uv[1]) try:mc.delete(o) except:pass else: for o in self.l_created: try:mc.delete(o) except:pass if self._createMode == 'curve' and len(self.l_return)>1: if len(self.l_return) > 1: self.l_created = [curves.curveFromPosList(self.l_return)] else: log.warning("Need at least 2 points for a curve") elif self._createMode == 'jointChain': self.l_created = [] mc.select(cl=True) for pos in self.l_return: self.l_created.append( mc.joint (p = (pos[0], pos[1], pos[2]),radius = 1) ) log.debug( self.l_created) if self.d_tagAndName: for o in self.l_created: try: i_o = cgmMeta.cgmNode(o) for tag in self.d_tagAndName.keys(): i_o.doStore(tag,self.d_tagAndName[tag]) i_o.doName() except StandardError,error: log.error(">>> clickMesh >> Failed to tag and name: %s | error: %s"%(i_o.p_nameShort,error))
def finalize(self): """ Press action. Clears buffers. """ #Clean our lists... self.createdList = lists.returnListNoDuplicates(self.createdList) self.returnList = lists.returnListNoDuplicates(self.returnList) if self.createMode in ['curve','jointChain','group','follicle'] and self.returnList: if self.createMode == 'group': bufferList = [] for i,o in enumerate(self.createdList): buffer = rigging.groupMeObject(o,False) bufferList.append(buffer) try:mc.delete(o) except:pass self.createdList = bufferList elif self.createMode =='follicle': if self.mode == 'midPoint': guiFactory.warning("Mid point mode doesn't work with follicles") return bufferList = [] for o in self.createdList: mesh = attributes.doGetAttr(o,'cgmHitTarget') if mc.objExists(mesh): uv = distance.returnClosestUVToPos(mesh,distance.returnWorldSpacePosition(o)) follicle = nodes.createFollicleOnMesh(mesh) attributes.doSetAttr(follicle[0],'parameterU',uv[0]) attributes.doSetAttr(follicle[0],'parameterV',uv[1]) try:mc.delete(o) except:pass else: for o in self.createdList: try:mc.delete(o) except:pass if self.createMode == 'curve' and len(self.returnList)>1: if len(self.returnList) > 1: self.createdList = [curves.curveFromPosList(self.returnList)] else: guiFactory.warning("Need at least 2 points for a curve") elif self.createMode == 'jointChain': self.createdList = [] mc.select(cl=True) for pos in self.returnList: self.createdList.append( mc.joint (p = (pos[0], pos[1], pos[2]),radius = 1) ) self.reset()
def doMove(self,**kws): if kws:log.debug("Snap.doMove>>> kws: %s"%kws) if len(self.l_targets) == 1: #>>> Check our target i_target = cgmMeta.cgmNode( self.l_targets[0] ) log.debug("i_target: %s"%i_target) targetType = i_target.getMayaType() if self.b_snapComponents: components = self.i_obj.getComponents() if not components:raise StandardError,"This objects has no components to snap: '%s'"%self.i_obj.getShortName() #>>>Progress bar mayaMainProgressBar = gui.doStartMayaProgressBar(len(components)) for c in components: if mc.progressBar(mayaMainProgressBar, query=True, isCancelled=True ) : break mc.progressBar(mayaMainProgressBar, edit=True, status = ("Wrapping '%s'"%c), step=1) if targetType in ['mesh','nurbsSurface','nurbsCurve']: pos = distance.returnWorldSpacePosition(c) targetLoc = mc.spaceLocator() mc.move (pos[0],pos[1],pos[2], targetLoc[0]) closestLoc = locators.locClosest([targetLoc[0]],i_target.mNode) if self._posOffset: self.doOrientObjToSurface(i_target.mNode,closestLoc) mc.move (self._posOffset[0],self._posOffset[1],self._posOffset[2], [closestLoc], r=True, rpr = True, os = True, wd = True) position.movePointSnap(c,closestLoc) mc.delete([targetLoc[0],closestLoc]) gui.doEndMayaProgressBar(mayaMainProgressBar)#Close out this progress bar else: pos = False if self.b_snaptoSurface:#>>> If our target is surface we can use if targetType in ['mesh','nurbsCurve','nurbsSurface']: i_locObj = self.i_obj.doLoc()#Get our position loc i_locTarget = cgmMeta.cgmObject( locators.locClosest([i_locObj.mNode],i_target.mNode) )#Loc closest #i_locObj.rename('objLoc') #i_locTarget.rename('targetLoc') if self._posOffset: try: self.doOrientObjToSurface(i_target.mNode,i_locTarget.mNode) mc.move (self._posOffset[0],self._posOffset[1],self._posOffset[2], [i_locTarget.mNode], r=True, rpr = True, os = True, wd = True) except StandardError,error: log.warn("self._posOffset failure!") log.error(error) pos = i_locTarget.getPosition(True) i_locObj.delete() i_locTarget.delete() elif self.b_midSurfacePos: log.debug("Snap.move>>> midSurfacePos mode!") if targetType not in ['mesh','nurbsCurve','nurbsSurface']: log.warning("Can't do midSurfacPos on targetType: '%s'"%targetType) return False #Get the axis info axisToCheck = kws.pop('axisToCheck',False) if not axisToCheck: axisToCheck = [] up = dictionary.returnVectorToString(self._upVector) or False if not up: raise StandardError,"SnapFactory>>> must have up vector for midSurfaceSnap: %s"%self._upVector for a in ['x','y','z']: if a != up[0]: axisToCheck.append(a) if not axisToCheck: raise StandardError,"SnapFactory>>> couldn't find any axis to do" #i_locObj = self.i_obj.doLoc()#Get our position loc #log.debug(axisToCheck) pos = RayCast.findMeshMidPointFromObject(i_target.mNode, self.i_obj.mNode, axisToCheck=axisToCheck,**kws) #i_locObj.delete() else: pos = i_target.getPosition(True) if pos: if self.i_obj.isComponent(): if self.b_softSelection:#Only need to do this if soft select is on mc.softSelect(softSelectEnabled = True) mc.select(self.i_obj.getComponent()) mc.move (pos[0],pos[1],pos[2],rpr=True) mc.select(cl=True) else: mc.move (pos[0],pos[1],pos[2], self.i_obj.getComponent()) else: mc.move (pos[0],pos[1],pos[2], self.i_obj.mNode, rpr=True)
def _fnc_processData(self): ''' Sort out the components ''' #...check if our vtx counts match... self.log_toDo("Remap dictionary argument") self.log_toDo("Non matching mesh types") self.mData.d_target = data.validateMeshArg(self.mData.d_target['mesh'])#...update _int_sourceCnt = int(self.mData.d_source['pointCount']) _int_targetCnt = int(self.mData.d_target['pointCount']) _type_source = self.mData.d_source['meshType'] _type_target = self.mData.d_target['meshType'] _target = self.mData.d_target['mesh'] _component = self.mData.d_target['component'] self.log_infoDict(self.mData.d_target,'target dict...') #if int(_int_sourceCnt) != int(_int_targetCnt): #return self._FailBreak_("Haven't implemented non matching component counts | source: {0} | target: {1}".format(_int_sourceCnt,_int_targetCnt)) if not _type_source == _type_target: return self._FailBreak_("Haven't implemented non matching mesh types | source: {0} | target: {1}".format(_type_source,_type_target)) #...generate a processed list... #[[jntIdx,v],[jntIdx,v]....] -- the count in the list is the vert count _raw_componentWeights = self.mData.d_sourceInfluences['componentWeights'] _raw_blendweights = self.mData.d_sourceInfluences['blendWeights'] _l_cleanData = [] #...First loop is to only initially clean the data... for i in range(_int_sourceCnt):#...for each vert _str_i = str(i) _subL = [] _bfr_raw = _raw_componentWeights[_str_i] _bfr_toNormalize = [] _bfr_clean = {} _d_normalized = {} for k,value in _bfr_raw.iteritems(): _bfr_clean[int(k)] = float(value) _d_normalized[int(k)] = None #normalize the values... for k,value in _bfr_clean.iteritems(): _bfr_toNormalize.append(value) _bfr_normalized = cgmMath.normSumList(_bfr_toNormalize,1.0) #self.log_info("To Normalize: {0}".format(_bfr_toNormalize)) #self.log_info("Normalized: {0}".format(_bfr_normalized)) #self.log_info("{0} pre sum: {1}".format(i,sum(_bfr_toNormalize))) #self.log_info("{0} sum: {1}".format(i,sum(_bfr_normalized))) for ii,k in enumerate(_d_normalized.keys()): _d_normalized[k] = _bfr_normalized[ii] #self.log_info("clean: {0}".format(_bfr_clean)) #self.log_info("norm: {0}".format(_d_normalized)) if not cgmMath.isFloatEquivalent(1.0, sum(_bfr_normalized) ): self.log_info("vert {0} not normalized".format(i)) #self.log_info("vert {0} base: {1}".format(i,_bfr_toNormalize)) #self.log_info("vert {0} norm: {1}".format(i,_bfr_normalized)) _l_cleanData.append(_d_normalized) #if i == 3:return self._FailBreak_("stop") self._l_processed = _l_cleanData#...initial push data #...nameMatch ------------------------------------------------------------------------ if self._b_nameMatch: self.log_info("nameMatch attempt...") _l_configInfluenceList = self.l_configInfluenceList _l_jointsToUseBaseNames = [names.getBaseName(n) for n in self.l_jointsToUse] for n in _l_jointsToUseBaseNames:#...see if all our names are there if not n in _l_configInfluenceList: #return self._FailBreak_ self.log_warning("nameMatch... joint '{0}' from joints to use list not in config list".format(n)) #self._FailBreak_("nameMatch... joint '{0}' from joints to use list not in config list".format(n)) #return False #return False _d_rewire = {} for i,n in enumerate(_l_configInfluenceList): _idx_base = _l_jointsToUseBaseNames.index(n) #self.log_error("Rewire. Name:{0} | config idx:{1} ===> currentIdx: {2}".format(n,_idx_config,i)) _d_rewire[i] = _idx_base """ for i,n in enumerate(_l_configInfluenceList): if _l_jointsToUseBaseNames[i] != n: self.log_error("Name mismatch. idx:{0} | config:{1} | useJoint:{2}".format(i,n,_l_jointsToUseBaseNames[i])) #_d_rewire[i] = _l_configInfluenceList.index(_l_jointsToUseBaseNames[i]) _d_rewire[i] = _l_configInfluenceList.index(_l_jointsToUseBaseNames[_l_jointsToUseBaseNames.index(n)]) """ self.log_infoDict(_d_rewire,"Rewire...") for i,d in enumerate(self._l_processed): _d_dup = copy.copy(d) #self.log_info("{0} before remap: {1}".format(i,d)) for r1,r2 in _d_rewire.iteritems():#...{1:2, 2:1} if r1 in _d_dup.keys():#...1,2 if r2 in _d_dup.keys(): _bfr1 = _d_dup[r1] _bfr2 = _d_dup[r2] d[r1] = _bfr2 d[r2] = _bfr1 else: d[r2] = d.pop(r1) #self.log_info("{0} after remap: {1}".format(i,d)) if int(_int_sourceCnt) != int(_int_targetCnt) or self._b_forceClosestComponent: try:#closest to remap ------------------------------------------------------------------------ self.log_warning("Non matching component counts. Using closestTo method to remap") _l_closestRetarget = [] #...generate a posList of the source data l_source_pos = [] _d_pos = self.mData.d_source['d_vertPositions'] for i in range(_int_sourceCnt): l_source_pos.append([float(v) for v in _d_pos[str(i)]])#...turn our strings to values self.progressBar_start(stepMaxValue=_int_targetCnt, statusMessage='Calculating....', interruptableState=False) for i in range(_int_targetCnt): _str_vert = "{0}.{1}[{2}]".format(_target,_component,i) self.progressBar_iter(status = "Finding closest to '{0}'".format(_str_vert)) #self.log_info(_str_vert) _pos = distance.returnWorldSpacePosition(_str_vert)#...get position _closestPos = distance.returnClosestPoint(_pos, l_source_pos)#....get closest _closestIdx = l_source_pos.index(_closestPos) #self.log_info("target idx: {0} | Closest idx: {1} | value{2}".format(i,_closestIdx,_l_cleanData[_closestIdx])) _l_closestRetarget.append(_l_cleanData[_closestIdx]) self.progressBar_end() self._l_processed = _l_closestRetarget#...push it backs self._b_smooth = True if _int_targetCnt >= _int_sourceCnt: self._f_smoothWeightsValue = .00005 else: self._f_smoothWeightsValue = .5 self.log_info("closestTo remap complete...") except Exception,error: raise Exception,"closestTo remap failure | {0}".format(error)
def getDistanceToCheck(self,m): assert mc.objExists(m), "'%s' doesn't exist. Couldn't check distance!"%m baseDistance = distance.returnDistanceBetweenPoints(self.clickPos, distance.returnWorldSpacePosition(m)) baseSize = distance.returnBoundingBoxSize(m) return distance.returnWorldSpaceFromMayaSpace( baseDistance + sum(baseSize) )
d_rootCastInfo = createMeshSliceCurve(targetGeo,mi_rootLoc,curveDegree=curveDegree,latheAxis=latheAxis,midMeshCast=midMeshCast,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) if extendMode == 'disc': l_sliceReturns.insert(1,d_rootCastInfo) else: l_sliceReturns.insert(0,d_rootCastInfo) #Special loli stuff if extendMode == 'loliwrap': Snap.go(i_ball.mNode,mi_rootLoc.mNode,True, True)#Snap to main object log.debug("hitReturns: %s"%d_rootCastInfo['hitReturns']) mi_crv = cgmMeta.cgmObject( d_rootCastInfo['curve'] ) #Pos data pos = distance.returnWorldSpacePosition("%s"%distance.returnMidU(mi_crv.mNode)) dist = distance.returnDistanceBetweenPoints(i_ball.getPosition(),pos) if '-' in aimAxis: distM = -dist else: distM = dist log.debug("distM: %s"%distM) #Move the ball pBuffer = i_ball.doGroup() i_ball.__setattr__('t%s'%single_aimAxis,distM) i_ball.parent = False mc.delete(pBuffer) uPos = distance.returnClosestUPosition(i_ball.mNode,mi_crv.mNode) Snap.go(i_ball.mNode,mi_rootLoc.mNode,move = False, orient = False, aim=True, aimVector=[0,0,-1])