def scaleAlongVector(self, scaleValue, scaleDirectionVector): """ This method scales subrofiles along vector and bakes this scaling information into subprofile points. """ scaleDirectionVector.normalize() newSubprofileList = [] for subprofile in self.subprofileList: scaledPointList = [] for point in subprofile.getPointList(): pointVector = MVector(point) pointPrime = point + (scaleDirectionVector * math.cos( pointVector.angle(scaleDirectionVector)) * pointVector.length() * (scaleValue - 1.0)) scaledPointList.append(pointPrime) newSubprofile = WireSubprofile(scaledPointList, subprofile.isClosed()) newSubprofileList.append(newSubprofile) self.subprofileList = newSubprofileList
def _createPatternWireProfileData(self, wireSubprofile): # PRE-PLACEMENT TRANSFORMATIONS prePlacementPointList = [] ppTransformationMatrix = MTransformationMatrix() scaleValue = self.backupData.patternScaleSubprofiles ppTransformationMatrix.setScale((scaleValue, scaleValue, 1.0), MSpace.kTransform) for point in wireSubprofile.getPointList(): prePlacementPointList.append(point * ppTransformationMatrix.asMatrix()) # PLACEMENT TRANSFORMATIONS patternSubprofileList = [] # circle layout if self.backupData.patternLayout == 0: eulerRotation = MEulerRotation() radianSteps = math.radians( 360.0 / self.backupData.patternNOS) * self.backupData.patternCoverage pTransformationMatrix = MTransformationMatrix() pTransformationMatrix.setTranslation(MVector(0.0, 1.0, 0.0), MSpace.kTransform) pTransformationMatrix.setRotatePivot(MPoint(0.0, -1.0, 0.0), MSpace.kTransform, True) for i in range(self.backupData.patternNOS): eulerRotation.z = radianSteps * i pTransformationMatrix.setRotation(eulerRotation) patternSubprofilePointList = [] for point in prePlacementPointList: patternSubprofilePointList.append( point * pTransformationMatrix.asMatrix()) patternSubprofileList.append( WireSubprofile(patternSubprofilePointList, wireSubprofile.isClosed())) # line layout elif self.backupData.patternLayout == 1: for i in range(self.backupData.patternNOS): translateVector = MVector(0.0, 0.0, 0.0) if self.backupData.patternNOS > 1: translateVector.x = i * self.backupData.patternCoverage / ( self.backupData.patternNOS - 1) # 0 to 1 range translateVector.x *= 2.0 # 0 to 2 range translateVector.x -= 1.0 # -1 to 1 range patternSubprofilePointList = [] for point in prePlacementPointList: patternSubprofilePointList.append(point + translateVector) patternSubprofileList.append( WireSubprofile(patternSubprofilePointList, wireSubprofile.isClosed())) return WireProfileData(patternSubprofileList)
def length_control_expression_archtype(curve_length, scale_ctl, fk0_npo, curve_op, scale_cns): from maya.api.OpenMaya import MVector def sigmoid(x, mi, mx): return mi + (mx-mi)*(lambda t: (1+((200. / curve_length)*100.)**(-t+0.5))**(-1) )( (x-mi)/(mx-mi)) tz = scale_ctl.translateY if curve_length < tz: # s = sigmoid(tz * (200. / curve_length), 0.0001, 100.0) * 0.01 s = tz / curve_length vis = True fk0_npo.scale = MVector(1., 1., 1.) curve_op.slave_length = curve_length # * s curve_op.maxstretch = s elif 0.0 < tz: s = tz / curve_length vis = True fk0_npo.scale = MVector(1., 1., 1.) curve_op.slave_length = curve_length * s curve_op.maxstretch = s else: s = 0.001 vis = False fk0_npo.scale = MVector(s, s, s) scale_cns.scale = MVector(s, s, s) fk0_npo.visibility = vis
def calc_coords(self, a_coords, b_coords, add=False, sub=False): ''' Perfoms add or substract operations on a [x, y, z] input: [float, float, float] output: [float, float, float] ''' a_vector = MVector(a_coords) b_vector = MVector(b_coords) if add: result = list(a_vector + b_vector) elif sub: result = list(b_vector - a_vector) else: sys.exit('Only "sub" or "add" flags supported') # Operations are correct even without float formatting #diff = [float('%.10f' % c) for c in diff] return result
def scaleAlongVector(self, scaleValue, scaleDirectionVector): """ For proper results this method assumes that scaleDirectionVector is on the same plane as WireSection (in world space). """ self.isWireProfileDataModified = True self.wireProfileDataModified = WireProfileData( self.wireProfileData.getSubprofileList()) scaleDirectionVectorLocalSpace = scaleDirectionVector * self.modelMatrix.asMatrixInverse( ) scaleDirectionVectorLocalSpace.z = 0.0 if (scaleDirectionVectorLocalSpace != MVector(0.0, 0.0, 0.0)): self.wireProfileDataModified.scaleAlongVector( scaleValue, scaleDirectionVectorLocalSpace) else: MGlobal.displayWarning( "Could not scale wire section along provided vector.")
def swap_coord_space(data): """ Transforms from PDX space (-Z forward, Y up) to Maya space (Z forward, Y up) """ global SPACE_MATRIX # matrix if type(data) == MMatrix or type(data) == pmdt.Matrix: mat = MMatrix(data) return SPACE_MATRIX * mat * SPACE_MATRIX.inverse() # quaternion elif type(data) == MQuaternion or type(data) == pmdt.Quaternion: mat = MMatrix(data.asMatrix()) return MTransformationMatrix(SPACE_MATRIX * mat * SPACE_MATRIX.inverse()).rotation(asQuaternion=True) # vector elif type(data) == MVector or type(data) == pmdt.Vector or len(data) == 3: vec = MVector(data) return vec * SPACE_MATRIX # uv coordinate elif len(data) == 2: return data[0], 1 - data[1] # unknown else: raise NotImplementedError("Unknown data type encountered.")
def get_length(self, a_pos, b_pos): return (MVector(b_pos) - MVector(a_pos)).length()
def doit(s=13): cmds.file(f=True, new=True) seed(s) cm.loadPlugin('exprespy') expr = cm.nt.Exprespy() x = randX() p = expr.i[0] _testSetGet(p, _randI()) _testSetGet(p, _randF()) _testSetGet(p, x) _testSetGet(p, x.m) _testSetGet(p, MMatrix(x.m)) _testSetGet(p, MFloatMatrix(x.m)) _testSetGet(p, x.t) _testSetGet(p, MVector(x.t)) _testSetGet(p, x.q) _testSetGet(p, MQuaternion(x.q)) _testSetGet(p, MPoint(x.q)) _testSetGet(p, _randFArr(2)) _testSetGet(p, _randS()) p = expr.addAttr('dblmat', 'matrix', getPlug=True) _testSetGet(p, x) _testSetGet(p, x.m) _testSetGet(p, MMatrix(x.m)) _testSetGet(p, MFloatMatrix(x.m)) p = expr.addAttr('atdblmat', 'at:matrix', getPlug=True) _testSetGet(p, x.m) _testSetGet(p, MMatrix(x.m)) _testSetGet(p, MFloatMatrix(x.m)) p = expr.addAttr('fltmat', 'fltMatrix', getPlug=True) _testSetGet(p, MFloatMatrix(x.m)) p = expr.addAttr('bool', 'bool', getPlug=True) _testSetGet(p, False) _testSetGet(p, True) _testSetGet(expr.addAttr('byte', 'byte', getPlug=True), _randI(0, 128)) # 0~127 _testSetGet(expr.addAttr('char', 'char', getPlug=True), _randI(0, 128)) # 0~127 _testSetGet(expr.addAttr('short', 'short', getPlug=True), _randI(-32767, 32767)) _testSetGet(expr.addAttr('long', 'long', getPlug=True), _randI()) _testSetGet(expr.addAttr('double', 'double', getPlug=True), _randF()) _testSetGet(expr.addAttr('doubleLinear', 'doubleLinear', getPlug=True), _randF(), partial(_compareF, tol=1e-12)) _testSetGet(expr.addAttr('doubleAngle', 'doubleAngle', getPlug=True), _randF(), partial(_compareF, tol=1e-12)) _testSetGet(expr.addAttr('time', 'time', getPlug=True), _randF(), partial(_compareF, tol=TIME_TOLERANCE)) _testSetGet(expr.addAttr('float', 'float', getPlug=True), _randF(), _compareF) _testSetGet(expr.addAttr('floatLinear', 'floatLinear', getPlug=True), _randF(), _compareF) _testSetGet(expr.addAttr('floatAngle', 'floatAngle', getPlug=True), _randF(), _compareF) _testSetGet(expr.addAttr('string', 'string', getPlug=True), _randS()) _testSetGet(expr.addAttr('dtdouble3', 'dt:double3', getPlug=True), x.s) _testSetGet(expr.addAttr('double3', 'double3', getPlug=True), x.s) _testSetGet(expr.addAttr('dblang3', 'double3', 'doubleAngle', getPlug=True), x.r, partial(_compareFArr, tol=1e-12)) _testSetGet(expr.addAttr('dbllnr3', 'double3', 'doubleLinear', getPlug=True), x.t, partial(_compareFArr, tol=1e-12)) _testSetGet(expr.addAttr('dtfloat3', 'dt:float3', getPlug=True), x.s, _compareFArr) _testSetGet(expr.addAttr('float3', 'float3', getPlug=True), x.s, _compareFArr) _testSetGet(expr.addAttr('fltang3', 'float3', 'floatAngle', getPlug=True), x.r, _compareFArr) _testSetGet(expr.addAttr('fltlnr3', 'float3', 'floatLinear', getPlug=True), x.t, _compareFArr) _testSetGet(expr.addAttr('color', 'float3', uac=True, getPlug=True), _randColor()) _testSetGet(expr.addAttr('reflectanceRGB', 'reflectanceRGB', getPlug=True), _randColor()) _testSetGet(expr.addAttr('spectrumRGB', 'spectrumRGB', getPlug=True), _randColor()) # setAttr すると Red にしか値が入らず、且つ違う値になる。-dt の方は問題ないのでバグだろう。 #_testSetGet(expr.addAttr('reflectance', 'reflectance', getPlug=True), _randColor()) #_testSetGet(expr.addAttr('spectrum', 'spectrum', getPlug=True), _randColor()) _testSetGetArray(expr.addAttr('dblarr', 'doubleArray', getPlug=True), _randFArr, lrange(8)) _testSetGetArray(expr.addAttr('fltarr', 'floatArray', getPlug=True), _randFArr, lrange(8), _compareFArr) _testSetGetArray(expr.addAttr('i32arr', 'Int32Array', getPlug=True), _randIArr, lrange(8)) _testSetGetArray(expr.addAttr('strarr', 'stringArray', getPlug=True), _randSArr, lrange(8)) # Int64Array の setAttr はバギー。 # - long を含むとエラー。 # - 要素数が奇数だと要素が1個減ってセットされる。 # - 負数は含められないので、実質 unsigned ぽいが、バグか仕様かは不明。 if cm.MAYA_VERSION >= (2016, 5): _testSetGetArray(expr.addAttr('i64arr', 'Int64Array', getPlug=True), partial(_randIArr, mn=0), lrange(0, 8, 2)) # _randLArr, lrange(8)) if cm.MAYA_VERSION >= (2016,): _testSetGetArray(expr.addAttr('matarr', 'matrixArray', getPlug=True), _randMatArr, lrange(8)) _testSetGetArray(expr.addAttr('vecarr', 'vectorArray', getPlug=True), _randVecArr, lrange(8)) _testSetGetArray(expr.addAttr('fvecarr', 'floatVectorArray', getPlug=True), _randFVecArr, lrange(8)) _testSetGetArray(expr.addAttr('pntarr', 'pointArray', getPlug=True), _randPntArr, lrange(8))
def _randVecArr(n): return [MVector(_randFArr(3)) for i in range(n)]
def create_anim_keys(joint_name, key_dict, timestart): jnt_obj = get_MObject(joint_name) # calculate start and end frames timestart = int(timestart) timeend = timestart + len(max(key_dict.values(), key=len)) # create a time array time_array = OpenMaya.MTimeArray() for t in xrange(timestart, timeend): time_array.append(OpenMaya.MTime(t, OpenMaya.MTime.uiUnit())) # define anim curve tangent k_Tangent = OpenMayaAnim.MFnAnimCurve.kTangentLinear if 's' in key_dict: # scale data animated_attrs = dict(scaleX=None, scaleY=None, scaleZ=None) for attrib in animated_attrs: # create the curve and API function set anim_curve, mFn_AnimCurve = create_animcurve(jnt_obj, attrib) animated_attrs[attrib] = mFn_AnimCurve # create data arrays per animating attribute x_scale_data = OpenMaya.MDoubleArray() y_scale_data = OpenMaya.MDoubleArray() z_scale_data = OpenMaya.MDoubleArray() for scale_data in key_dict['s']: # convert to Game space x_scale_data.append(scale_data[0]) y_scale_data.append(scale_data[0]) z_scale_data.append(scale_data[0]) # add keys to the new curves for attrib, data_array in zip(animated_attrs, [x_scale_data, y_scale_data, z_scale_data]): mFn_AnimCurve = animated_attrs[attrib] mFn_AnimCurve.addKeys(time_array, data_array, k_Tangent, k_Tangent) if 'q' in key_dict: # quaternion data animated_attrs = dict(rotateX=None, rotateY=None, rotateZ=None) for attrib in animated_attrs: # create the curve and API function set anim_curve, mFn_AnimCurve = create_animcurve(jnt_obj, attrib) animated_attrs[attrib] = mFn_AnimCurve # create data arrays per animating attribute x_rot_data = OpenMaya.MDoubleArray() y_rot_data = OpenMaya.MDoubleArray() z_rot_data = OpenMaya.MDoubleArray() for quat_data in key_dict['q']: # convert to Game space q = swap_coord_space(MQuaternion(*quat_data)) # convert from quaternion to euler, this gives values in radians (which Maya uses internally) euler_data = q.asEulerRotation() x_rot_data.append(euler_data.x) y_rot_data.append(euler_data.y) z_rot_data.append(euler_data.z) # add keys to the new curves for attrib, data_array in zip(animated_attrs, [x_rot_data, y_rot_data, z_rot_data]): mFn_AnimCurve = animated_attrs[attrib] mFn_AnimCurve.addKeys(time_array, data_array, k_Tangent, k_Tangent) if 't' in key_dict: # translation data animated_attrs = dict(translateX=None, translateY=None, translateZ=None) for attrib in animated_attrs: # create the curve and API function set anim_curve, mFn_AnimCurve = create_animcurve(jnt_obj, attrib) animated_attrs[attrib] = mFn_AnimCurve # create data arrays per animating attribute x_trans_data = OpenMaya.MDoubleArray() y_trans_data = OpenMaya.MDoubleArray() z_trans_data = OpenMaya.MDoubleArray() for trans_data in key_dict['t']: # convert to Game space t = swap_coord_space(MVector(*trans_data)) x_trans_data.append(t[0]) y_trans_data.append(t[1]) z_trans_data.append(t[2]) # add keys to the new curves for attrib, data_array in zip(animated_attrs, [x_trans_data, y_trans_data, z_trans_data]): mFn_AnimCurve = animated_attrs[attrib] mFn_AnimCurve.addKeys(time_array, data_array, k_Tangent, k_Tangent)
def import_animfile(animpath, timestart=1.0, progress_fn=None): start = time.time() print "[io_pdx_mesh] importing {}".format(animpath) progress = None if progress_fn: progress = progress_fn('Importing', 10) # read the file into an XML structure asset_elem = pdx_data.read_meshfile(animpath) # find animation info and samples info = asset_elem.find('info') samples = asset_elem.find('samples') framecount = info.attrib['sa'][0] # set scene animation and playback settings fps = info.attrib['fps'][0] try: pmc.currentUnit(time=('{}fps'.format(fps))) except RuntimeError: fps = int(fps) if fps == 15: pmc.currentUnit(time='game') elif fps == 30: pmc.currentUnit(time='ntsc') else: raise NotImplementedError("Unsupported animation speed. {}".format(fps)) print "[io_pdx_mesh] setting playback speed - {}".format(fps) if progress_fn: progress.update(1, 'setting playback speed') pmc.playbackOptions(e=True, playbackSpeed=1.0) pmc.playbackOptions(e=True, animationStartTime=0.0) print "[io_pdx_mesh] setting playback range - ({},{})".format(timestart, (timestart + framecount - 1)) if progress_fn: progress.update(1, 'setting playback range') pmc.playbackOptions(e=True, minTime=timestart) pmc.playbackOptions(e=True, maxTime=(timestart + framecount - 1)) pmc.currentTime(0, edit=True) # find bones being animated in the scene print "[io_pdx_mesh] finding bones -" if progress_fn: progress.update(1, 'finding bones') bone_errors = [] for bone in info: bone_joint = None bone_name = clean_imported_name(bone.tag) try: matching_bones = pmc.ls(bone_name, type=pmc.nt.Joint, long=True) # type: pmc.nodetypes.joint bone_joint = matching_bones[0] except IndexError: bone_errors.append(bone_name) print "[io_pdx_mesh] failed to find bone '{}'".format(bone_name) if progress_fn: progress.update(1, 'failed to find bone!') # set initial transform and remove any joint orientation (this is baked into rotation values in the .anim file) if bone_joint: # compose transform parts _scale = [bone.attrib['s'][0], bone.attrib['s'][0], bone.attrib['s'][0]] _rotation = MQuaternion(*bone.attrib['q']) _translation = MVector(*bone.attrib['t']) # convert to Game space bone_joint.setScale(_scale) bone_joint.setRotation(swap_coord_space(_rotation)) bone_joint.setTranslation(swap_coord_space(_translation)) # zero out joint orientation bone_joint.jointOrient.set(0.0, 0.0, 0.0) # break on bone errors if bone_errors: raise RuntimeError("Missing bones required for animation:\n{}".format(bone_errors)) # check which transform types are animated on each bone all_bone_keyframes = OrderedDict() for bone in info: bone_name = clean_imported_name(bone.tag) key_data = dict() all_bone_keyframes[bone_name] = key_data for sample_type in bone.attrib['sa'][0]: key_data[sample_type] = [] # then traverse the samples data to store keys per bone s_index, q_index, t_index = 0, 0, 0 for f in range(0, framecount): for i, bone_name in enumerate(all_bone_keyframes): bone_key_data = all_bone_keyframes[bone_name] if 's' in bone_key_data: bone_key_data['s'].append(samples.attrib['s'][s_index : s_index + 1]) s_index += 1 if 'q' in bone_key_data: bone_key_data['q'].append(samples.attrib['q'][q_index : q_index + 4]) q_index += 4 if 't' in bone_key_data: bone_key_data['t'].append(samples.attrib['t'][t_index : t_index + 3]) t_index += 3 for bone_name in all_bone_keyframes: bone_keys = all_bone_keyframes[bone_name] # check bone has keyframe values if bone_keys.values(): print "[io_pdx_mesh] setting {} keyframes on bone '{}'".format(list(bone_keys.keys()), bone_name) if progress_fn: progress.update(1, 'setting keyframes on bone') bone_long_name = pmc.ls(bone_name, type=pmc.nt.Joint, long=True)[0].name() create_anim_keys(bone_long_name, bone_keys, timestart) pmc.select(None) print "[io_pdx_mesh] import finished! ({:.4f} sec)".format(time.time() - start) if progress_fn: progress.finished()
def _computeOutMeshArrayElement(self, pOutMeshArrayElement, pInCurveArrayElement, dataBlock): #-------------------------------------------------------------------------# # READ #-------------------------------------------------------------------------# voCurve = dataBlock.inputValue( pInCurveArrayElement).asNurbsCurveTransformed() interpolationDistance = self.backupData.interpolationDistance interpolationRange = self.backupData.interpolationRange interpolationSteps = self.backupData.interpolationSteps normalsReverse = self.backupData.normalsReverse normalsSmoothing = self.backupData.normalsSmoothing rotateProfile = self.backupData.rotateProfile scaleProfile = self.backupData.scaleProfile twist = self.backupData.twist wireProfileIndex = self.backupData.wireProfileIndex #-------------------------------------------------------------------------# # PROCESS #-------------------------------------------------------------------------# # WIRE PROFILE self.activeWireProfileData = self._getWireProfileData(wireProfileIndex) # SETUP WIRE SECTION BUILD INFORMATION fnNURBSCurve = MFnNurbsCurve(voCurve) curveLength = fnNURBSCurve.length() wireSectionBuildInfoList = [] # start to end interpolation if interpolationRange == 0: for step in range(interpolationSteps + 1): param = fnNURBSCurve.findParamFromLength( (curveLength / interpolationSteps) * step) tangent = fnNURBSCurve.tangent(param).normalize() adjustOnEP = False stepBackTangent = MVector(0.0, 0.0, 0.0) wireSectionBuildInfo = (param, tangent, adjustOnEP, stepBackTangent) wireSectionBuildInfoList.append(wireSectionBuildInfo) # ep to ep interpolation elif interpolationRange == 1: tangent = fnNURBSCurve.tangent(0.0).normalize() adjustOnEP = False stepBackTangent = MVector(0.0, 0.0, 0.0) wireSectionBuildInfo = (0.0, tangent, adjustOnEP, stepBackTangent) wireSectionBuildInfoList.append(wireSectionBuildInfo) lastKnot = 0.0 for knot in fnNURBSCurve.knots(): if knot != lastKnot: startLength = fnNURBSCurve.findLengthFromParam(lastKnot) endLength = fnNURBSCurve.findLengthFromParam(knot) lengthRange = endLength - startLength for step in range(1, interpolationSteps + 1): # There is possibility to omit getting params from length and # get those straight up from knots, but it yields non-uniform # spacing between wire sections. param = fnNURBSCurve.findParamFromLength( startLength + (lengthRange / interpolationSteps) * step) adjustOnEP = False stepBackTangent = MVector(0.0, 0.0, 0.0) if step == interpolationSteps: adjustOnEP = True accuracy = 10000.0 stepBackTangentParam = fnNURBSCurve.findParamFromLength( startLength + (lengthRange / accuracy) * (accuracy - 1.0)) stepBackTangent = fnNURBSCurve.tangent( stepBackTangentParam).normalize() tangent = fnNURBSCurve.tangent(param).normalize() wireSectionBuildInfo = (param, tangent, adjustOnEP, stepBackTangent) wireSectionBuildInfoList.append(wireSectionBuildInfo) lastKnot = knot # distance interpolation elif interpolationRange == 2: curveDistance = 0.0 distanceSafeThreshold = interpolationDistance * 0.3 while (curveDistance < curveLength - distanceSafeThreshold): param = fnNURBSCurve.findParamFromLength(curveDistance) tangent = fnNURBSCurve.tangent(param).normalize() adjustOnEP = False stepBackTangent = MVector(0.0, 0.0, 0.0) wireSectionBuildInfo = (param, tangent, adjustOnEP, stepBackTangent) wireSectionBuildInfoList.append(wireSectionBuildInfo) curveDistance += interpolationDistance param = fnNURBSCurve.findParamFromLength(curveLength) tangent = fnNURBSCurve.tangent(param).normalize() adjustOnEP = False stepBackTangent = MVector(0.0, 0.0, 0.0) wireSectionBuildInfo = (param, tangent, adjustOnEP, stepBackTangent) wireSectionBuildInfoList.append(wireSectionBuildInfo) # CREATE WIRE SECTIONS wireSectionList = [] for (param, tangent, adjustOnEP, stepBackTangent) in wireSectionBuildInfoList: wireSection = WireSection(self.activeWireProfileData) # translate point = fnNURBSCurve.getPointAtParam(param) wireSection.setTranslation(point) # rotate if (len(wireSectionList) == 0): # First wire section is rotated in a way that omits rotation around # local z axis. Comparing this to FPS camera movement we would # say that there is no roll transformation, only pitch and yawn. xRotation = 0.0 tangentProjection = MVector(tangent.x, 0.0, tangent.z) if (tangentProjection != tangent): if (tangent.x == 0 and tangent.z == 0): xRotation = math.radians(90.0) else: xRotation = math.acos( mathUtils.dot(tangent, tangentProjection) / (tangent.length() * tangentProjection.length())) if (tangent.y > 0.0): xRotation = -xRotation yRotation = 0.0 if (tangentProjection != MVector(0.0, 0.0, 0.0)): yRotation = math.acos( mathUtils.dot(tangentProjection, MVector( 0.0, 0.0, 1.0)) / tangentProjection.length()) if (tangentProjection.x < 0.0): yRotation = -yRotation wireSection.rotate(MEulerRotation(xRotation, yRotation, 0.0), WireSection.RotationType.ALIGN_WITH_TANGENT) else: previousWireSection = wireSectionList[-1] alignWithTangentRotation \ = previousWireSection.getRotationOfType(WireSection.RotationType.ALIGN_WITH_TANGENT) \ * previousWireSection.getRotationOfType(WireSection.RotationType.ADJUST_ON_EP) \ * MQuaternion(previousWireSection.getLocalZAxis(), tangent) wireSection.rotate(alignWithTangentRotation, WireSection.RotationType.ALIGN_WITH_TANGENT) if adjustOnEP == True and fnNURBSCurve.degree == 1: wireSection.rotate( MQuaternion(wireSection.getLocalZAxis(), stepBackTangent, 0.5), WireSection.RotationType.ADJUST_ON_EP) if (rotateProfile != 0.0): wireSection.rotate( MQuaternion(math.radians(rotateProfile), wireSection.getLocalZAxis()), WireSection.RotationType.CUSTOM_PROFILE_ROTATION) if (twist != 0.0): curveLengthToPoint = fnNURBSCurve.findLengthFromParam(param) twistRotationAngle = math.radians( twist * (curveLengthToPoint / curveLength)) twistRotation = MQuaternion(twistRotationAngle, wireSection.getLocalZAxis()) wireSection.rotate(twistRotation, WireSection.RotationType.TWIST) # scale wireSection.setScale(scaleProfile, scaleProfile, 1.0) if adjustOnEP == True and fnNURBSCurve.degree == 1: transformationMatrix = MTransformationMatrix() stepBackTangentOpposite = stepBackTangent * -1 transformationMatrix.setRotation( MQuaternion(tangent, stepBackTangentOpposite, 0.5)) scaleVector = tangent * transformationMatrix.asMatrix() scaleValue = 1 / math.sin( scaleVector.angle(stepBackTangentOpposite)) wireSection.scaleAlongVector(scaleValue, scaleVector) # add wireSectionList.append(wireSection) # GENERATE MESH DATA vertexList = [] polygonOffsetList = [] vertexSequenceList = [] numSubprofiles = self.activeWireProfileData.getNumSubprofiles() for i in range(numSubprofiles): subprofileSize = self.activeWireProfileData.getSubprofileSize(i) # vertex list for wireSection in wireSectionList: if (normalsReverse == True ): # reverse normals / change drawing order vertexList.extend( list(reversed(wireSection.getSubprofilePoints(i)))) else: vertexList.extend(wireSection.getSubprofilePoints(i)) # polygon offset list numQuads = 0 if self.activeWireProfileData.isSubprofileClosed(i) == True: numQuads = subprofileSize * (len(wireSectionList) - 1) else: numQuads = (subprofileSize - 1) * (len(wireSectionList) - 1) polygonOffsetList.extend([4] * numQuads) # [4, 4, 4, ...] # vertex sequence list meshJump = i * subprofileSize * len(wireSectionList) for j in range(len(wireSectionList) - 1): wireSectionJump = j * subprofileSize for k in range(subprofileSize - 1): vertexSequenceList.extend([ meshJump + wireSectionJump + k, meshJump + wireSectionJump + k + 1, meshJump + wireSectionJump + subprofileSize + 1 + k, meshJump + wireSectionJump + subprofileSize + k ]) if self.activeWireProfileData.isSubprofileClosed(i) == True: vertexSequenceList.extend([ meshJump + wireSectionJump + subprofileSize - 1, meshJump + wireSectionJump, meshJump + wireSectionJump + subprofileSize, meshJump + wireSectionJump + (2 * subprofileSize) - 1 ]) # CREATE MESH fnMesh = MFnMesh() fnMeshData = MFnMeshData() oMeshData = fnMeshData.create() oMesh = fnMesh.create(vertexList, polygonOffsetList, vertexSequenceList, parent=oMeshData) # SET NORMALS SMOOTHING #if (self.computeFlagMap["normals"] == True): # << ADD LATER WHEN self.computeFlagMap["topology"] # is implemented for topology creation itMeshEdge = MItMeshEdge(oMesh) if (normalsSmoothing == 0.0): # hard edge while (itMeshEdge.isDone() == False): fnMesh.setEdgeSmoothing(itMeshEdge.index(), False) itMeshEdge.next() elif (normalsSmoothing == 180.0): # soft edge while (itMeshEdge.isDone() == False): fnMesh.setEdgeSmoothing(itMeshEdge.index(), True) itMeshEdge.next() else: while (itMeshEdge.isDone() == False): if (itMeshEdge.numConnectedFaces() == 2): faceIDList = itMeshEdge.getConnectedFaces() faceNormal1 = fnMesh.getPolygonNormal(faceIDList[0]) faceNormal2 = fnMesh.getPolygonNormal(faceIDList[1]) angleRad = faceNormal1.angle(faceNormal2) if (angleRad <= math.radians(normalsSmoothing)): fnMesh.setEdgeSmoothing(itMeshEdge.index(), True) else: fnMesh.setEdgeSmoothing(itMeshEdge.index(), False) itMeshEdge.next() fnMesh.cleanupEdgeSmoothing() #-------------------------------------------------------------------------# # OUTPUT #-------------------------------------------------------------------------# dataBlock.outputValue(pOutMeshArrayElement).setMObject(oMeshData) dataBlock.setClean(pOutMeshArrayElement)
cmds.sets(mfnMesh.fullPathName(), e = 1, fe = 'initialShadingGroup') mfnMesh.updateSurface() ''' # mfnMesh = om.mfnMesh() # mfnmesh.create() # now need to find edge index from point # A example test beizer curve, later convert this to our curve ''' -1 1 1 1 -0.5,0.5 0.5,0.5 -0.5,-0.5 0.5,-0.5 -1 -1 1 -1 ''' # this should be replaced by .cp file modifications p = [MVector(-1.0,0.0,-1.0),MVector(-0.5,0.0,-0.5),MVector(-0.5,0.0,0.5), MVector(-1.0,0.0,1.0)] c2 = [MVector(-1.0,0.0,-1.0),MVector(-0.5,0.0,-0.5),MVector(0.5,0.0,-0.5), MVector(1.0,0.0,-1.0)] c3 = [MVector(-1.0,0.0,1.0),MVector(-0.5,0.0,0.5),MVector(0.5,0.0,0.5), MVector(1.0,0.0,1.0)] c4 = [MVector(1.0,0.0,-1.0),MVector(0.5,0.0,-0.5),MVector(0.5,0.0,0.5), MVector(1.0,0.0,1.0)] createSingleCrease(newFace[0], p) createSingleCrease(newFace[0], c2) createSingleCrease(newFace[0], c3) createSingleCrease(newFace[0], c4) # subdivide the faces with polySubdivideFacet polySplitCrease()
def getLocalYAxis(self): return MVector(0.0, 1.0, 0.0) * self.modelMatrix.asMatrix()
def setTranslation(self, point): self.modelMatrix.setTranslation(MVector(point), MSpace.kTransform)