From 2cc1dd0409ae1f36cb45be1261a2c7ab5f41bec6 Mon Sep 17 00:00:00 2001 From: "Spivak Vladimir (cwolf3d)" Date: Sun, 21 Apr 2019 14:05:35 +0300 Subject: Separated mesh_discombobulator from add_mesh_extra_objects --- add_mesh_extra_objects/__init__.py | 11 - add_mesh_extra_objects/mesh_discombobulator.py | 870 ------------------------- 2 files changed, 881 deletions(-) delete mode 100644 add_mesh_extra_objects/mesh_discombobulator.py (limited to 'add_mesh_extra_objects') diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index da2c4ec7..6f5c575b 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -57,7 +57,6 @@ if "bpy" in locals(): importlib.reload(add_mesh_menger_sponge) importlib.reload(add_mesh_vertex) importlib.reload(add_empty_as_parent) - importlib.reload(mesh_discombobulator) importlib.reload(add_mesh_beam_builder) importlib.reload(Blocks) importlib.reload(Wallfactory) @@ -80,7 +79,6 @@ else: from . import add_mesh_menger_sponge from . import add_mesh_vertex from . import add_empty_as_parent - from . import mesh_discombobulator from . import add_mesh_beam_builder from . import Blocks from . import Wallfactory @@ -250,9 +248,6 @@ def menu_func(self, context): lay_out.menu("VIEW3D_MT_mesh_torus_add", text="Torus Objects") lay_out.separator() - lay_out.operator("discombobulate.ops", - text="Discombobulator") - lay_out.separator() lay_out.menu("VIEW3D_MT_mesh_extras_add", text="Extras") lay_out.separator() @@ -297,12 +292,6 @@ classes = [ add_mesh_vertex.AddSymmetricalVert, add_empty_as_parent.P2E, add_empty_as_parent.PreFix, - mesh_discombobulator.discombobulator, - mesh_discombobulator.discombobulator_dodads_list, - mesh_discombobulator.discombob_help, - mesh_discombobulator.VIEW3D_OT_tools_discombobulate, - mesh_discombobulator.chooseDoodad, - mesh_discombobulator.unchooseDoodad, add_mesh_beam_builder.addBeam, Wallfactory.add_mesh_wallb, add_mesh_triangles.MakeTriangle diff --git a/add_mesh_extra_objects/mesh_discombobulator.py b/add_mesh_extra_objects/mesh_discombobulator.py deleted file mode 100644 index f1d564ac..00000000 --- a/add_mesh_extra_objects/mesh_discombobulator.py +++ /dev/null @@ -1,870 +0,0 @@ -# GPL # Original Authors: Evan J. Rosky (syrux), Chichiri, Jace Priester # - -import bpy -import random -import math -from bpy.types import ( - Operator, - Menu, - ) -from mathutils import ( - Vector, - Quaternion, - ) -from bpy.props import ( - BoolProperty, - IntProperty, - FloatProperty, - StringProperty, - ) - -# ################### Globals #################### # - -doprots = True - -# Datas in which we will build the new discombobulated mesh -nPolygons = [] -nVerts = [] -Verts = [] -Polygons = [] -dVerts = [] -dPolygons = [] -i_prots = [] # index of the top polygons on which we"ll generate the doodads -i_dood_type = [] # type of doodad (given by index of the doodad obj) - - -# ############### Utility Functions ############### # - -def randnum(a, b): - return random.random() * (b - a) + a - - -def randVertex(a, b, c, d, Verts): - """Return a vector of a random vertex on a quad-polygon""" - i = random.randint(1, 2) - A, B, C, D = 0, 0, 0, 0 - if(a == 1): - A, B, C, D = a, b, c, d - else: - A, B, C, D = a, d, c, b - - i = randnum(0.1, 0.9) - - vecAB = Verts[B] - Verts[A] - E = Verts[A] + vecAB * i - - vecDC = Verts[C] - Verts[D] - F = Verts[D] + vecDC * i - - i = randnum(0.1, 0.9) - vecEF = F - E - - O = E + vecEF * i - return O - - -# ################## Protusions #################### # - -def fill_older_datas(verts, polygon): - """ Specifically coded to be called by the function addProtusionToPolygon, - its sets up a tuple which contains the vertices from the base and the top of the protusions. - """ - temp_vertices = [] - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - return temp_vertices - - -def extrude_top(temp_vertices, normal, height): - """ This function extrude the polygon composed of the four first members of the tuple - temp_vertices along the normal multiplied by the height of the extrusion. - """ - j = 0 - while j < 3: - temp_vertices[0][j] += normal[j] * height - temp_vertices[1][j] += normal[j] * height - temp_vertices[2][j] += normal[j] * height - temp_vertices[3][j] += normal[j] * height - j += 1 - - -def scale_top(temp_vertices, center, normal, height, scale_ratio): - """ This function scale the polygon composed of the four first members of the tuple temp_vertices. """ - vec1 = [0, 0, 0] - vec2 = [0, 0, 0] - vec3 = [0, 0, 0] - vec4 = [0, 0, 0] - - j = 0 - while j < 3: - center[j] += normal[j] * height - vec1[j] = temp_vertices[0][j] - center[j] - vec2[j] = temp_vertices[1][j] - center[j] - vec3[j] = temp_vertices[2][j] - center[j] - vec4[j] = temp_vertices[3][j] - center[j] - temp_vertices[0][j] = center[j] + vec1[j] * (1 - scale_ratio) - temp_vertices[1][j] = center[j] + vec2[j] * (1 - scale_ratio) - temp_vertices[2][j] = center[j] + vec3[j] * (1 - scale_ratio) - temp_vertices[3][j] = center[j] + vec4[j] * (1 - scale_ratio) - j += 1 - - -def add_prot_polygons(temp_vertices): - """ Specifically coded to be called by addProtusionToPolygon, this function - put the data from the generated protusion at the end the tuples Verts and Polygons, - which will later used to generate the final mesh. - """ - global Verts - global Polygons - global i_prots - - findex = len(Verts) - Verts += temp_vertices - - polygontop = [findex + 0, findex + 1, findex + 2, findex + 3] - polygon1 = [findex + 0, findex + 1, findex + 5, findex + 4] - polygon2 = [findex + 1, findex + 2, findex + 6, findex + 5] - polygon3 = [findex + 2, findex + 3, findex + 7, findex + 6] - polygon4 = [findex + 3, findex + 0, findex + 4, findex + 7] - - Polygons.append(polygontop) - i_prots.append(len(Polygons) - 1) - Polygons.append(polygon1) - Polygons.append(polygon2) - Polygons.append(polygon3) - Polygons.append(polygon4) - - -def addProtusionToPolygon(obpolygon, verts, minHeight, maxHeight, minTaper, maxTaper): - """Create a protusion from the polygon "obpolygon" of the original object and use - several values sent by the user. It calls in this order the following functions: - - fill_older_data; - - extrude_top; - - scale_top; - - add_prot_polygons; - """ - # some useful variables - polygon = obpolygon.vertices - - tVerts = list(fill_older_datas(verts, polygon)) # list of temp vertices - height = randnum(minHeight, maxHeight) # height of generated protusion - scale_ratio = randnum(minTaper, maxTaper) - - # extrude the top polygon - extrude_top(tVerts, obpolygon.normal, height) - # Now, we scale, the top polygon along its normal - scale_top(tVerts, GetPolyCentroid(obpolygon, verts), obpolygon.normal, height, scale_ratio) - # Finally, we add the protusions to the list of polygons - add_prot_polygons(tVerts) - - -# ################# Divide a polygon ############### # - -def divide_one(list_polygons, list_vertices, verts, polygon, findex): - """ called by divide_polygon, to generate a polygon from one polygon, maybe I could simplify this process """ - temp_vertices = [] - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - - list_vertices += temp_vertices - - list_polygons.append([findex + 0, findex + 1, findex + 2, findex + 3]) - - -def divide_two(list_polygons, list_vertices, verts, polygon, findex): - """ called by divide_polygon, to generate two polygons from one polygon and - add them to the list of polygons and vertices which form the discombobulated mesh - """ - temp_vertices = [] - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - temp_vertices.append((verts[polygon[0]] + verts[polygon[1]]) / 2) - temp_vertices.append((verts[polygon[2]] + verts[polygon[3]]) / 2) - - list_vertices += temp_vertices - - list_polygons.append([findex + 0, findex + 4, findex + 5, findex + 3]) - list_polygons.append([findex + 1, findex + 2, findex + 5, findex + 4]) - - -def divide_three(list_polygons, list_vertices, verts, polygon, findex, center): - """ called by divide_polygon, to generate three polygons from one polygon and - add them to the list of polygons and vertices which form the discombobulated mesh - """ - temp_vertices = [] - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - temp_vertices.append((verts[polygon[0]] + verts[polygon[1]]) / 2) - temp_vertices.append((verts[polygon[2]] + verts[polygon[3]]) / 2) - temp_vertices.append((verts[polygon[1]] + verts[polygon[2]]) / 2) - temp_vertices.append(center.copy()) - - list_vertices += temp_vertices - - list_polygons.append([findex + 0, findex + 4, findex + 5, findex + 3]) - list_polygons.append([findex + 1, findex + 6, findex + 7, findex + 4]) - list_polygons.append([findex + 6, findex + 2, findex + 5, findex + 7]) - - -def divide_four(list_polygons, list_vertices, verts, polygon, findex, center): - """ called by divide_polygon, to generate four polygons from one polygon and - add them to the list of polygons and vertices which form the discombobulated mesh - """ - temp_vertices = [] - temp_vertices.append(verts[polygon[0]].copy()) - temp_vertices.append(verts[polygon[1]].copy()) - temp_vertices.append(verts[polygon[2]].copy()) - temp_vertices.append(verts[polygon[3]].copy()) - temp_vertices.append((verts[polygon[0]] + verts[polygon[1]]) / 2) - temp_vertices.append((verts[polygon[2]] + verts[polygon[3]]) / 2) - temp_vertices.append((verts[polygon[1]] + verts[polygon[2]]) / 2) - temp_vertices.append(center.copy()) - temp_vertices.append((verts[polygon[0]] + verts[polygon[3]]) / 2) - temp_vertices.append(center.copy()) - - list_vertices += temp_vertices - - list_polygons.append([findex + 0, findex + 4, findex + 7, findex + 8]) - list_polygons.append([findex + 1, findex + 6, findex + 7, findex + 4]) - list_polygons.append([findex + 6, findex + 2, findex + 5, findex + 7]) - list_polygons.append([findex + 8, findex + 7, findex + 5, findex + 3]) - - -def dividepolygon(obpolygon, verts, number): - """Divide the poly into the wanted number of polygons""" - global nPolygons - global nVerts - - poly = obpolygon.vertices - - if(number == 1): - divide_one(nPolygons, nVerts, verts, poly, len(nVerts)) - elif(number == 2): - divide_two(nPolygons, nVerts, verts, poly, len(nVerts)) - elif(number == 3): - divide_three(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon, verts)) - elif(number == 4): - divide_four(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon, verts)) - - -# ################## Discombobulate ################ # - -def GetPolyCentroid(obpolygon, allvertcoords): - centroid = Vector((0, 0, 0)) - for vindex in obpolygon.vertices: - centroid += Vector(allvertcoords[vindex]) - centroid /= len(obpolygon.vertices) - return centroid - - -def division(obpolygons, verts, sf1, sf2, sf3, sf4): - """Function to divide each of the selected polygons""" - divide = [] - if (sf1): - divide.append(1) - if (sf2): - divide.append(2) - if (sf3): - divide.append(3) - if (sf4): - divide.append(4) - - for poly in obpolygons: - if(poly.select is True and len(poly.vertices) == 4): - a = random.randint(0, len(divide) - 1) - dividepolygon(poly, verts, divide[a]) - - -def protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper): - """function to generate the protusions""" - verts = [] - for vertex in obverts: - verts.append(vertex.co) - - for polygon in obpolygons: - if(polygon.select is True): - if(len(polygon.vertices) == 4): - addProtusionToPolygon(polygon, verts, minHeight, maxHeight, minTaper, maxTaper) - - -def test_v2_near_v1(v1, v2): - if (v1.x - 0.1 <= v2.x <= v1.x + 0.1 and - v1.y - 0.1 <= v2.y <= v1.y + 0.1 and - v1.z - 0.1 <= v2.z <= v1.z + 0.1): - return True - - return False - - -def angle_between_nor(nor_orig, nor_result): - angle = math.acos(nor_orig.dot(nor_result)) - axis = nor_orig.cross(nor_result).normalized() - - q = Quaternion() - q.x = axis.x * math.sin(angle / 2) - q.y = axis.y * math.sin(angle / 2) - q.z = axis.z * math.sin(angle / 2) - q.w = math.cos(angle / 2) - - return q - - -def doodads(object1, mesh1, dmin, dmax): - """function to generate the doodads""" - global dVerts - global dPolygons - i = 0 - # on parcoure cette boucle pour ajouter des doodads a toutes les polygons - # english translation: this loops adds doodads to all polygons - while(i < len(object1.data.polygons)): - if object1.data.polygons[i].select is False: - continue - - doods_nbr = random.randint(dmin, dmax) - j = 0 - - while(j <= doods_nbr): - origin_dood = randVertex(object1.data.polygons[i].vertices[0], object1.data.polygons[i].vertices[1], - object1.data.polygons[i].vertices[2], object1.data.polygons[i].vertices[3], Verts) - type_dood = random.randint(0, len(self.DISC_doodads) - 1) - polygons_add = [] - verts_add = [] - - # First we have to apply scaling and rotation to the mesh - bpy.ops.object.select_pattern(pattern=self.DISC_doodads[type_dood], extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[self.DISC_doodads[type_dood]] - bpy.ops.object.transform_apply(location=False, rotation=True, scale=True) - - for polygon in bpy.data.objects[self.DISC_doodads[type_dood]].data.polygons: - polygons_add.append(polygon.vertices) - for vertex in bpy.data.objects[self.DISC_doodads[type_dood]].data.vertices: - verts_add.append(vertex.co.copy()) - normal_original_polygon = object1.data.polygons[i].normal - - nor_def = Vector((0.0, 0.0, 1.0)) - qr = nor_def.rotation_difference(normal_original_polygon.normalized()) - - if(test_v2_near_v1(nor_def, -normal_original_polygon)): - qr = Quaternion((0.0, 0.0, 0.0, 0.0)) - - # qr = angle_between_nor(nor_def, normal_original_polygon) - for vertex in verts_add: - vertex.rotate(qr) - vertex += origin_dood - findex = len(dVerts) - - for polygon in polygons_add: - dPolygons.append([polygon[0] + findex, polygon[1] + findex, polygon[2] + findex, polygon[3] + findex]) - i_dood_type.append(bpy.data.objects[self.DISC_doodads[type_dood]].name) - - for vertex in verts_add: - dVerts.append(vertex) - j += 1 - i += 5 - - -def protusions_repeat(object1, mesh1, r_prot): - - for j in i_prots: - if j < len(object1.data.polygons): - object1.data.polygons[j].select = True - else: - print("Warning: hit end of polygons in object1") - - -# add material to discombobulated mesh -def setMatProt(discObj, origObj, sideProtMat, topProtMat): - # First we put the materials in their slots - bpy.ops.object.select_pattern(pattern=discObj.name, extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[discObj.name] - try: - origObj.material_slots[topProtMat] - origObj.material_slots[sideProtMat] - except: - return - - bpy.ops.object.material_slot_add() - bpy.ops.object.material_slot_add() - discObj.material_slots[0].material = origObj.material_slots[topProtMat].material - discObj.material_slots[1].material = origObj.material_slots[sideProtMat].material - - # Then we assign materials to protusions - for polygon in discObj.data.polygons: - if polygon.index in i_prots: - polygon.material_index = 0 - else: - polygon.material_index = 1 - - -def setMatDood(self, doodObj): - # First we add the materials slots - bpy.ops.object.select_pattern(pattern=doodObj.name, extend=False) - bpy.context.view_layer.objects.active = doodObj - for name in self.DISC_doodads: - try: - bpy.ops.object.material_slot_add() - doodObj.material_slots[-1].material = bpy.data.objects[name].material_slots[0].material - for polygon in doodObj.data.polygons: - if i_dood_type[polygon.index] == name: - polygon.material_index = len(doodObj.material_slots) - 1 - except: - print() - - -def clean_doodads(self): - current_doodads = list(self.DISC_doodads) - - for name in current_doodads: - if name not in bpy.data.objects: - self.DISC_doodads.remove(name) - - -def discombobulate(self, minHeight, maxHeight, minTaper, maxTaper, sf1, sf2, sf3, sf4, - dmin, dmax, r_prot, sideProtMat, topProtMat, isLast): - global doprots - global nVerts - global nPolygons - global Verts - global Polygons - global dVerts - global dPolygons - global i_prots - - bpy.ops.object.mode_set(mode="OBJECT") - - # start by cleaning up doodads that don"t exist anymore - clean_doodads(self) - - # Create the discombobulated mesh - mesh = bpy.data.meshes.new("tmp") - object = bpy.data.objects.new("tmp", mesh) - bpy.context.collection.objects.link(object) - - # init final verts and polygons tuple - nPolygons = [] - nVerts = [] - Polygons = [] - Verts = [] - dPolygons = [] - dVerts = [] - - origObj = bpy.context.active_object - - # There we collect the rotation, translation and scaling datas from the original mesh - to_translate = bpy.context.active_object.location - to_scale = bpy.context.active_object.scale - to_rotate = bpy.context.active_object.rotation_euler - - # First, we collect all the information we will need from the previous mesh - obverts = bpy.context.active_object.data.vertices - obpolygons = bpy.context.active_object.data.polygons - verts = [] - for vertex in obverts: - verts.append(vertex.co) - - division(obpolygons, verts, sf1, sf2, sf3, sf4) - - # Fill in the discombobulated mesh with the new polygons - mesh.from_pydata(nVerts, [], nPolygons) - mesh.update(calc_edges=True) - - # Reload the datas - bpy.ops.object.select_all(action="DESELECT") - bpy.ops.object.select_pattern(pattern=object.name, extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[object.name] - obverts = bpy.context.active_object.data.vertices - obpolygons = bpy.context.active_object.data.polygons - - protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper) - - # Fill in the discombobulated mesh with the new polygons - mesh1 = bpy.data.meshes.new("discombobulated_object") - object1 = bpy.data.objects.new("discombobulated_mesh", mesh1) - bpy.context.collection.objects.link(object1) - mesh1.from_pydata(Verts, [], Polygons) - mesh1.update(calc_edges=True) - - # Set the material"s of discombobulated object - setMatProt(object1, origObj, sideProtMat, topProtMat) - - bpy.ops.object.select_pattern(pattern=object1.name, extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[object1.name] - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.normals_make_consistent(inside=False) - bpy.ops.mesh.select_all(action="DESELECT") - bpy.ops.object.mode_set(mode="OBJECT") - - # if(bpy.context.scene.repeatprot): - protusions_repeat(object1, mesh1, r_prot) - - if(len(self.DISC_doodads) != 0 and self.dodoodads and isLast): - doodads(object1, mesh1, dmin, dmax) - mesh2 = bpy.data.meshes.new("dood_mesh") - object2 = bpy.data.objects.new("dood_obj", mesh2) - bpy.context.collection.objects.link(object2) - mesh2.from_pydata(dVerts, [], dPolygons) - mesh2.update(calc_edges=True) - setMatDood(self, object2) - object2.location = to_translate - object2.rotation_euler = to_rotate - object2.scale = to_scale - - bpy.ops.object.select_pattern(pattern=object.name, extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[object.name] - bpy.ops.object.delete() - - bpy.ops.object.select_pattern(pattern=object1.name, extend=False) - bpy.context.view_layer.objects.active = bpy.data.objects[object1.name] - bpy.context.scene.update() - - # translate, scale and rotate discombobulated results - object1.location = to_translate - object1.rotation_euler = to_rotate - object1.scale = to_scale - - # set all polys to selected. this allows recursive discombobulating. - for poly in mesh1.polygons: - poly.select = True - - -# ### Operators for selecting and deselecting an object as a doodad ### # - -class chooseDoodad(Operator): - bl_idname = "object.discombobulate_set_doodad" - bl_label = "Discombobulate set doodad object" - bl_description = ("Save the Active Object as Doodad \n" - "Object has to be quads only") - bl_options = {"REGISTER"} - - @classmethod - def poll(cls, context): - obj = bpy.context.active_object - if (obj is not None and obj.type == "MESH"): - mesh = obj.data - - for polygon in mesh.polygons: - is_ok = len(polygon.vertices) - if is_ok != 4: - return False - return True - - return False - - def execute(self, context): - obj_name = bpy.context.active_object.name - msg = "Object with this name already saved" - - if obj_name not in self.DISC_doodads: - self.DISC_doodads.append(obj_name) - msg = "Saved Doodad object: {}".format(obj_name) - - self.report({"INFO"}, message=msg) - - def invoke(self, context, event): - self.execute(context) - return {"FINISHED"} - - -class unchooseDoodad(Operator): - bl_idname = "object.discombobulate_unset_doodad" - bl_label = "Discombobulate unset doodad object" - bl_description = "Remove the saved Doodad Object(s)" - bl_options = {"REGISTER"} - - remove_all: bpy.props.BoolProperty( - name="Remove all Doodads", - default=False, - ) - - def execute(self, context): - msg = ("No doodads to remove") - doodadery = self.DISC_doodads - if len(doodadery) > 0: - if not self.remove_all: - name = bpy.context.active_object.name - if name in doodadery: - self.DISC_doodads.remove(name) - msg = ("Removed Doodad object: {}".format(name)) - else: - self.DISC_doodads[:] = [] - msg = "Removed all Doodads" - else: - msg = "No Doodads to Remove" - - self.report({"INFO"}, message=msg) - - def invoke(self, context, event): - self.execute(context) - return {"FINISHED"} - - -# ################## Interpolygon ################## # - -class discombobulator(Operator): - bl_idname = "object.discombobulate" - bl_label = "Discombobulate" - bl_description = "Apply" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - i = 0 - while i < self.repeatprot: - isLast = False - if i == self.repeatprot - 1: - isLast = True - discombobulate(self.minHeight, self.maxHeight, self.minTaper, self.maxTaper, self.subpolygon1, - self.subpolygon2, self.subpolygon3, self.subpolygon4, self.mindoodads, self.maxdoodads, - self.repeatprot, self.sideProtMat, self.topProtMat, isLast) - i += 1 - return {"FINISHED"} - - -class discombobulator_dodads_list(Menu): - bl_idname = "OBJECT_MT_discombobulator_dodad_list" - bl_label = "List of saved Doodads" - bl_description = "List of the saved Doodad Object Names" - bl_options = {"REGISTER"} - - def draw(self, context): - layout = self.layout - - doodle = len(self.DISC_doodads) - layout.label(text="Saved doodads : {}".format(doodle)) - layout.separator() - if doodle > 0: - for name in self.DISC_doodads: - layout.label(text=name) - - -class discombob_help(Menu): - bl_idname = "HELP_MT_discombobulator" - bl_label = "Usage Information" - bl_description = "Help" - bl_options = {"REGISTER"} - - def draw(self, context): - layout = self.layout - layout.label(text="Usage Information:", icon="INFO") - layout.separator() - layout.label(text="Quads only, not Triangles or Ngons", icon="ERROR") - layout.label(text="Works only with Mesh object that have faces") - layout.separator() - layout.label(text="Select a face or faces") - layout.label(text="Press Discombobulate to create greebles") - layout.label(text="In object mode, still needs a selection in Edit Mode") - layout.separator() - layout.label(text="Doodads - additional objects layered on the mesh surface") - layout.label("(Similar to dupliverts - but as one separate object)") - layout.separator() - layout.label(text="Limitations:", icon="MOD_EXPLODE") - layout.label(text="Be careful with the repeat protusions setting") - layout.label("(Runs reqursively)") - layout.label(text="If possible, avoid using on a high polycount base mesh") - layout.label("(It can run out of memory and take a long time to compute)") - -class VIEW3D_OT_tools_discombobulate(Operator): - bl_idname = "discombobulate.ops" - bl_label = "Discombobulator" - bl_description = ("Easily add sci-fi details to a surface \n" - "Needs an existing active Mesh with Faces") - bl_options = {"REGISTER"} - - executing = False - - DISC_doodads = [] - # Protusions Buttons: - repeatprot: IntProperty( - name="Repeat protusions", - description=("Make several layers of protusion \n" - "Use carefully, runs recursively the discombulator"), - default=1, min=1, max=4 # set to 4 because it's 2**n reqursive - ) - doprots: BoolProperty( - name="Make protusions", - description="Check if we want to add protusions to the mesh", - default=True - ) - subpolygon1: BoolProperty( - name="1", - default=True - ) - subpolygon2: BoolProperty( - name="2", - default=True - ) - subpolygon3: BoolProperty( - name="3", - default=True - ) - subpolygon4: BoolProperty( - name="4", - default=True - ) - polygonschangedpercent: FloatProperty( - name="Polygon %", - description="Percentage of changed polygons", - default=1.0 - ) - minHeight: FloatProperty( - name="Min height", - description="Minimal height of the protusions", - default=0.2 - ) - maxHeight: FloatProperty( - name="Max height", - description="Maximal height of the protusions", - default=0.4 - ) - minTaper: FloatProperty( - name="Min taper", - description="Minimal height of the protusions", - default=0.15, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) - maxTaper: FloatProperty( - name="Max taper", - description="Maximal height of the protusions", - default=0.35, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) - # Doodads buttons: - dodoodads: BoolProperty( - name="Make doodads", - description="Check if we want to generate doodads", - default=False - ) - mindoodads: IntProperty( - name="Minimum doodads number", - description="Ask for the minimum number of doodads to generate per polygon", - default=1, min=0, max=50 - ) - maxdoodads: IntProperty( - name="Maximum doodads number", - description="Ask for the maximum number of doodads to generate per polygon", - default=6, min=1, max=50 - ) - doodMinScale: FloatProperty( - name="Scale min", description="Minimum scaling of doodad", - default=0.5, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) - doodMaxScale: FloatProperty( - name="Scale max", - description="Maximum scaling of doodad", - default=1.0, min=0.0, max=1.0, - subtype='PERCENTAGE' - ) - # Materials buttons: - sideProtMat: IntProperty( - name="Side's prot mat", - description="Material of protusion's sides", - default=0, min=0 - ) - topProtMat: IntProperty( - name="Prot's top mat", - description="Material of protusion's top", - default=0, min=0 - ) - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == "MESH") - - def draw(self, context): - layout = self.layout - - row = layout.row() - row.menu("HELP_MT_discombobulator", icon="INFO") - box = layout.box() - box.label(text="Protusions settings") - row = box.row() - row.prop(self, "doprots") - row = box.row() - row.prop(self, "minHeight") - row = box.row() - row.prop(self, "maxHeight") - row = box.row() - row.prop(self, "minTaper") - row = box.row() - row.prop(self, "maxTaper") - row = box.row() - col1 = row.column(align=True) - col1.prop(self, "subpolygon1") - col2 = row.column(align=True) - col2.prop(self, "subpolygon2") - col3 = row.column(align=True) - col3.prop(self, "subpolygon3") - col4 = row.column(align=True) - col4.prop(self, "subpolygon4") - row = box.row() - row.prop(self, "repeatprot") - box = layout.box() - box.label(text="Doodads settings") - row = box.row() - is_doodad = self.dodoodads - row.prop(self, "dodoodads") - - row = box.row() - row.enabled = is_doodad - row.prop(self, "mindoodads") - row = box.row() - row.enabled = is_doodad - row.prop(self, "maxdoodads") - row = box.row() - row.enabled = is_doodad - oper = row.operator("object.discombobulate_set_doodad", text="Pick doodad") - - row = box.row() - splits = row.split(factor = 0.5) - splits.enabled = is_doodad - splits.operator("object.discombobulate_unset_doodad", - text="Remove active doodad").remove_all = False - splits.operator("object.discombobulate_unset_doodad", - text="Remove all doodads").remove_all = True - - col = box.column(align=True) - doodle = len(self.DISC_doodads) - - col.enabled = (True if doodle > 0 else False) - col.menu("OBJECT_MT_discombobulator_dodad_list", - text="List of saved Doodads ({})".format(doodle)) - - box = layout.box() - box.label(text="Materials settings") - row = box.row() - row.prop(self, "topProtMat") - row = box.row() - row.prop(self, "sideProtMat") - - def invoke(self, context, event): - return context.window_manager.invoke_props_dialog(self, width=300) - - def check(self, context): - return not self.executing - - def execute(self, context): - self.executing = True - i = 0 - while i < self.repeatprot: - isLast = False - if i == self.repeatprot - 1: - isLast = True - discombobulate(self, self.minHeight, self.maxHeight, self.minTaper, self.maxTaper, self.subpolygon1, - self.subpolygon2, self.subpolygon3, self.subpolygon4, self.mindoodads, self.maxdoodads, - self.repeatprot, self.sideProtMat, self.topProtMat, isLast) - i += 1 - return {"FINISHED"} - #bpy.ops.object.discombobulate("INVOKE_DEFAULT") -- cgit v1.2.3