def fromGeneticInstanceToBlender(tree_creator, context, genetic_instance): """ Reads all the current Tree Creator parameters from the LSystem instance """ # LSystem part tree_creator.iterations = genetic_instance.lsystem.niterations tree_creator.nproductions = len(genetic_instance.lsystem.productions) tree_creator.ndefines = len(genetic_instance.lsystem.globalDefines) tree_creator.axiom = str(genetic_instance.lsystem.axiom) updateDefinesGui(tree_creator,context) updateProductionsGui(tree_creator,context) i = 0 keys = list(genetic_instance.lsystem.globalDefines.keys()) values = list(genetic_instance.lsystem.globalDefines.values()) for (def_name,def_value) in iterateOverDefines(tree_creator): # TODO: CHECK THIS!!!! THEY ARE IN A DICTIONARY! NOT ORDERED! setattr(tree_creator,def_name,str(keys[i])) setattr(tree_creator,def_value,values[i]) i+=1 i = 0 productions = genetic_instance.lsystem.productions for (namep,namec,names) in iterateOverProductions(tree_creator): setattr(tree_creator,namep,str(productions[i].predecessor)) setattr(tree_creator,namec,str(productions[i].condition)) setattr(tree_creator,names,str(productions[i].successor)) i+=1 # Turtle parameters part tp = genetic_instance.turtleParameters tree_creator.defaultRadius = tp.branch_radius tree_creator.tropism_susceptibility = tp.tropism_susceptibility tree_creator.canopy = tp.use_canopy tree_creator.details_scale = tp.details_scale #print(tp.trunk_material_choice) tree_creator.trunk_material = DetailsHandler.nameOfMaterial(tp.trunk_material_choice) #print(tree_creator.trunk_material) tree_creator.leaf_material = DetailsHandler.nameOfMaterial(tp.leaf_material_choice) tree_creator.leaf_object_name = DetailsHandler.nameOfLeafModel(tp.leaf_choice) tree_creator.bulb_object_name = DetailsHandler.nameOfBulbModel(tp.bulb_choice) tree_creator.flower_object_name = DetailsHandler.nameOfFlowerModel(tp.flower_choice) tree_creator.fruit_object_name = DetailsHandler.nameOfFruitModel(tp.fruit_choice)
def drawMesh(self, context, turtleResult, origin_offset = (0,0,0), suffix = "", randomSeed = None, multipleInstances = False, overridenContext = None): if overridenContext is None: scene = context.scene else: scene = overridenContext['scene'] verts = turtleResult.verts edges = turtleResult.edges radii = turtleResult.radii leaves = turtleResult.leaves bulbs = turtleResult.bulbs flowers = turtleResult.flowers fruits = turtleResult.fruits instance_index = turtleResult.instance_index idd = turtleResult.idd if randomSeed: self.rnd.seed(randomSeed+instance_index) if len(verts) == 0: if overridenContext is None: context.area.header_text_set("WARNING: Mesh drawing aborted due no vertices supplied.") else: context['area'].header_text_set("WARNING: Mesh drawing aborted due no vertices supplied.") print("WARNING: Mesh drawing aborted due no vertices supplied.") return if self.limitDrawing and len(verts) > MAX_DRAWABLE_VERTS: if overridenContext is None: context.area.header_text_set("WARNING: Mesh drawing aborted due to huge number of vertices: " + str(len(verts))) else: context['area'].header_text_set("WARNING: Mesh drawing aborted due to huge number of vertices: " + str(len(verts))) print("WARNING: Mesh drawing aborted due to huge number of vertices: " + str(len(verts))) return if suffix == "": name = str(idd) + "_" + str(instance_index) else: name = suffix if multipleInstances: origin_offset = (origin_offset[0]-((int)(instance_index/5))*1+self.rnd.uniform(-0.5,0.5)*1.0, origin_offset[1]+(instance_index%5)*1+self.rnd.uniform(-0.5,0.5)*1.0, origin_offset[2]) me = bpy.data.meshes.new('PlantFormMesh' + name) ob = bpy.data.objects.new("PlantForm" + name, me) me.from_pydata(verts, edges, []) me.update() ob.location = scene.cursor_location + Vector(origin_offset) scene.objects.link(ob) # Add details #print("Turtle renderer: Show detaiils") if self.showLeaves: if self.randomize_details: leaf_name = DetailsHandler.LEAF_NAMES[random.randint(0,len(DetailsHandler.LEAF_NAMES)-1)] else: leaf_name = DetailsHandler.LEAF_NAMES[self.leaf_detail_index] self.addDetails("leaf",leaves,leaf_name,self.details_scale,ob) if self.randomize_details: bulb_name = DetailsHandler.BULB_NAMES[random.randint(0,len(DetailsHandler.BULB_NAMES)-1)] else: bulb_name = DetailsHandler.BULB_NAMES[self.bulb_detail_index] self.addDetails("bulb",bulbs,bulb_name,self.details_scale,ob) if self.randomize_details: flower_name = DetailsHandler.FLOWER_NAMES[random.randint(0,len(DetailsHandler.FLOWER_NAMES)-1)] else: flower_name = DetailsHandler.FLOWER_NAMES[self.flower_detail_index] self.addDetails("flower",flowers,flower_name,self.details_scale,ob) if self.randomize_details: fruit_name = DetailsHandler.FRUIT_NAMES[random.randint(0,len(DetailsHandler.FRUIT_NAMES)-1)] else: fruit_name = DetailsHandler.FRUIT_NAMES[self.fruit_detail_index] self.addDetails("fruit",fruits,fruit_name,self.details_scale,ob) # Metaballs around leaves to simulate canopy #print("Turtle renderer: Show canopy") if self.showCanopy: if len(leaves) > 0: mballGenerator = MetaballGenerator() for leafQuad in leaves: pos = self.toBlenderVector(leafQuad.pos) mball = mballGenerator.addMetaball() mball.co = pos mball.radius = self.metaBallRadius mballGenerator.mballCurrentObject.parent = ob # The current mball element's object is in this variable scene.objects.active = mballGenerator.mballCurrentObject # Select the object as active scene.objects.active.select = True # Must force selection bpy.ops.object.convert(target='MESH', keep_original=False) if len(bpy.context.object.data.vertices) > 0: # Set the foliage material foliage_material_name = "" if foliage_material_name != "": mat = bpy.data.materials[foliage_material_name] scene.objects.active.data.materials.append(mat) # We also unwrap the resulting mesh for texture mapping bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.faces_shade_flat() # Flat shaded bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.unwrap() bpy.ops.object.mode_set(mode='OBJECT') if self.showSkin: if self.limitDrawing and len(verts) > MAX_SKINNABLE_VERTS: if overridenContext is None: context.area.header_text_set("WARNING: Mesh skinning blocked due to large number of vertices: " + str(len(verts))) else: context['area'].header_text_set("WARNING: Mesh skinning blocked due to large number of vertices: " + str(len(verts))) print("WARNING: Mesh skinning blocked due to large number of vertices: " + str(len(verts))) return else: if self.verbose: print("Turtle renderer: Applying skin modifier") current_modifier_index = 0 # Apply a skin modifier # Note that this will create A LOT of vertices (simplification will help later) scene.objects.active = ob # Select the object as active bpy.ops.object.modifier_add(type='SKIN') scene.objects.active.modifiers[current_modifier_index].use_smooth_shade=True current_modifier_index+=1 verts = scene.objects.active.data.vertices skinverts = scene.objects.active.data.skin_vertices[0].data # Set the radius of the branches if self.verbose: print("Turtle renderer: Setting radius") for i,v in enumerate(skinverts): r = radii[i] """ height = verts[i].co[2] if height > 0: r = 1.0/height else: r = 1.0 if (r < 0.1): r = 0.1 if (r > 1.0): r = 1.0 #print(r) """ v.radius = [r* 0.01, r* 0.01] # r = 1 -> small radius if not self.fastSkin: if self.verbose: print("Turtle renderer: Making it nicer") # Additional modifications to make the mesh nicer # Add a SubSurf modifier to obtain a smoother mesh bpy.ops.object.modifier_add(type='SUBSURF') scene.objects.active.modifiers[current_modifier_index].levels = 1 current_modifier_index+=1 # Edge Split makes for a more cartoony appearance bpy.ops.object.modifier_add(type='EDGE_SPLIT') current_modifier_index+=1 #bpy.ops.object.modifier_apply(modifier="EdgeSplit"); current_modifier_index-=1 # Simplification #if not self.fastSkin: if self.simplify: if self.verbose: print("Turtle renderer: Simplification") bpy.ops.object.modifier_add(type='DECIMATE') scene.objects.active.modifiers[current_modifier_index].ratio=0.1 scene.objects.active.modifiers[current_modifier_index].decimate_type = 'DISSOLVE' # We use planar decimation, more cartoonish scene.objects.active.modifiers[current_modifier_index].angle_limit = 5.0/180.0*3.14159 # 5 degrees is enough current_modifier_index+=1 #bpy.ops.object.modifier_apply(modifier="Decimate"); current_modifier_index-=1 # We will apply modifier to obtain the final mesh. self.applyModifiers = True if self.applyModifiers: if self.verbose: print("Turtle renderer: Apply modifiers") bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.modifier_apply(modifier="Skin") if not self.fastSkin: bpy.ops.object.modifier_apply(modifier="Subsurf") if not self.fastSkin: bpy.ops.object.modifier_apply(modifier="EdgeSplit") if self.simplify: bpy.ops.object.modifier_apply(modifier="Decimate") if self.simplify: # We can also simplify further by removing doubles bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all() bpy.ops.mesh.remove_doubles() # We use the default threshold (0.0001). We can put here: threshold=0.01 if we prefer. bpy.ops.mesh.normals_make_consistent(inside=False) bpy.ops.object.mode_set(mode='OBJECT') if self.verbose: print("Turtle renderer: Trunk material") # Set the trunk material trunk_material_name = DetailsHandler.nameOfMaterial(self.trunk_material_index) mat = bpy.data.materials[trunk_material_name] scene.objects.active.data.materials.append(mat) scene.objects.active = scene.objects.active #mballGenerator.mballCurrentObject # Select the object as active scene.objects.active.select = True # Must force selection """