Пример #1
0
def fromBlenderToGeneticInstance(tree_creator, genetic_instance):
    """ Writes the current Tree Creator parameters to the GeneticInstance """

    # LSystem part
    genetic_instance.lsystem.clear()
    genetic_instance.lsystem.setIterations(tree_creator.iterations)

    # NOTE: it is important that the defines are created before the productions or the axioms, so they can be used by them
    for (def_name,def_value) in iterateOverDefines(tree_creator):
        if not getattr(tree_creator,def_name) is "":
            genetic_instance.lsystem.addGlobalDefine(getattr(tree_creator,def_name),getattr(tree_creator,def_value))

    genetic_instance.lsystem.setAxiomFromString(tree_creator.axiom)

    for (namep,namec,names) in iterateOverProductions(tree_creator):
        if not getattr(tree_creator,namep) is "" and not getattr(tree_creator,namep) is "":
            rule = getattr(tree_creator,namep)+":"+getattr(tree_creator,namec)+"->"+getattr(tree_creator,names)
            genetic_instance.lsystem.addProductionFromString(rule)

    # Turtle parameters part
    tp = genetic_instance.turtleParameters
    tp.branch_radius = tree_creator.defaultRadius
    tp.tropism_susceptibility = tree_creator.tropism_susceptibility
    tp.use_canopy = tree_creator.canopy
    tp.details_scale = tree_creator.details_scale
    tp.trunk_material_choice = DetailsHandler.indexOfMaterial(tree_creator.trunk_material)
    tp.leaf_material_choice = DetailsHandler.indexOfMaterial(tree_creator.leaf_material)
    tp.leaf_choice =  DetailsHandler.indexOfLeafModel(tree_creator.leaf_object_name)
    tp.bulb_choice =  DetailsHandler.indexOfBulbModel(tree_creator.bulb_object_name)
    tp.flower_choice =  DetailsHandler.indexOfFlowerModel(tree_creator.flower_object_name)
    tp.fruit_choice =  DetailsHandler.indexOfFruitModel(tree_creator.fruit_object_name)
Пример #2
0
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)
Пример #3
0
    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

                """