def make_road(self, *args): #find out how to scale road to fit on face in case the size is changed #and this is optional. make it so that if two or more faces are selected in 1 direction, it automatically finds #out which direction to build the roads to sel_faces = cmds.ls(selection=True, flatten=True) for items in sel_faces: check5_value = cmds.checkBox(self.check5, query=True, value=True) check6_value = cmds.checkBox(self.check6, query=True, value=True) if check5_value == True and check6_value == True or check5_value == False and check6_value == False: sys.exit("Error! Pick one.") road = cmds.duplicate(u'road') cmds.parent(road, world=True) face = pm.MeshFace(items) pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) #moves road to the centre of a face cmds.move(centerPoint[0], centerPoint[1], centerPoint[2], road[0], scalePivotRelative=True, worldSpace=True) if check5_value == True and check6_value == False: pass elif check5_value == False and check6_value == True: cmds.rotate(90, road[0], rotateY=True)
def getFaceNormals(): faceList = [pm.MeshFace(res) for res in pm.filterExpand(expand = True, sm = 34)] if len(faceList) == 0: cmds.error("no faces selected!") norm = pm.dt.Vector() for face in faceList: norm += face.getNormal(space = 'world').normal() return norm.normal()
def find_average_normal(faces): face_normals = [] for face in faces: mesh_face = pmc.MeshFace(face) face_normals.append(mesh_face.getNormal()) sum_of_normals = sum(face_normals) ave_vtx_normal = sum_of_normals / len(sum_of_normals) ave_vtx_normal.normalize() tangent = ave_vtx_normal.cross(pmc.dt.Vector(0, 1, 0)) tangent.normalize() tangent2 = ave_vtx_normal.cross(tangent) tangent2.normalize() return ave_vtx_normal, tangent, tangent2
def place_objects(): cmds.select(mesh_name) number_of_faces = cmds.polyEvaluate(f=True) # we're comparing with up comparisonVector = OpenMaya.MVector(0, 1, 0) if len(tree_list) != 0: increment_age(tree_list) global seeds #print(seeds) for x in range(seeds): place = random.randint(0, number_of_faces) face = pm.MeshFace("{}.f[{}]".format(mesh_name, place)) # check normal of face pm.select(face) polyInfo = pm.polyInfo(fn=True) polyInfoArray = re.findall(r"[\w.-]+", polyInfo[0]) # convert the string to array with regular expression polyInfoX = float(polyInfoArray[2]) polyInfoY = float(polyInfoArray[3]) polyInfoZ = float(polyInfoArray[4]) face_normal = OpenMaya.MVector(polyInfoX, polyInfoY, polyInfoZ) deltaAngle = math.degrees(face_normal.angle(comparisonVector)) # the angle is in degrees so the result is # "if the difference between this normal and 'up' is more then 20 degrees, turn the point off" global angle angle = cmds.intSliderGrp('input_angle', query=True, value=True) if abs(deltaAngle) > angle: continue # Get center of face pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) plant = cmds.textField(plant_name, query=True, text=True) cmds.select(plant) tree_list.append(TreeInfo(cmds.instance(plant))) cmds.move(centerPoint[0], centerPoint[1], centerPoint[2]) tree_list[-1].update_fitness
def make_intersection(*args): sel_faces = cmds.ls(selection=True, flatten=True) for items in sel_faces: intersection = cmds.duplicate(u'intersection') face = pm.MeshFace(items) pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) #moves intersection to the centre of a face cmds.move(centerPoint[0], centerPoint[1], centerPoint[2], intersection[0], scalePivotRelative=True, worldSpace=True) cmds.parent(intersection, world=True)
def place_buildings(self, *args): sel_faces = cmds.ls(selection=True, flatten=True) for items in sel_faces: #all make_building methods are places here without "()" so they don't all end up being called all_buildings = [ self.make_building, self.make_building_2, self.make_building_3, self.make_building_4 ] #This gets/queries the value of the checkbox check1_value = cmds.checkBox(self.check1, query=True, value=True) #If check1 is checked off, it removes make_building from the list if check1_value == False: all_buildings.remove(self.make_building) check2_value = cmds.checkBox(self.check2, query=True, value=True) if check2_value == False: all_buildings.remove(self.make_building_2) check3_value = cmds.checkBox(self.check3, query=True, value=True) if check3_value == False: all_buildings.remove(self.make_building_3) check4_value = cmds.checkBox(self.check4, query=True, value=True) if check4_value == False: all_buildings.remove(self.make_building_4) #random.choice does not work unless there is 2 or more values to choose from. #the next couple of lines until after else works around this issue length = len(all_buildings) new_rand_bulding = 'nothing' if length == 1: new_rand_building = all_buildings[0]() elif length == 0: import sys sys.exit( "Error! Can't have 0 buildings. Please check at least one." ) else: #here it chooses a method and calls it, hence the "()" after "(all_buildings)" rand_building = random.choice(all_buildings)() new_rand_building = rand_building #gets the centre point of a face face = pm.MeshFace(items) pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) #moves building to the centre of a face cmds.move(centerPoint[0], centerPoint[1], centerPoint[2], new_rand_building[0], scalePivotRelative=True, worldSpace=True) width_value = cmds.floatField(self.width_floatfield, query=True, value=True) height_value = cmds.floatField(self.height_floatfield, query=True, value=True) widthDiv_value = cmds.intField(self.widthDiv_intfield, query=True, value=True) heightDiv_value = cmds.intField(self.heightDiv_intfield, query=True, value=True) maxHeight_value = cmds.intField(self.maxHeight_intfield, query=True, value=True) minHeight_value = cmds.intField(self.minHeight_intfield, query=True, value=True) face_width = width_value / widthDiv_value face_height = height_value / heightDiv_value max_width = face_width - (face_width * 0.10) # max_depth(cube) = max_height(building) max_depth = face_height - (face_height * 0.10) min_width = face_width * 0.6 min_depth = face_height * 0.6 max_size = (1.005 * max_width) - max_width min_size = max_size * 0.6 rand_size = random.uniform(min_size, max_size) cmds.scale(rand_size, rand_size, rand_size, new_rand_building[0]) cmds.move(0.828, new_rand_building[0], moveY=True, scalePivotRelative=True, relative=True) block = cmds.polyCube(name="building_block", width=face_width, depth=face_height, height=0.85) block_pos = cmds.xform(block[0] + ".vtx[0]", query=True, translation=True) cmds.move(block_pos[1], block[0] + ".scalePivot", moveY=True, worldSpace=True) cmds.move(block_pos[1], block[0] + ".rotatePivot", moveY=True, worldSpace=True) cmds.move(centerPoint[0], centerPoint[1], centerPoint[2], block[0], scalePivotRelative=True, worldSpace=True) #cmds.rename("building_block", "build_block") cmds.polyUnite(block[0], new_rand_building[0], name="building1", constructionHistory=False) cmds.hide("modular")
def scatter_objects(self, rand_rotation, rand_scale, align_to_normals): selection = cmds.ls(orderedSelection=True, flatten=True) vertex_names = cmds.filterExpand(selection, selectionMask=31, expand=True) face_names = cmds.polyListComponentConversion(vertex_names, fromVertex=True, toFace=True) face_names = cmds.filterExpand(face_names, selectionMask=34, expand=True) face_normals = [] for face in face_names: meshface = pmc.MeshFace(face) face_normals.append(meshface.getNormal()) sum_of_normals = sum(face_normals) ave_vtx_normal = sum_of_normals / len(sum_of_normals) tangent = ave_vtx_normal.cross(pmc.dt.Vector(0, 1, 0)) tangent.normalize() tangent2 = ave_vtx_normal.cross(tangent) tangent2.normalize() pos = cmds.xform(vertex_names, query=True, worldSpace=True, translation=True) matrix = [tangent2.x, tangent2.y, tangent2.z, 0.0, ave_vtx_normal.x, ave_vtx_normal.y, ave_vtx_normal.z, 0.0, tangent.x, tangent.y, tangent.z, 0.0, pos[0], pos[1], pos[2], 1.0] # Create a group to contain scatter objects scatter_group = cmds.group(em=True, n='scatter_group') object_to_instance = selection[0] if cmds.objectType(object_to_instance) == 'transform': for vertex in vertex_names: new_instance = cmds.instance(object_to_instance) position = cmds.pointPosition(vertex, world=True) # Position and add random rotation and scale new_position = [x for x in position] new_rotation = [random.uniform(rand_rotation[0], rand_rotation[1]) for _ in range(3)] new_scale = [random.uniform(rand_scale[0], rand_scale[1]) for _ in range(3)] if align_to_normals: cmds.xform(new_instance, worldSpace=True, matrix=matrix) # Move objects to position cmds.move(new_position[0], new_position[1], new_position[2], new_instance, absolute=True, worldSpace=True) # Set object rotation cmds.rotate(new_rotation[0], new_rotation[1], new_rotation[2], new_instance, relative=True, objectSpace=True) # Set object scale cmds.scale(new_scale[0], new_scale[1], new_scale[2], new_instance, relative=True) # Parent new instances to the scatter group from earlier cmds.parent(new_instance, scatter_group) else: print("Please ensure the first object you select is a transform.")
def create_snow(): import pymel.core as pm selobj = maya.cmds.ls(sl=True) if len(selobj) <= 0: maya.cmds.warning( 'Select one object to generate snow on top of it') return selobj = selobj[0] dup = maya.cmds.duplicate(selobj) maya.cmds.select(dup) obj = maya.cmds.ls(sl=True)[0] bbox = maya.cmds.xform(obj, q=True, ws=True, boundingBox=True) selection = maya.OpenMaya.MSelectionList() selection.add(obj) obj_mdagpath = maya.OpenMaya.MDagPath() selection.getDagPath(0, obj_mdagpath) obj_mfnMesh = maya.OpenMaya.MFnMesh(obj_mdagpath) face_ids = None tri_ids = None ids_sorted = False space = maya.OpenMaya.MSpace.kWorld max_param = 999999 test_both_directions = False accel_params = None sort_hits = True hit_points = maya.OpenMaya.MFloatPointArray() hit_ray_params = maya.OpenMaya.MFloatArray() hit_faces = maya.OpenMaya.MIntArray() selection = maya.cmds.ls(sl=True) num_of_faces = maya.cmds.polyEvaluate(selection, f=True) window = maya.cmds.window(t="Adding snow ... Please wait!") maya.cmds.columnLayout() progress_control = maya.cmds.progressBar(maxValue=num_of_faces, width=300) maya.cmds.showWindow(window) for i in range(num_of_faces): pselect = selection[0] + '.f[' + str(i) + ']' face = pm.MeshFace(pselect) pt = face.__apimfn__().center(maya.OpenMaya.MSpace.kWorld) center_point = pm.datatypes.Point(pt) pn = maya.cmds.polyInfo(pselect, fn=True)[0].split("\n")[0].split() maya.cmds.progressBar(progress_control, edit=True, pr=i + 1) ray_direction = maya.OpenMaya.MFloatVector(0, 0.25, 0) ray_source = maya.OpenMaya.MFloatPoint(center_point[0], center_point[1] + 0.1, center_point[2]) hit_points.clear() if obj_mfnMesh.allIntersections( ray_source, ray_direction, face_ids, tri_ids, ids_sorted, space, max_param, test_both_directions, accel_params, sort_hits, hit_points, hit_ray_params, hit_faces, None, None, None, 0.000001): maya.cmds.select(pselect, add=True) maya.cmds.selectMode(co=True) maya.cmds.delete() maya.cmds.selectMode(o=True) maya.cmds.deleteUI(window) em = maya.cmds.emitter(type='surface', spd=0, rate=1000) prt = maya.cmds.nParticle() maya.cmds.connectDynamic(prt[0], em=em) maya.cmds.setAttr(prt[1] + '.ignoreSolverGravity', 1) maya.cmds.setAttr(prt[1] + '.ignoreSolverWind', 1) maya.cmds.setAttr(prt[1] + '.maxCount', 70000) maya.cmds.setAttr(prt[1] + '.radius', 1) maya.cmds.setAttr(prt[1] + '.particleRenderType', 7) maya.cmds.play() maya.mel.eval('doParticleToPoly;')