예제 #1
0
def test_add_axe():
    g = MTG()
    labels = g.property('label')
    p1 = add_plant(g)
    p2 = add_plant(g)
    vid_axe = add_axe(g, 'T0')
    assert g.complex(vid_axe) == p1
    assert labels[g.parent(vid_axe)] == 'MS'
    vid_axe = add_axe(g, 'T1.3', plant_number=2)
    assert g.complex(vid_axe) == p2
    assert labels[g.parent(vid_axe)] == 'T1'
    vid_metamer0 = g.component_roots_at_scale(vid_axe, 3)[0]
    assert labels[g.parent(vid_metamer0)] == "metamer3"
예제 #2
0
파일: mtg.py 프로젝트: imane-aanna/adel
def read_lsystem_string( string,
                         symbol_at_scale,
                         functional_symbol={},
                         mtg=None ):
    """Read a string generated by a lsystem.

    :Parameters:

    - `string`: The lsystem string representing the axial tree.
    - `symbol_at_scale`: A dict containing the scale for each symbol name.

    :Optional parameters:

    - `functional_symbol`: A dict containing a function for specific symbols.
        The args of the function have to be coherent with those in the string.
        The return type of the functions have to be a dictionary of properties: dict(name, value)

    :Return:

        MTG object
    """

    import openalea.plantgl.all as pgl
    s = string

    def transform(turtle, mesh):
        x = turtle.getUp()
        z = turtle.getHeading()

        bo = pgl.BaseOrientation(x, z^x)
        matrix = pgl.Transform4(bo.getMatrix())
        matrix.translate(turtle.getPosition())
        mesh = mesh.transform(matrix)
        return mesh
        

    # 1. Create the mtg structure.
    if mtg is None:
        mtg = MTG()

    # 2. add some properties to the MTG
    mtg.add_property('index')
    mtg.add_property('can_label')
    mtg.add_property('geometry')
    mtg.add_property('tissue_type')

    vid = mtg.root # vid of the support tree, i.e. at the finest scale
    current_vertex = mtg.root
    branching_stack = []

    pending_edge = '' # edge type for the next edge to be created
    scale = 0

    lsys_symbols = ['[', ']', '/', '+', '^', 'f']
    modules = symbol_at_scale.keys()
    symbols = lsys_symbols + modules

    index = dict(zip(symbol_at_scale.keys(), [0]*len(symbol_at_scale)))

    is_ramif = False 

    # 2. Create a PlantGL Turtle...
    turtle = pgl.Turtle()

    max_scale = max(symbol_at_scale.values())

    for edge_type in symbols:
        if edge_type != 'f':
            s = s.replace(edge_type, '\n%s'%edge_type)
        else:
            s = s.replace('f(', '\nf(')
    l = s.split()

    try:
        plant_name = [s for s in symbol_at_scale.keys() if 'plant' in s.lower()][0]
    except:
        ValueError("""Incorrect plant name (should be plant)""")

    for node in l:
        # Check if node is a module

        tag = node[0]

        if tag == '[':
            branching_stack.append(vid)
            turtle.push()
            is_ramif = True
        elif tag == ']':
            vid = branching_stack.pop()
            current_vertex = vid
            scale = mtg.scale(vid)
            turtle.pop()
            is_ramif = False
        elif tag == '/':
            args = get_args(node[1:])
            if args:
                angle = get_float(args[1:-1])
                turtle.rollR(angle)
            else:
                turtle.rollR()
        elif tag == '+':
            args = get_args(node[1:])
            if args:
                angle = get_float(args[1:-1])
                turtle.left(angle)
            else:
                turtle.left()
        elif tag == '^':
            args = get_args(node[1:])
            if args:
                angle = get_float(args[1:-1])
                turtle.up(angle)
            else:
                turtle.up()
        elif tag == 'f' and node[1] == '(':
            args = get_args(node[1:])
            if args:
                length = get_float(args[1:-1])
                if length > 0:
                    turtle.f(length)
            else:
                turtle.f()
        else:
            # add new modules to the mtg (i.e. add nodes)
            name = get_name(node)
            if name not in modules:
                print 'Unknow element %s'% name
                continue
            
            module_scale = symbol_at_scale[name]
            if is_ramif:
                edge_type = '+'
            else:
                edge_type = '<'

            log(node, module_scale, edge_type )
            
            if module_scale == scale:
                if mtg.scale(vid) == scale:
                    vid = mtg.add_child(vid, edge_type=edge_type, label=name)
                    current_vertex = vid
                    pending_edge = ''

                    log('','Cas 1.1', scale, 
                        'mtg.scale(vid)', mtg.scale(vid), 
                        'generated vertex', vid)

                    assert mtg.scale(vid) == module_scale
                else:
                    # add the edge to the current vertex
                    current_vertex = mtg.add_child(current_vertex, 
                                                   edge_type=edge_type, 
                                                   label=name)
                    log('', 'Cas 1.2', scale, 
                        'mtg.scale(vid)', mtg.scale(vid), 
                        'generated vertex', current_vertex)
                    assert mtg.scale(current_vertex) == module_scale
                is_ramif = False
            elif module_scale > scale:
                log('', 'Cas 2', scale, 'mtg.scale(vid)', mtg.scale(vid))

                old_current_vertex = current_vertex
                while module_scale > scale:
                    if mtg.scale(vid) == scale:
                        assert vid == current_vertex
                        vid = mtg.add_component(vid)
                        current_vertex = vid
                        log('', '', 'Cas 2.1', scale, 'generate new component', current_vertex)
                        scale += 1
                        if module_scale == scale:
                            assert mtg.scale(current_vertex) == module_scale
                            mtg.property('label')[current_vertex] = name
                            break
                    else:
                        scale += 1
                        current_vertex = mtg.add_component(current_vertex)
                else:
                    log(node, 'add_child(%d, child=%d)'%(old_current_vertex, current_vertex))
                    mtg.property('label')[current_vertex] = name
                    if mtg.scale(vid) == scale:
                        vid = mtg.add_child(vid, child=current_vertex, edge_type=edge_type)
                        is_ramif = False
            else:
                assert module_scale < scale
                while module_scale < scale:
                    scale -= 1
                    current_vertex = mtg.complex(current_vertex)
                else:
                    current_vertex = mtg.add_child(current_vertex, edge_type=edge_type, label=name)
                    assert mtg.scale(current_vertex) == module_scale
        
            # MANAGE the properties, the geometry and the indices!!!
            index[name] += 1
            if name == plant_name:
                for k in index.keys():
                    if k != name:
                        index[k] = 0

            mtg.property('index')[current_vertex] = index[name]
            if name in functional_symbol:
                features = eval(node, functional_symbol)
                geom = features.get('geometry')
                canlabel = features.get('label')
                ttype = features.get('tissue_type')
                
                if geom:
                    # get the transformation from the turtle
                    geom = transform(turtle, geom)
                    mtg.property('geometry')[current_vertex] = geom

                    if name == 'StemElement':
                        # parse args to know how the turtle has to move .
                        args = get_args(node)[1:-1]
                        list_args= args.split(',')
                        length = float(list_args[1]) # 2nd arg
                        if length > 0:
                            turtle.f(length)

                if canlabel:
                    canlabel.elt_id = index[name]
                    plant_id = mtg.complex_at_scale(current_vertex, scale=1)
                    canlabel.plant_id = mtg.property('index')[plant_id]
                    mtg.property('can_label')[current_vertex] = canlabel

                if ttype:
                    mtg.property('tissue_type')[current_vertex] = ttype
                    
    mtg = fat_mtg(mtg)
    return mtg