Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PROFESOR GUIA:
MARÍA CECILIA BASTARRICA PIÑEYRO
MIEMBROS DE LA COMISIÓN:
NANCY VIOLA HITSCHFELD KAHLER
MARÍA CECILIA RIVARA ZÚÑIGA
SANTIAGO DE CHILE
MAYO, 2012
Resumen
En el actual mercado globalizado las grandes compañías de desarrollo de software están
entregando a sus clientes distinta variedad de productos y con cada vez menos distancia
de tiempo entre un producto y otro. Esto se debe a gran parte en la reutilización de sus
productos para la generación de los nuevos. Esto responde a una creciente demanda por
la variedad en los productos o su customización.
Para llevar esto a cabo, las empresas de tecnología desarrollan lo que se conoce como
“familia de productos” que se generan a partir de un paradigma de desarrollo conocido
como SPL o línea de productos de software. Sus ventajas son la de tener un bajo Time to
Market, además de disminuir los costos de producción y mejorar la mantenibilidad de los
productos, entre muchas otras.
Se pretende aplicar este paradigma en base a dos aplicaciones que actualmente
comparten gran parte de su implementación. Estas aplicaciones son “Face animator” y
“Tree grow simulator”, las cuales básicamente son aplicaciones que permiten visualizar
mallas geométricas y manipularlas según distintos parámetros y algoritmos. “Face
animator” es una aplicación pensada en la manipulación de mallas geométricas que
modelan rostros humanos, permitiendo el movimiento de distintas partes del rostro. Por
otro lado la aplicación “Tree grow simulator” está pensada para la manipulación de mallas
geométricas que modelan troncos de árboles, permitiendo crear una animación para ver
su crecimiento mediante la distribución de una hormona.
Para lograr generar una familia de productos en base a estas dos aplicaciones, se tuvo que
estudiar el código fuente de ambos y hacer correcciones en el código fuente de una de
estas, para poder hacer una aplicación genérica. Para esto se identificaron los puntos en
común (commonalities) y las distintas opciones para una funcionalidad (puntos de
variabilidad). Para esto se utilizó una herramienta web llamada “S.P.L.O.T.”, que permite
generar un modelo de características o “features” y aplicar reglas lógicas entre las
distintas opciones para mantener la consistencia de los productos. Esta herramienta
también cuenta con un catalogo o configurador de productos, donde se permite elegir las
opciones (variantes) de los puntos de variabilidad, así generando una configuración para
una aplicación especifica.
El paso siguiente fue la creación de una nueva aplicación, que permite seleccionar las
variantes para los puntos variables pre definidos. Luego esta herramienta compila el
código fuente y genera un archivo de configuración y un ejecutable, que es la nueva
aplicación configurada con las opciones seleccionadas.
Dentro de las dificultades encontradas, el actual diseño no permite la separación de
componentes de manera de que estos sean independientes, importante al momento de
compilar, por lo que se propone como un futuro desarrollo la restructuración en las clases
de la interfaz grafica y donde se implementan los distintos puntos de variabilidad.
También se puede agregar funcionalidades como lectura de un archivo XML directamente
desde la herramienta “S.P.L.O.T.” cargando así automáticamente la selección de opciones.
También se hace necesario agregar funcionalidades que existen en la aplicación “Tree
grow simulator” y no se encuentran implementados en el código fuente de “Face
Animator”.
I
Agradecimientos
Quería partir agradeciendo a mi madre y abuela, quienes pusieron todo de sí para que yo
pudiese terminar este largo proceso. Son a ellas a quien más debo, tanto en lo material
como en lo emocional, ya que siempre tuvieron la mayor confianza en mis capacidades y
compartían mi sueño de poder lograr esta tarea. También quiero agradecer a mi novia por
su paciencia y palabras de aliento cuando lo necesitaba.
También quiero reconocer la ayuda de mis amigos y familiares por comprender el escaso
tiempo del que disponía. Termino estas palabras de agradecimiento, reconociendo a mis
compañeros de carrera de quienes aprendí mucho.
Gonzalo Urroz
Mayo 2012.
II
Índice General
Capitulo 1 ............................................................................................................................................ 1
1. Introducción .............................................................................................................................. 1
1.1 Antecedentes generales ...................................................................................................... 1
Capitulo 2 ............................................................................................................................................ 5
2. Antecedentes ............................................................................................................................ 5
2.1 Línea de producto de software............................................................................................ 5
2.1.1. Framework............................................................................................................7
2.4. FaceAnimator..................................................................................................................... 14
Capitulo 3 .......................................................................................................................................... 16
3. Diseño e Implementación ....................................................................................................... 16
3.1 Actualización librerías ........................................................................................................ 16
Capitulo 4 .......................................................................................................................................... 28
4. Resultados ............................................................................................................................... 28
4.1 Herramienta de visualización de Variabilidad ................................................................... 28
III
Capitulo 5 .......................................................................................................................................... 41
5. Conclusiones y trabajo futuro ................................................................................................. 41
Referencias ........................................................................................................................................ 43
Apéndices .......................................................................................................................................... 44
IV
Índice de Figuras
Figura 4.1.1: Análisis de las funcionalidades y del modelo con [S.P.L.O.T.] ..................................... 29
Figura 4.2.3: Versión A, solo se permite abrir archivos de mallas geométricas ............................... 35
Figura 4.2.4: Versión A, solo se permiten los formatos wfm y wrl ................................................... 36
Figura 4.2.5: Versión B, se permiten los formatos wrl, wfm off y txt. .............................................. 36
Figura 4.2.6: Versión B, se aplica registration method al momento de abrir una malla geométrica 37
Figura 4.2.7: Versión A, solo se presenta el algoritmo de refinamiento “Delunay Longest Edge
Bisection” .......................................................................................................................................... 37
V
Figura 4.2.9: Versión A, solo se presenta el algoritmo de des refinamiento “Largo Arcos Mínimos”
........................................................................................................................................................... 38
Figura 4.2.10: Versión B, solo se presenta el algoritmo de des refinamiento “Área Cara Minima”. 39
VI
Capitulo 1
1. Introducción
En el siguiente capítulo se explica la problemática que el presente trabajo de memoria
pretende resolver. Se presenta una visión general de distintos temas para contextualizar al
lector, para luego definir los objetivos que se pretenderán lograr.
El Instituto de Ingeniería de Software (SEI) define de la siguiente manera una SPL: “Es un
conjunto de sistemas de software compartiendo características comunes y administradas
que satisface las necesidades específicas de un segmento de mercado particular o misión
y que son desarrollados de forma prescrita a partir de un conjunto común de elementos
clave”. Como lo indica la definición, una SPL consiste en un conjunto de elementos clave
para producir sistemas de software que comparten características comunes (llamadas
similitudes o commonalities), pero al mismo tiempo mantienen características propias
(llamada variabilidad) [Montilva2006].
1
otro lado de la línea sin tener que enviar todo el video, o bien para tener un avatar 1 más
realista de un usuario en alguna determinada aplicación. Otra representación posible es el
modelamiento de superficies de troncos de árboles [TreeGrowSimulator], mediante
mallas cilíndricas, esto con el fin de poder simular y estudiar el comportamiento a través
del tiempo de la superficie en función de la concentración de una hormona, la cual se
calcula a través de una ecuación que modela su comportamiento.
1.2 Motivación
La animación de rostros humanos es un tema ampliamente estudiado y de importancia en
distintas áreas de la ciencia, tales como biología y computación gráfica. Diversos trabajos
se han realizado en esta área, en los cuales se aborda el problema desde distintas
perspectivas y dando distintas soluciones según el resultado que se necesita. Esto se debe
a que existen distintos modelos de entendimiento del rostro humano y por ende distintas
maneras de simular su comportamiento. Es por esto que estos modelos de entendimiento
irán evolucionando durante el tiempo, dando por resultado el refinamiento de las técnicas
de simulación, así como también la creación de nuevas técnicas.
Para poder lograr esto, existe la posibilidad de desarrollar un sistema que contenga todas
las técnicas posibles, pero esto se hace infactible debido a que la cantidad de técnicas va
creciendo año a año. Además el producto nunca alcanzaría la etapa de producción ya que
los tiempos de desarrollo y mantenimiento evolutivo para agregar las nuevas técnicas
aumentarían considerablemente.
Además se agrega la complejidad de que el actual sistema también se puede utilizar para
el modelamiento de otro tipo de problemas, como por ejemplo, la simulación del
crecimiento de ramas de árboles [TreeGrowSimulator], y existen funcionalidades que sólo
sirven exclusivamente para un tipo de malla, la cuales pueden ser mallas de triángulos o
mallas de cuadriláteros, dejando la impresión de un sistema inestable.
1
Avatar: La imagen o icono que simboliza a una persona en relaciones por Internet o entornos
virtuales compartidos.
2
Es por esto que una solución promisoria para este tipo de problemas va por desarrollar
software que siga las bases de la línea de productos de software, las cuales permiten la
reutilización de código u objetos, lo cual permite tener los siguientes beneficios:
• Incremento en la calidad.
Objetivos específicos
Dentro de los objetivos específicos requeridos para poder lograr la satisfacción del
objetivo general se encuentran:
3
• Determinar un conjunto de puntos de variabilidad dentro del diseño de este
sistema para poder encapsularlos dentro de la arquitectura, generando funcionalidades
“reemplazables”.
• Generación de una interfaz gráfica que permita seleccionar entre las distintas
alternativas existentes para poder utilizar el sistema, según las funcionalidades o
herramientas que se necesiten.
4
Capitulo 2
2. Antecedentes
En el siguiente capítulo se exponen las nociones de los distintos temas asociados al trabajo
desarrollado en el presente documento, con mayor detalle. En él se explican temas como
las líneas de producto, o las aplicaciones “FaceAnimator”, “TreeGrowSimulator” y
“S.P.L.O.T.”, de manera de que el lector tenga un antecedentes para comprender la
problemática y el desarrollo del trabajo.
Aun cuando los consumidores utilizaban el software estándar, sus necesidades no se veían
resueltas completamente con estas herramientas. Fue por esto que la industria comenzó a
incluir las distintas necesidades de los consumidores a su producción. Con esto nace lo
que se conoce como “Customización Masiva” que se define como “La producción a gran
escala de bienes hechos a medida de las necesidades de los clientes” [SPLE05].
Para poder desarrollar este modelo de producción, se necesita poder definir lo que se
conoce como una plataforma, la cual se define a grandes rasgos como “la base
tecnológica en la que otras tecnologías o procesos son construidos” [SPLE05]. En el
ámbito del desarrollo de software, las plataformas se definen como “una colección de
artefactos reusables, como por ejemplo requerimientos, diseño, test, clases, etc.”
5
[SPLE05]. Se refiere entonces a la plataforma como los ladrillos con los cuales construir el
producto deseado. Para conseguir esto, es necesario que la creación de estas plataformas
sea lo suficientemente flexible como para habilitar la construcción de una amplia gama de
productos. Esto se conoce como Variabilidad.
Para que las empresas puedan implementar este modelo de producción exitosamente, se
necesita una organización constante de los procesos y plataformas que desarrollan.
Algunas prácticas que facilitan la adopción de este modelo de producción en el ámbito del
software son:
• Configuración Tardía
Las motivaciones que tienen las empresas para adoptar este modelo, entre otras, son:
6
Usabilidad: Permite a los usuarios familiarizarse con el uso del sistema, ya que
mantiene funcionalidades en común.
Es así como podemos definir la Ingeniería de líneas de productos de software (LPS o SPL
en ingles) como un paradigma para desarrollar aplicaciones de software utilizando
plataformas y la customización en masa.
2.1.1. Framework
El paradigma de desarrollo propuesto por [SPLE05] se separa en 2 procesos: la Ingeniería
de dominio y la Ingeniería de aplicación. Esto permite separar los esfuerzos en crear una
aplicación robusta y entregar software hechos a medida en un corto tiempo.
7
Dentro de este ciclo existe el proceso de “Administración de Producto (Product
Management)”, el cual define el alcance de la familia de productos a desarrollar y generar
la planificación para el futuro de los productos dependiendo de los artefactos que se
encuentran disponibles y los que se requerirán. Esta planificación se conoce como
“RoadMap” u “Hoja de ruta tecnológica”.
El Diseño de dominio busca generar una arquitectura de referencia para la línea del
producto. Para esto es necesario identificar los puntos de variabilidad en la arquitectura,
permitiendo la aplicación o configuración de estas en el futuro. El producto que genera es
un diseño de partes reutilizables.
Con estos artefactos definidos, la Ingeniería de aplicación busca hacer el mayor uso de
estos. Para esto el proceso de Ingeniería de requerimientos de aplicación determina qué
requerimientos de dominio sirven para conseguir la implementación específica
(determinada también por el RoadMap). En este punto si existen requerimientos
específicos que no se encuentren en los de dominio, se debe buscar beneficiar lo general,
para disminuir el esfuerzo de adaptar la aplicación específica.
Luego se continúa con el Diseño de la aplicación, la cual toma el diseño de dominio y hace
las elecciones de variabilidad para la aplicación especifica a construir. Se debe evitar
dentro de lo posible hacer cambios en la arquitectura que signifiquen un esfuerzo igual a
generar la misma aplicación desde cero.
8
A continuación se procede a la configuración de los artefactos seleccionados en el proceso
anterior, denominado como Realización de la aplicación. Se debe mantener una buena
documentación de la configuración seleccionada, ya que permite hacer un seguimiento a
los artefactos seleccionados, facilitando de esta manera la mantención.
La variabilidad se define en los procesos de dominio, por lo que esto implica que la
variabilidad debe ser administrada: definiéndola, resolviéndola, administrando la
documentación y referencias.
Para poder identificar la variabilidad, primero se debe hacer el ejercicio de formular las
siguientes preguntas:
• ¿Cómo varia?
Esto permite definir el sujeto variable, que es el ítem variable o una propiedad de este.
Como ejemplo, un sujeto de variabilidad es el color en un auto.
Luego se puede definir el objeto variable, el cual es una instancia en particular del sujeto
de variabilidad. Siguiendo con el ejemplo, un objeto variable seria el color rojo.
9
Se pueden distinguir distintos tipos de variabilidad. Una de estas es la variabilidad en el
tiempo. Esta variabilidad se define como “la existencia de diferentes versiones de un
artefacto que son válidos en distintos momentos” [SPLE05]. Esta variabilidad responde a
un proceso natural en los productos de software, la evolución de los sistemas. Un ejemplo
de variabilidad en el tiempo se puede apreciar, continuando con el ejemplo del auto, el
sistema de bloqueo o apertura de las puertas. Actualmente este punto de variabilidad
puede tener las variantes de “Llaves” o “Tarjetas magnéticas” y a medida que la
tecnología avanza, puede tener otras, por ejemplo “Lectores de huella digital”,
“Reconocimiento de Voz”, etc.
También se puede definir la variabilidad dependiendo del origen de esta, ya que estas
pueden ser definidas de manera Externa o Interna. La variabilidad Externa obedece a los
cambios percibidos como necesarios por el cliente. Luego se puede definir como “la
variabilidad de artefactos de dominios que es visible a los clientes” [SPLE05]. La causa de
la variabilidad externa generalmente proviene desde necesidades específicas del cliente,
pero a veces puede resultar exigible dado el marco legal de la aplicación. Un ejemplo de
variabilidad externa es el artefacto por el cual se controla el acceso a una puerta. Esta
pueda ser un teclado numérico o/y un lector biométrico, dependiendo de la seguridad que
exija el cliente o las normas dentro del ambiente donde se encuentra este artefacto.
Por otro lado, se puede definir la variabilidad Interna como “la variabilidad de artefactos
de dominio que permanecen escondidos al cliente” [SPLE05]. La causa de la variabilidad
Interna nace al momento de implementar o refinar las variabilidades externas. Esto a su
vez genera más refinamiento, cada vez de más bajo nivel. Como al cliente le interesan los
aspectos del sistema de más alto nivel, es necesario “esconder” ciertos puntos que no
ayudan a la utilización ni comercialización del producto, ya que lo hacen más complejo. Un
ejemplo de esto puede ser dado un lector de huellas digitales, saber qué tipo de
almacenamiento y algoritmos de compresión utiliza el sistema para almacenar las
imágenes.
Es necesario destacar, que entre más variabilidades externas se definan mayor va a ser el
número de variabilidades internas definidas, creciendo en lo que se conoce como un
modelo piramidal, ya que por cada variabilidad externa necesariamente se debe refinar a
10
una o más variabilidades internas, las cuales a su vez pueden ser refinadas hasta llegar a
niveles más bajos de abstracción. Es por esto que es importante mantener al mínimo las
variabilidades externas ya que estas traen consigo un aumento de la complejidad y los
costos de los sistemas.
2.2. S.P.L.O.T.
[S.P.L.O.T.] (http://www.splot-research.org/) es un sistema web Opensource
desarrollado en Java que permite crear un modelo altamente interactivo de razonamiento
y configuración de productos.
2
SAT: Problema de satisfacibilidad booleana. Es un tipo de problema de complejidad Np-completo.
11
Figura 2.2.1 Creación de clausulas lógicas en forma CNF
12
Figura 2.2.2 Configuración de producto de modelo de bicicletas TREK
También el sistema cuenta con la ventaja de que tiene propagación retroactiva, lo que
permite que no se tenga que volver sobre decisiones pasadas.
Esta herramienta cuenta con un repositorio gratuito y abierto que permite almacenar los
modelos generados (archivos XML).
Estas características fueron las principales ventajas identificadas para optar por este
sistema para especificar la variabilidad del sistema. Esto sobre algunas notaciones para
documentar la variabilidad como los propuestos en [FODA], los cuales permiten expresar
las distintas componentes de buena manera, pero carecen de componentes interactivos
como el de [S.P.L.O.T.]. Además se necesita tener conocimiento técnico de las sintaxis de
las expresiones. Existen también herramientas parecidas a [S.P.L.O.T.] como [FAMAFW] o
[XFEATURE], los cuales necesitan de una inscripción previa y/o son programas que se
descargan al computador.
La herramienta provista por [S.P.L.O.T] fue seleccionada para la descripción de los puntos
de variabilidad del sistema, permitiendo mantener en un repositorio centralizado las
especificaciones del sistema y de fácil acceso.
13
2.3. TreeGrowSimulator
El sistema [TreeGrowSimulator] fue desarrollado en la Universidad de Chile, por la
profesora Nancy Hitschfeld y un equipo de memoristas. Este sistema sirve como base para
la implementación de [FaceAnimator], ya que utilizan la misma arquitectura y
herramientas de computación gráfica.
Este software sienta las bases para el desarrollo de la presente memoria, ya que en él se
encuentran implementadas las clases bases (artefactos) que permiten sentar una
plataforma base en la cual construir una aplicación que trabaje con mallas geométricas.
Este sistema fue desarrollado en C++, y su objetivo principal (como lo indica su titulo) fue
el estudio del crecimiento de troncos de árboles provocado por la aplicación de una
hormona. Existe la funcionalidad de ver paso a paso los cambios en la corteza del árbol o
ver los cambios de forma continua.
2.4. FaceAnimator
El sistema [FaceAnimator] estuvo inmerso dentro de un proyecto de mayor envergadura,
que involucra a equipos de trabajo de la Universidad Nacional de Rosario, en Argentina y
del INRIA Nancy - Grand Est, en Francia. Este proyecto global tuvo como nombre BAVI:
Bio-inspired Audio/Visual Information Integration, que involucra el descubrimiento de
características de movimiento humano a través de un enfoque bio inspirado por parte del
14
equipo francés, junto a la participación del equipo argentino, mediante la extracción de
parámetros de movimiento a partir de información auditiva.
También se tuvo que habilitar la carga de mallas específicas, ya que las mallas geométricas
que soportaba el sistema no incluían los formatos que tienen las mallas que representan
rostros. Para manipular de buena manera los rostros se agregó la funcionalidad de “calce”
de puntos entre la malla cargada y una malla estándar que permite aplicar movimiento de
manera más fácil. Así se agregó un menú que permite mover puntos del rostro
previamente definidos (en base a la plantilla “Candide-3” [Candidade3]). Esto permitiría
generar deformaciones a los rostros. Para poder guardar estas deformaciones y poder
cargarlas nuevamente, se especificó un archivo que contiene las instrucciones de
deformaciones. Luego este archivo se puede cargar para que los movimientos sean leídos
por la aplicación todos de una vez y genere las deformaciones sobre el rostro para ser
visualizadas paso a paso o en forma continua.
15
Capitulo 3
3. Diseño e Implementación
En el presente capitulo se describen los pasos llevados a cabo para la ejecución de la
solución planteada según los objetivos a cumplir, desde la instalación del código fuente de
la aplicación [FaceAnimator], el rediseño de clases, hasta la utilización de la aplicación
[S.P.L.O.T] para identificar las variabilidades de la aplicación, permitiendo el desarrollo
completo de la solución final, llamada “Meshing Tool Generator”.
gtkmm
gtkglextmm
gsl
geomview
Una vez instaladas estas librerías, se compiló el sistema sin éxito, ya que existían
problemas con las librerías instaladas. El depuramiento del código fuente permitió
identificar que la librería libsigc++ se encontraba en una versión mayor que en la que fue
desarrollado en primera instancia el sistema. Al no saber la versión con la cual el sistema
era estable, se procedió a actualizar el sistema a la nueva librería. Esta librería permite la
llamada de funciones callback mediante la asignación de señales a distintos eventos. La
versión de la librería actualizada es 2.0. Los cambios necesarios para que el sistema
pudiese compilar con éxito fueron:
16
Se comentó la inclusión del header #include
<sigc++/compatibility.h> ya que en esta nueva versión no se utiliza.
Además se tuvo que incluir algunos headers que en algunas clases no permitían la
ejecución de la aplicación, la lista de errores y su solución se detallan a continuación:
El diseño básico comienza con la primera abstracción, la cual es la clase “Malla” que es el
punto común de las aplicaciones. Para esto también se implementaron las clases “Nodo”,
“Arco” y “Cara” que permiten construir una malla y operar sobre esta. La estrategia
utilizada se pensó para que se pudiese construir una malla inicial según distintos criterios,
como la geometría de la malla, la densidad de esta, y la posible aplicación de algoritmos
de refinamiento o mejoramiento sobre esta malla [MeshTools2005]. Dado que pueden
existir distintas implementaciones para cada uno de estos pasos, se diseñaron como clases
separadas entre sí, como por ejemplo dada la definición la clase “Triangulo”, un posible
diseño era el de implementar como método de esta clase las estrategias de refinamientos
o como un componente separado de esta clase. Se eligió esta segunda estrategia
principalmente por 2 razones [MeshTools2005]:
La aplicación final debe ser extensible a fin de ser capaces de generar nuevas
miembros de la familia mediante la incorporación de nuevas estrategias y criterios
y hacer muy pocas modificaciones al código fuente.
Como se puede ver en la figura 3.2.1, el diseño final es un diseño modular donde se
implementa una gran cantidad de interfaces, lo que permite intercambiar la
implementación final de los distintos algoritmos. Como por ejemplo, se puede ver que la
clase “Comando” es una interfaz que permite la ejecución de métodos sobre el objeto
malla, haciendo transparente e independiente la implementación de esta con la de los
algoritmos. Dentro del diseño se pueden apreciar distintas interfaces para distintos
objetivos, como la de deformar la malla, guardar la malla en algún formato establecido o
ver información de la malla, entre otros. Estas interfaces a su vez instancian interfaces
hijas hasta llegar a las diferentes implementaciones de las opciones de los algoritmos o
criterios que puede a llegar a tener uno de estos comandos.
18
Figura 3.2.1: Diagrama de clases [FaceAnimator].
19
3.2.2. Modificación de Clases
Aun cuando la gran mayoría del diseño se mantuvo con la estrategia comentada en el
punto 3.2.1, existen casos en que la implementación de funcionalidades específicas para la
aplicación [FaceAnimator] no siguió la estrategia ideal. En el caso de la clase
“MovimientoNodos” (Figura 3.2.2), la cual es una interfaz para la implementación de
movimiento de nodos según distintos métodos, su ubicación en el diseño es
conceptualmente errónea ya que se puede apreciar que depende directamente de la clase
“Malla”, siendo que ya existe una clase que funciona como interfaz de movimientos de
nodos, en especifico de mallas de triángulos, la clase “AlgDesplazamientoMallaTriangulo”.
Es por eso que se eliminó y colgaron sus hijos directamente de
“AlgDesplazamientoMallaTriangulo”, como se puede ver en la figura 3.2.3. Para poder
lograr esto se debió modificar parte de la clase malla, la cual implementaba el método
“moverNodosSegunParametro”, donde se hacía inclusión de la clase
“MovimientosFromFile” directamente. Luego para poder incluir esta clase como clase hija
de “AlgDesplazamientoMallaTriangulos” se debió declarar este método en esta clase de
manera virtual, y la implementación se hizo en todos los hijos. Esto permitió “desacoplar”
la clase “MovimientosFromFile” de la clase Malla ya que generaba una dependencia
circular al tratar de definirla directamente como clase hija de
“AlgDesplazamientoMallaTriangulos”.
20
Figura 3.2.3: Diseño final de dependencia de clase AlgDesplazamientoMallaTriangulos
Las otras clases que necesitaban modificación eran las clases “RegistrationMethod” e
“Interpolator”, ya que estas no se insertaban dentro del diseño general y no dependían de
ninguna clase padre, como se aprecia en la figura 3.2.4. Ambas clases son utilizadas para
generar un “calce” entre la malla de rostro seleccionada y una malla de rostros estándar,
lo que permite generar movimientos en esta malla. Dado que estas clases son especificas
para la aplicación [FaceAnimator] su dependencia no puede ser directa a una clase base
de la aplicación. Por esta razón se crea una nueva clase padre, llamada
“GenerarMallaInicial”, la cual contiene como hijos a las clases “RegistrationMethod” e
“Interpolator”, como se puede ver en la figura 3.2.5. Esta clase reemplaza a la clase
Generar y absorbe todos sus hijos. La idea de esta clase es crear un método virtual que
genera la malla inicial con la que se va a trabajar, permitiendo utilizar las clases necesarias
según el tipo de malla escogida.
21
Figura 3.2.5: Diseño final de herencia de clase GenerarMallaInicial
22
Algoritmo de refinamiento: Algoritmo que permite refinar la malla geométrica,
aumentando la cantidad de puntos que la construyen. Sus posibles opciones
(variantes) son :
o LEPP-DELAUNAY
o CREAR ANIMACIÓN
o ACTIONUNITS
o CONCENTRACIÓN HORMONA
Aplicaciones Específicas: Funcionalidad especifica que se aplican sobre la malla para fines
específicos de cada aplicación, sus variantes actuales son:
o DISTRIBUCIÓN DE HORMONA
Idioma: Idioma en cual los mensajes y las interfaces graficas son presentadas, sus
variantes son:
o INGLES
o ESPAÑOL
o ÁREA MÍNIMA
o EDGE-COLAPSE
Manejo de Archivos: Herramientas que permiten seleccionar las distintas acciones para
manejar archivos de mallas geométricas, sus variantes son:
o GUARDAR
OFF
TXT
WRL
CMS_1
Algoritmo de Malla Inicial: Esto permite seleccionar al algoritmo que se aplica a la malla
que se genera al momento de abrir un archivo.
o REGISTRATION METHOD
o DUMMY ALGORITHM
o MOSTRAR CARAS
o MOSTRAR ARCOS
o BORRAR MALLA
o TRIANGULAR
o CUADRANGULAR
Abrir: Se debe seleccionar al menos una opción de formato para poder abrir una
malla y trabajar sobre esta.
24
Una vez definidos los puntos de variabilidad, se definieron las reglas lógicas que permiten excluir o
incluir puntos variables en base a los seleccionados anteriormente. Como ejemplo, si se selecciona
que se utilizará el formato de archivo OFF, esto excluye la utilización de la aplicación de
Registration Method al momento de generar la malla inicial.
Para generar estas reglas lógicas, se utiliza a través del sistema [S.P.L.O.T.] la herramienta “Create
Constraint” donde se selecciona las funcionalidades relacionadas. Existen básicamente 2 reglas
lógicas, de exclusión y de inclusión:
Las reglas lógicas que se generaron en base a las funcionalidades identificadas son (Figura 3.3.1):
25
El archivo fuente de modelo actual se encuentra en el Apéndice F. Este archivo se encuentra en
formato SXFM3, el cual se puede cargar a la herramienta ingresando el archivo SXFM mediante una
URL.
Meshing Tool Generator es una aplicación sencilla que permite a través de un menú
seleccionar las variantes para cada punto variable. Luego con los valores seleccionados el
programa genera un archivo llamado “build_option.txt”, en el cual se encuentran las
instrucciones para construir la aplicación que se desea. Como se puede apreciar en la
figura 3.4.1 este archivo se utiliza tanto en el momento de compilación como el momento
de ejecución de la
aplicación.
Meshing Tool
Generator
build_op
MakeFile
tion.txt
Aplicación
3
Simple XML Feature Model http://gsd.uwaterloo.ca:8088/SPLOT/sxfm.html
26
El archivo “build_option.txt” es un archivo de texto plano donde cada línea refiere a un
punto variable, en la cual se escribe el valor de cada variante. La estructura y la lista de
valores que se aceptan se encuentran en el Apéndice C.
Una vez creado el archivo, la aplicación Meshing Tool Generator ejecuta el makefile el
cual recibe como parámetro de entrada el archivo “build_option.txt” y permite compilar
utilizando solo las clases que se necesitan según las variantes seleccionadas. Un ejemplo
de un makefile que utiliza esta estrategia se puede encontrar en el Apéndice E.
27
Capitulo 4
4. Resultados
En el siguiente capítulo se encuentran imágenes que muestran el resultado del trabajo
realizado para esta memoria. En él se puede verificar las distintas estadísticas del
resultado del modelo de variabilidad propuesto en la herramienta [S.P.L.O.T.], así también
se puede apreciar el resultado final de la aplicación “Meshing Tool Generator”, donde se
muestra como se produce una versión de la aplicación [FaceAnimator], según distintos
parámetros escogidos. Finalmente se presenta una pequeña discusión de los resultados
obtenidos en comparación con los objetivos propuestos.
28
Figura 4.1.1: Análisis de las funcionalidades y del modelo con [S.P.L.O.T.]
De estos datos se destaca que existen 46 funcionalidades, de las cuales 10 son opcionales,
6 obligatorias, y existen 29 agrupaciones. El largo máximo del árbol es de 3 hijos. El
número de reglas lógicas es 17, con 10 reglas lógicas que provienen de las transitividad de
estas.
El análisis de errores permite saber si existen brazos en el árbol que no son seleccionables
dadas las reglas lógicas, esto se conoce como Dead Features o funcionalidades muertas.
Este análisis también nos dice que existen 7 funcionalidades comunes en todas las
29
configuraciones. Estas son = {FaceAnimator, Algoritmo Refinamiento, Manejo de Archivos,
Idioma, ABRIR, Algoritmo de Malla Inicial, Nombre Aplicación}
Dentro del análisis de las métricas, las posibles configuraciones son 4.618.592
considerando la inclusión o no de cada funcionalidad.
30
Figura 4.1.4: Catalogo de configuración del producto
31
El catalogo se puede apreciar en la siguiente URL
http://gsd.uwaterloo.ca:8088/SPLOT/SplotConfigurationServlet?action=interactive_configuration_m
ain&op=reset&userModels=&selectedModels=model_20110507_674768061.xml
32
Figura 4.2.2: Verificación de reglas lógicas.
34
El archivo de configuración build_options.txt que genera la aplicación es el siguiente:
Figura 4.2.3: Versión A, solo se permite abrir formatos MATLAB, OFF y CMS_1
35
Figura 4.2.4: Versión B, solo se permiten los formatos WFM y WRL
36
Figura 4.2.6: Versión B, Se permite ver caras y arcos además de la estadística de la malla.
37
Figura 4.2.8: Versión B, al cargar la malla se ejecuta Registration Method.
Figura 4.2.9: Versión A, solo se presenta el algoritmo de des refinamiento “Largo Arcos Mínimos”
38
Figura 4.2.10: Versión B, solo se presenta el algoritmo de des refinamiento “Área Cara Mínima”.
Además de este tipo de problemas, se encontró que para poder reflejar las
configuraciones escogidas para la aplicación a generar, se necesita modificar la
construcción de los menús para que no aparezcan disponibles cuando no se seleccionan.
Esto es debido a que actualmente la construcción de la interfaz principal del programa se
hace en una sola clase (GUIVentanaPrincipal_glade.cc) lo que hace necesaria
la estrategia de leer los parámetros al momento de ejecución para saber cuál es la
configuración de menús a mostrar. Se tiene también que esta clase adjunta eventos a los
menús asociados y estos eventos están implementados principalmente en 2 clases
GUIVentanaFaceModeling.cc y GUIVentanaTreeGrowth.cc. Actualmente
solo se utiliza una clase (GUIVentanaFaceModeling), ya que se debe instanciar al
comienzo para generar la interfaz principal, dejando afuera la implementación de algunos
eventos propios de la clase GUIVentanaTreeGrowth.
La consecuencia de estos problemas son dos: primero que hace necesario la inclusión de
la mayoría de las clases al momento de compilar la aplicación, dejando aplicaciones con
implementaciones iguales, que solo cambian en la organización del menú. El segundo
problema es que necesariamente el programa a ejecutar necesita un archivo con
parámetros para saber qué elementos del menú mostrar, lo cual aumenta la complejidad
y disminuye su robustez ya que permite que este archivo sea modificado, afectando
directamente en la ejecución de la aplicación.
Aún cuando existen estos problemas, el objetivo general se pudo cumplir, generando una
aplicación que permite configurar las aplicaciones, aún la construcción de la aplicación
según las opciones seleccionadas suceda solo a nivel de la construcción del menú y no de
la compilación de clases.
40
Capitulo 5
El trabajo futuro sobre esta aplicación se puede dividir en dos áreas principalmente, una
es la extensibilidad de la aplicación “Meshing Tool Generator” y la otra es la de la revisión
e implementación de mejoras en las clases que componen la estructura de las aplicaciones
[TreeGrowSimulator] y [FaceAnimator]. En detalle las extensiones posibles para el
presente trabajo son:
Proveer una lectura del archivo XML o CVS (que se puede descargar del catálogo
de producto en la herramienta [S.P.L.O.T.], una vez seleccionados todas las
funcionalidades requeridas (ver Apéndices D y E) en la aplicación “Meshing Tool
Generator” que cargue la configuración directamente, ahorrando tiempo ya que
no es necesario re implementar la interfaz de “Meshing Tool Generator” para
cada nuevo punto de variabilidad que se quiera agregar.
42
Referencias
[SPLE05] Klaus Pohl, Gunter Bockle, Frank van der Linder “Software Product Line
Engineering”. Springer Berling Heidelberg, NY, USA. 2005. Cap 1-4.
[FODA] Kang, Cohen, Hess, Novak, Spencer “Feature Oriented Domain Analisys
Feasibility Studio”. Technical Report CMU/SEI-90-TR-21. Carnegie Mellon University,
SEI, Noviembre 1990. pp. 40- 66
43
Apéndices
A Diagrama de Clases Modificado
45
C Ejemplo de XML generado por herramienta [S.P.L.O.T.]
<!--
This file contains details about the configuration of model FaceAnimator and includes
selected/deselected features,
configuration steps, and the type of decisions made (e.g. manual, automatic, auto-completion).
-->
<configuration model="FaceAnimator">
<feature id="_r">
<name>FaceAnimator</name>
<type>templateModel</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="_r_13">
<name>Algoritmo Refinamiento</name>
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="_r_13_15_16">
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
46
<feature id="_r_13_15_17">
<name>LEPP-DELAUNAY</name>
<type>grouped</type>
<value>1</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_11">
<name>Algoritmo Deformacion</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_11_12_13">
<name>CREAR ANIMACION</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_11_12_14">
<name>DEFORMACION CD3</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
47
<feature id="_r_15">
<name>Opciones de Visualizacion</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_15_16_17">
<name>ACTION UNITS</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_15_16_18">
<name>CONCENTRACION HORMONA</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_19">
<name>Aplicaciones Especificas</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
48
<feature id="_r_19_20_21">
<name>DISTRIBUCION DE HORMONA</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="__r_19">
<name>Idioma</name>
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="__r_19_21_22">
<name>ESPANOL</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="__r_19_21_23">
<name>INGLES</name>
<type>grouped</type>
<value>1</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
49
<feature id="_r_22">
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_22_23">
<name>MEJORAR</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_22_24">
<name>DESREFINAR</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_22_24_25_26">
<name>AREA MINIMA</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
50
<feature id="_r_22_24_25_27">
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_36">
<name>Manejo de Archivos</name>
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="_r_36_37">
<name>GUARDAR</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_36_40">
<name>ABRIR</name>
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
51
<feature id="_r_36_41_45">
<name>MATLAB</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_36_41_47">
<name>OFF</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_36_41_48">
<name>TXT</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_36_41_49">
<name>WRL</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
52
<feature id="_r_36_41_50">
<name>CMS_1</name>
<type>grouped</type>
<value>1</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_51">
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="_r_51_38_39">
<name>DUMY ALGORITHM</name>
<type>grouped</type>
<value>1</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_51_38_40">
<name>REGISTRATION METHOD</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
53
<feature id="_r_41">
<name>Nombre Aplicacion</name>
<type>mandatory</type>
<value>1</value>
<decisionType>propagated</decisionType>
<decisionStep>1</decisionStep>
</feature>
<feature id="_r_42">
<name>Caracteristicas de Visualizacion</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_42_43_44">
<name>MOSTRAR CARAS</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_42_43_45">
<name>MOSTRAR ARCOS</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
54
<feature id="_r_42_43_46">
<name>INFORMACION</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_42_43_47">
<name>ELIMINAR</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_48">
<name>Modificacion Geometria</name>
<type>optional</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
<feature id="_r_48_49_50">
<name>TRIANGULAR</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
55
<feature id="_r_48_49_51">
<name>CUADRANGULAR</name>
<type>grouped</type>
<value>0</value>
<decisionType>auto-completion</decisionType>
<decisionStep>2</decisionStep>
</feature>
</configuration>
56
_r_42_43_44,MOSTRAR CARAS,grouped,0,auto-completion,2,
_r_42_43_45,MOSTRAR ARCOS,grouped,0,auto-completion,2,
_r_42_43_46,INFORMACION,grouped,0,auto-completion,2,
_r_42_43_47,ELIMINAR,grouped,0,auto-completion,2,
_r_48,Modificacion Geometria,optional,0,auto-completion,2,
_r_48_49_50,TRIANGULAR,grouped,0,auto-completion,2,
_r_48_49_51,CUADRANGULAR,grouped,0,auto-completion,2,
E Ejemplo MakeFile
## Variables
CC = g++
FLAGS = -O2 -DNDEBUG -lgsl -lgslcblas
EXE_NAME = treegrowthsimulator
GTK_FLAGS = `pkg-config gtkglextmm-1.2 --cflags --libs`
##all :
57
algrefinamientomallacuadrilateros.cpp leppdelaunay.cpp
delaunaylongestedgebisection.h
ifeq ($(ADEF),CD3)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
herr_visual.o: *.h
ifeq ($(HVIS),AU)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
alg_aplicacion.o: *.h
ifeq ($(AAPP), *)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
idioma.o: *.h
ifeq ($(IDIOMA),*)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
herr_mod_malla.o: *.h
ifeq ($(ref),lepp)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
herr_archivos.o: *.h
ifeq ($(ref),lepp)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
endif
malla_inicial.o: *.h
ifeq ($(REGIS),REG)
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
else
$(CC) $(FLAGS) -c *.cpp $(GTK_FLAGS)
58
endif
clean:
rm -f $(EXE_NAME) *.o
60
F Modelo de puntos de variabilidad herramienta [S.P.L.O.T.]
formato SXML
<!-- This model was created online using SPLOT's Feature Model Editor (http://www.splot-
research.org) on Thu, Sep 22, 2011 - 1:22 AM --><feature_model
name="FaceAnimator"><meta><data name="description">FaceAnimator</data><data
name="creator">Gonzalo U</data><data name="address"/><data
name="email">gonzalourroz@gmail.com</data><data name="phone"/><data
name="website"/><data name="organization">U. de Chile</data><data
name="department"/><data name="date"/><data name="reference"/></meta><feature_tree>
:r FaceAnimator(_r)
:m Algoritmo Refinamiento(_r_13)
:g (_r_13_15) [1,1]
: LEPP-DELAUNAY(_r_13_15_17)
:o Algoritmo Deformacion(_r_11)
:g (_r_11_12) [1,1]
: CREAR ANIMACION(_r_11_12_13)
: DEFORMACION CD3(_r_11_12_14)
:o Opciones de Visualizacion(_r_15)
:g (_r_15_16) [1,1]
: ACTION UNITS(_r_15_16_17)
: CONCENTRACION HORMONA(_r_15_16_18)
:o Aplicaciones Especificas(_r_19)
:g (_r_19_20) [1,1]
: DISTRIBUCION DE HORMONA(_r_19_20_21)
:m Idioma(__r_19)
:g (__r_19_21) [1,1]
: ESPANOL(__r_19_21_22)
: INGLES(__r_19_21_23)
61
:o MEJORAR(_r_22_23)
:o DESREFINAR(_r_22_24)
:g (_r_22_24_25) [1,1]
: AREA MINIMA(_r_22_24_25_26)
:m Manejo de Archivos(_r_36)
:o GUARDAR(_r_36_37)
:m ABRIR(_r_36_40)
:g (_r_36_41) [1,*]
: MATLAB(_r_36_41_45)
: OFF(_r_36_41_47)
: TXT(_r_36_41_48)
: WRL(_r_36_41_49)
: CMS_1(_r_36_41_50)
:g (_r_51_38) [1,1]
: DUMY ALGORITHM(_r_51_38_39)
: REGISTRATION METHOD(_r_51_38_40)
:m Nombre Aplicacion(_r_41)
:o Caracteristicas de Visualizacion(_r_42)
:g (_r_42_43) [1,*]
: MOSTRAR CARAS(_r_42_43_44)
: MOSTRAR ARCOS(_r_42_43_45)
: INFORMACION(_r_42_43_46)
: ELIMINAR(_r_42_43_47)
:o Modificacion Geometria(_r_48)
:g (_r_48_49) [1,*]
: TRIANGULAR(_r_48_49_50)
62
: CUADRANGULAR(_r_48_49_51)
</feature_tree><constraints>
constraint_42:~_r_15_16_18 or _r_19_20_21
constraint_45:~_r_11 or ~_r_36_41_45
constraint_56:~_r_36_41_50 or ~_r_51_38_40
constraint_38:~_r_15_16_17 or ~_r_36_41_50
constraint_47:~_r_11 or ~_r_36_41_48
constraint_55:~_r_36_41_48 or ~_r_51_38_40
constraint_37:~_r_15_16_17 or ~_r_36_41_48
constraint_46:~_r_11 or ~_r_36_41_47
constraint_54:~_r_36_41_47 or ~_r_51_38_40
constraint_36:~_r_15_16_17 or ~_r_36_41_47
constraint_49:~_r_11 or _r_36_41_49
constraint_53:~_r_36_41_45 or ~_r_51_38_40
constraint_35:~_r_15_16_17 or ~_r_36_41_45
constraint_48:~_r_11 or ~_r_36_41_50
constraint_50:~_r_15_16_17 or _r_36_41_49
constraint_51:~_r_19_20_21 or ~_r_36_41_49
constraint_52:_r_36_41_49 or ~_r_51_38_40
</constraints></feature_model>
63