IZTAPALAPA Ciencias Bsicas e Ingeniera Ingeniera Electrnica rea de Computacin. Proyecto Terminal. Desarrollo de un sistema de reconstruccin de imgenes 3D a partir de cortes. Marzo 1999 Humberto G. Cewantes Maceda 93319407 Asesor: Alfonso Martnez Martnez Documentacin del proyecto nor: Humberto Cewantes Maceda Asesor : Alfonspklannez Martinez / Esta documentacin concierne al proyecto terminal realizado por Humberto Cervantes Maceda, bajo la asesora de Alfonso Martnez Martnez. Fue realizado durante 1998 en el laboratorio de Procesamiento De Seales e Imgenes Biomdicas de la Universidad Autnoma Metropolitana Iztapalapa. Se puede encontrar una versin electrnica del mismo en la direccin siguiente: http://itzamna.uam.mx/DOCUMENTACION/Indice.html Esta documentacin fue terminada el 15 de Marzo de 1999. Dedicado a: Alfonso Martnez y todo el equipo de LICPOS Mis padres, Humberto e Ilse y mi hermano Miguel. Y tambin a Gaby por estar siempre conmigo. j Domo Arigato Gozaimashita ! DOCUMENTACION DEL PROYECTO TERMINAL "Sistema de reconstruccin de Imgenes 3D a partir de cortes'' por Humberto Cervantes Maceda . INDICE: . . 1 .. Introduccion al sistema ................................................................................ 1 2.- La metodologa utilizada ............................................................................. 1 2.1 . El macro proceso .......................................................................................... 2 2.2- El micro proceso ........................................................................................... 3 3 .. Especificacin y Anlisis del sistema ...................................................... 4 3.1 . Requerimientos iniciales ............................................................................... 4 3.2- Situaciones potenciales ................................................................................. 5 3.3- Tarietas CRC ................................................................................................ 5 3.4- Anlisis de casos de uso ................................................................................ 7 3.4.1 . Introduccin ........................................................................................... 7 3.4.2- Descripcin de los casos de uso ............................................................ 8 3.5- Prototipo de la interfaz de usuario ................................................................ 9 3.6- Anlisis de las clases .................................................................................... 10 3.6.1 . Determinacin de las clases .................................................................. 10 3.6.4- Diccionario de datos de las clases ......................................................... 11 3.6.3 . Diagramas de secuencia ........................................................................ 12 3.6.4- Diagrama de clases inicial ..................................................................... 15 3.7- Conclusin del anlisis .................................................................................. 16 4.- Diseo del sistema ......................................................................................... 16 4.1 Patrones de diseo .......................................................................................... 17 4.2 Aplicacin de los patrones .............................................................................. 19 4.2.1 El maneiador de ventanas ....................................................................... 19 4.2.2 El procesador de imgenes - ..................................................................... 21 4.3 El rea grfica ................................................................................................ 22 4.4 Refinamientos de la Coleccin De Datos ...................................................... 23 4.4.1 El arreglo como lista ligada .................................................................... 26 4.5 Diagramas de secuencia ................................................................................ 26 4.6 Diagrama de clases ....................................................................................... 29 4.7 Conclusin de la etapa de diseo ................................................................... 30 - 5.- La Implementacin ....................................................................................... 30 5.1 Las clases C ObietoInteractivo y C ObietoModificable .............................. 31 5.2 Encapsulando la interfase de ventanas ........................................................... 31 5.3 Meioras en el rea grfica .............................................................................. 35 5.4 Meioras en la clase C Imagen ....................................................................... 35 5.5 Meioras y otros usos para la lista ligada ........................................................ 36 5.6 La configuracin del stack y su uso ............................................................... 37 5.7 Diamamas de secuencia ................................................................................. 37 5.8 Diagramas de clases ....................................................................................... 43 5.8.1 Detalle de clases ..................................................................................... 47 5.9 Conclusin de la etapa ................................................................................... 48 . 6.- Aspectos Tcnicos ........................................................................................ 48 6.1 Recuperacion del apuntador 'this' dentro de xforms ...................................... 48 6.2 Pasos a seguir - para implementar una nueva ventana ..................................... 54 6.3 Cambio de contexto para multiples reas grficas (Elcanvas) ...................... 63 6.4 Desplegando imgenes con OpenGL ............................................................. 64 6.5 Implementacin de 'itoa' en una clase de funciones 'externas'. ...................... 64 6.6 Uso de 'make' para compilar la aplicacin ..................................................... 65 - . 7.- Conclusiones .................................................................................................. 68 8.- Bibliografa ..................................................................................................... 69 Introduccin. 1 .- Introduccin. En la actualidad estamos viviendo una poca de auge en el terreno de la computacin, esto es no slo en el plano tecnolgico sino tambin en el de la creacin de aplicaciones o 'software', a diario aparecen nuevos desarrollos cada vez ms poderosos pero a la vez sencillos de utilizar. La propuesta de proyecto terminal que se presenta en este reporte concierne el desarrollo de una aplicacin para el rea de Ingeniera Biomdica, en particular para el laboratorio de procesamiento de seales e imgenes biomdicas (PDSIB) de la UAM - Iztapalapa. Esta aplicacin tiene cmo objetivo la representacin en forma de imgenes tridimensionales de reconstrucciones hechas a partir de cortes tomogrficos a los que se les ha aplicado uno o varios algoritmos. Las imgenes que se obtienen a partir de estudios como el de resonancia magntica o el de tomografa muestran secciones del cuerpo en imgenes con diversos tonos de gris. Es posible crear un objeto tridimensional que represente alguna estructura interna y que se obtiene a partir de las imgenes, y que se pueda emplear por ejemplo, para visualizar el crneo ante la necesidad de estudiar una fractura en la cabeza. Las imgenes deben ser procesadas antes de realizar las reconstrucciones, y para ello existe una gran variedad de algoritmos que permiten obtener resultados de mayor o menor calidad. En el laboratorio de procesamiento de seales e imgenes biomdicas se desean probar nuevos algoritmos para la obtencin de reconstrucciones tridimensionales, pero hasta ahora no hay manera de hacerlo en las estaciones de trabajo, que permiten desplegar grficas de manera eficiente, de ah surge el inters por un sistema como este. La creacin de aplicaciones no es una tarea sencilla, sobre todo cuando estas comienzan a tener un cierto grado de complejidad, y por ello es necesaria la utilizacin de alguna metodologa que permita llevar un orden a lo largo del proceso de desarrollo de la aplicacin. En lo que nos concierne, seguiremos la metodologa propuesta por Gradv Booch en su libro "Object Solutions". 2.- La metodologa. La metodologa con enfoque Orientado a Objetos, que nos propone el autor de este libro, es la del seguimiento de un ciclo de desarrollo iterativo e incremental. Con iterativo se refiere al hecho de que los pasos principales del mtodo debern ser repetidos varias veces, y esto se realiza de manera incremental esto es que en cada ocasin se refinan los resultados que se tienen de la iteracin anterior. Podemos asimilar el proceso a una espiral cuyo dimetro aumenta con el tiempo, pues aparecen cada vez ms detalles, esto se llama el "macro proceso'' (proceso global) y en su trayectoria se encuentran una serie de otras pequeas espirales, que deben ser recorridas para poder continuar el seguimiento de la trayectoria de la espiral principal, eso se llama el "micro proceso" (proceso local). 1 Macr o Proceso Mi cr o 9 I t 1 O - - Progreso Fig. 1, El macro proceso la serie de micro procesos . 2.1 - El macro proceso. El macro proceso, o proceso global, cuyo enfoque es principalmente administrativo, comprende el refinamiento sucesivo de la arquitectura del sistema, y est compuesto por los pasos principales del desarrollo tradicional del software (el modelo top-down), estos son: Las fases que se muestran en el diagrama consisten principalmente de: Concepcin: Establecimiento de los requerimientos centrales. Anlisis: Desarrollo de un modelo del comportamiento deseado del sistema. Diseo: Creacin de una arquitectura para la implementacin. Evolucin: Reestructuracin y puesta en accin de la implementacin. Existe tambin una fase ms que no se muestra en el digrama pero igualmente importante: Mantenimiento: Administra la Evolucin posterior a la entrega. Debemos recordar que el macro proceso no es una serie de pasos que se recorran una sola vez, sino que debe de realizarse las veces que sea necesario hasta que el problema est lo suficientemente comprendido como para que se pueda solucionar de manera ptima. La comprensin del problema es definitivamente la tarea mas importante que debe llevar a cabo el equipo de desarrollo pues es a partir de aqu que se edificaran los cimientos de la aplicacin, esto es la arquitectura, y tambin se podrn evaluar los riesgos existentes. Cada vez que la arquitectura se completa en una nueva iteracin se puede lanzar una versin de prueba que permite apreciar si la ruta que se est tomando es correcta as como la posibilidad de tomar en cuenta detalles que no se hubiesen apreciado antes. Esto presenta claras ventajas respecto al enfoque tradicional en el cual el cliente y el equipo difcilmente podan ver el funcionamiento de la aplicacin sino hasta el final del proceso. 2 2.2- El micro proceso. El micro proceso o proceso local, tiene un enfoque principalmente tcnico. El macro proceso provee un contexto para el micro proceso al establecer los productos intermedios y las metas hacia las cuales el equipo se dirige. El macro proceso y el micro proceso no son entidades distintas, estn entrelazados y los logros en el proceso global se obtienen a travs del proceso local. Las fases de este proceso son las siguientes: Las fases mostradas en el diagrama consisten de: Descubrimiento: Bsqueda de las abstracciones que modelen correctamente el problema. Semntica: Determinacin de la correcta distribucin de responsabilidades entre las clases y los objetos identificados hasta ese momento. Relacin: Identificacin de las relaciones entre las abstracciones. Implementacin: Representacin de cada abstraccin y mecanismo de la manera ms eficiente y elegante. El micro proceso es tambin cclico, es oportunista en el sentido que cada ciclo comienza solamente con aquello que se conoce bien, con la oportunidad de refinar el trabajo que se realiza a cada iteracin, se enfoca principalmente en roles y responsabilidades ms que en las funciones y en el control y finalmente es pragmtico esto es que se cierra un ciclo al armar regularmente porciones reales y ej ecutables. Posteriormente podremos apreciar el ciclo del micro proceso aplicado al proyecto que se esta describiendo, en particular en lo referente al descubrimiento de clases y sus relaciones. Los dos proceso anteriores resumen de manera global la metodologa que se emple durante el desarrollo del proyecto. Es importante mencionar que tambin adoptamos algunas ideas propuestas por otros autores, en particular nos referimos a aquellas que describe Scott W. Ambler en sus papeles acerca del "proceso de modelado orientado a objetos: una aproximacin manejada por arquitectura". De este autor en particular retomamos la visin de manera 'serial' del desarrollo. Aunque hemos hecho un nfasis especial en que el proceso es algo iterativo, podemos pensar que cada iteracin ocurre de una manera secuencial, que puede ser recorrida en ambas direcciones, y a partir de ello utilizamos la propuesta que nos hace el autor acerca de las tcnicas de modelado tiles en cada momento del proceso, para ello podemos referirnos al diagrama siguiente: 3 bi agr oma de casos de uso Casos de uso Pr ot ot i po de la i n t er f . de usuari o bi agr oma de componentes Di agrama de ~ +Secuenci a Prot ot i po t cni co Di agrama de dat os 1D (c) 1997 Sc o t t W. Ambler El diagrama anterior es til pues nos permite ubicarnos dentro de la etapa del macro proceso dada la cantidad de diagramas que se necesitan, aunque no todos son indispensables. 3.- Anlisis del sistema. Como hemos visto en la parte introductoria a este trabajo, el primer paso a seguir durante el desarrollo de una aplicacin es, antes que sentarse a teclear, el comprender de la manera mas completa posible las peticiones del usuario respecto a las caractersticas del producto que desea. Es evidente que durante esta etapa de desarrollo, la interaccin con el cliente es obligatoria, ya que l y las personas que harn uso futuro del producto son los que comprenden realmente las situaciones que pueden presentarse durante la utilizacin. Primeramente vamos a citar los requerimientos que se nos presentaron, para ello se realiz una pequea entrevista con el futuro usuario que expuso de manera global cuales eran sus interses. 3.1 - Requerimientos iniciales. La obtencin de requerimientos se facilita si se tiene un pizarrn disponible, y es recomendable que el cliente realice diagramas y exprese sus ideas de forma natural es decir intentando enunciar con fiases sencillas sus necesidades. Se nos pidi: Un Sistema de visualizacin 3D ampliable, esto es que pueda ser adaptable a futuros procesos de calculo. Que se pueda desplegar un stack de imgenes 2D, en su conjunto, ciertas caractersticas deben ser tomadas en cuenta, tales como la posibilidad de ver cierta imagen en detalle, o de variar el tamao del montaje. A la salida se desea obtener un conjunto de datos tridimensionales, o bien la posibilidad de generar una imagen 2D si no se realiza una reconstruccin. El usuario debe pedir datos concernientes al conjunto de imgenes (la distancia, el tamao ...) 4 Que se pueda ver el montaje antes o despus de ser procesado, as como la posibilidad de no perder la imagen original aun despus de realizar el procesamiento. Que se desplieguen histogramas de las imgenes. Que se pueda interactuar con las imgenes en su conjunto. Responsabilidades En un principio no se ha especificado de manera concreta el tipo de procesamiento que se va a realizar sobre las imgenes, dado que esta herramienta se enfoca a la posibilidad de aplicar diversos tipos de algoritmos, y de poder agregar otros ms posteriormente, una cuestin fundamental a tomar en cuenta es que el sistema sea extensible. Colaboradores 3.2 Situaciones potenciales. Las situaciones potenciales, o principales que van a ocurrir al utilizar el sistema tambin se obtienen a partir de la entrevista con el cliente, simplemente se hace una 'recopilacin de ideas', es decir, el cliente puede ir diciendo que cosas piensa que pueden suceder, estas se anotan, y posteriormente se reagruparn para el anlisis de casos de uso. Entre las situaciones ms importantes que potencialmente se pueden presentar, encontramos: Cargar datos en memoria. (Hay que introducir la informacin de los datos al cargarlos). Guardar los datos. Desplegar el stack. (Se debe poder modificar el despliegue para ver detalles u otras cosas). Realizar segmentaciones (incluye configuracin de parmetros del algoritmo). Mostrar una imgen 3D. (Incluyendo la interaccin con esta.) Mostrar el histograma de una imagen. Estas situaciones pueden parecer pocas pero involucran en realidad una gran cantidad de procesos para poder ser llevadas a cabo. Recordemos que se trata slo de las situaciones principales. Modelo CRC. El paso siguiente en el anlisis de requerimientos de una aplicacin es la creacin del modelo CRC. De acuerdo con Ambler, el modelo CRC es una coleccin de tarjetas CRC (Clase - Responsabilidad - Colaborador). Estas tarjetas se dividen en tres secciones que contienen la informacin del nombre de la clase, sus responsabilidades y sus colaboradores. A continuacin se muestra cmo se distribuye esta informacin. Una clase es cualquier persona, cosa, evento, concepto, pantalla o reporte. Las responsabilidades de 5 una clase son las cosas que conoce y las que realiza, sus atributos y mtodos. Los colaboradores de una clase son las dems clases con las que trabaja en conjunto para llevar a cabo sus responsabilidades. -No. Imagen -0atos de la Imagen Crea Copia Elimina En la prctica conviene tener pequeas tarjetas de cartn por ejemplo, que se llenarn y que se mostrarn al cliente, de manera que se pueda llegar a un acuerdo sobre la vlidez de las abstracciones propuestas. Histograma Los pasos a seguir para llenar las tarjetas son los siguientes: -Tipo de despliegue 2/30 -Parmetros de despliegue Encontrar clases Encontrar responsabilidades Definir colaboradores Definir casos de uso (situaciones potenciales). Disponer las tarjetas Stack de Imgenes Volumen 30 Para encontrar las clases debemos pensar qu cosas interactuan con el sistema (en nuestro caso el usuario), y qu cosas son parte del sistema (en un principio se propuso un stack de imgenes, un volumen 3D, un montaje y un proceso de calculo), as como las pantallas tiles a la aplicacin (un despliegue de montaje, una entrada de parmetros, un despliegue de volumen y una pantalla general). Una vez que las clases principales han sido encontradas se procede a buscar los atributos y las responsabilidades, para esto se puede formular la pregunta Qu sabe la clase? y Qu hace la clase?. Finalmente se buscan los colaboradores dentro de la lista de clases que se tenga. Para el proyecto que estamos analizando, las tarjetas CRC que se propusieron inicialmente heron las siguientes: - Oistancia - Oatos Pac. - Tom. Pixel Cargar Imgenes en Mem Admini st rar Memor ia Vista Grfica Imagen I Vista Grfica IVolumen 30 Cal cu I a Normal es Almacena en memoria datos Reorienta CargaGuardaTraduce dat. 1 imagen I I Histogroma -0atos del Histograma Imagen -Parmetros Calcula Despliega Lee Valor 1 Procesador de Imagenes I -Tipo de procesamiento I -Datos especficos al PMC I Volumen 30 Stack de Imgenes 6 Esta coleccin de tarjetas representan un intento inicial de encontrar abstacciones tiles para la resolucin del problema. Podemos ver que entre otras cosas se busco una abstraccin a la Vista Grfica, esto aparentemente podra no ser tn relevante desde un principio, pero es una buena costumbre separar las cuestiones dependientes de la plataforma (despues veremos esto con ms detalle), aparte de que esta abstraccin engloba la generalidad de las ventanas que podrn aparecer posteriormente. La definicin de casos de uso implica el estudiar qu tanta posibilidad hay de realizar las situaciones potenciales que el cliente propone mediante las responsabilidades definidas en las tarjetas. Por ejemplo, si una de las situaciones potenciales es la de cargar datos, podemos ver que la abstraccin StackDeImagenes tiene prevista esa posibilidad. Esto se debe realizar para las diversas situaciones potenciales. Se menciona que el ltimo paso a seguir es el de la disposicin de las tarjetas, efectivamente, ya que las tarjetas se pueden ordenar de diversas maneras, se debe de aprovechar esto para tratar de encontrar una estructura lgica. Por ejemplo, en el caso anterior nos podemos dar cuenta que el Stack de Imgenes ocupa una posicin importante dentro del arreglo, mientras que el histograma no tanto. Esto nos ayudara posteriormente durante la representacin del diagrama de clases para encontrar similitudes entre clases o relaciones entre ellas. 3.4- Anlisis de casos de uso. Otra de las herramientas esenciales para obtener una mayor comprensin del problema son los digramas de casos de uso. A continuacin se da una definicin y se muestra tambin como fueron empleados para la realizacin de la aplicacin. 3.4.1 Introduccin. Los casos de uso como los describe Karl E. Wiegers son ''escenarios en los cuales el usuario interacta con el sistema que se est definiendo para lograr cierto objetivo especfico o realizar alguna tarea en particular". El mtodo que seguimos en nuestro desarrollo es el siguiente: a partir de entrevistas con los futuros usuarios del sistema, se intentan descubrir las diversas situaciones que se puedan presentar durante la utilizacin del sistema. Por ejemplo, si el cliente menciona la necesidad de cargar archivos desde el disco, entonces una de las situaciones de uso potenciales del sistema ser: "El usuario carga un archivo de datos". Ntese que los escenarios se describen como enunciados en el lenguaje del cliente. Una vez que se obtienen la mayor parte de las situaciones (recordemos que la naturaleza cclica del proceso implica que posteriormente podran aparecer nuevas situaciones que no hubiesen sido contempladas durante la primera aproximacin, y que por ello se deben realizar varias entrevistas con el cliente), debemos intentar reagruparlas y encontrar casos de uso generales que abarquen varias de las situaciones antes encontradas. As, el escenario de caso de uso es una instancia del caso de uso general. Hemos visto como los casos de uso son escenarios que se pueden presentar durante la utilizacin del sistema, pero tambin debemos tomar en cuenta a los actores. Un actor, de acuerdo con la definicin que encontramos en el tutorial de UML (www.rational.com), es "alguien o algo que debe interactuar con el 7 sistema en desarrollo". As, podemos pensar por ejemplo en que un doctor es un actor en un sistema mdico. Estos dos componentes, actores y casos de uso sern entonces representados en diagramas llamados 'diagramas de casos de uso'. En estos diagramas se muestran los actores y los casos de uso, as como las relaciones que existan entre ellos, pues no todos los actores estn relacionados con todos los casos de uso. Tambin existen relaciones entre los casos de uso, destacan dos tipos distintos, aquellas de <uso y las de extensin. Las relaciones de USO muestran comportamientos que son comunes a uno o ms casos de uso, las relaciones de extensin muestran comportamientos opcionales. 3.4.2- Descripcin de los casos de uso. Enseguida veremos como se aplic lo antes mencionado dentro del proyecto. Para comenzar, retomamos las situaciones potenciales de utilizacin del sistema, pero detallandolas ms, primero se muestra el nombre del caso de uso y enseguida sus instancias: Caso de uso: Transferencia de Datos - El usuario introduce un stack de imgenes. - El usuario guarda un stack de imgenes (procesadas o no). - El usuario guarda los datos de la reconstruccin (volumen). - El usuario carga una reconstruccin. Caso de uso: Seleccionar Parmetros - El usuario introduce los datos del stack de imgenes. - El usuario selecciona un tipo de procesamiento y los parmetros especficos al proceso. - El usuario selecciona parmetros diversos del despliegue. Caso de uso: Procesar Datos - El usuario realiza una segmentacin. - El usuario realiza una reconstruccin. Caso de uso: Interactuar con Datos - El usuario interacta con la imagen 3D (rotacin...). - El usuario interacta con la imagen 2D (seleccin ...) - El usuario interacta con el histograma. Caso de uso: Desplegar Datos - El sistema despliega datos en forma de montaje (2D). 8 - El sistema muestra datos en forma de imagen 3D. - El sistema muestra datos en forma de histograma. En lo que concierne a los actores, para nuestro proyecto solo tenemos un actor que es el usuario. El diagrama a continuacin muestra los casos de uso ,sus relaciones as como al actor antes mencionado. a Transferencia de Datos 3.5- Prototipo de la interfaz de usuario. Es importante presentar al futuro clientehsuario un prototipo de la interfaz que tendr la aplicacin. Para ello se puede hacer uso de los digramas de flujo de la interfase, que muestran que interfases irn apareciendo dependiendo de las acciones que tome el usuario. En este caso, el requerimiento para la interfaz de usuario es sencillo, bsicamente se trata de una ventana con un rea grfica en donde se vern las imgenes con las que se esta trabajando y un men a partir del cual se pueden realizar las acciones tales como cargadguardar, seleccionar procesos y ayuda. 9 Posteriormente se tendrn que agregar nuevas ventanas ya que cada proceso necesita ser configurado de manera distinta. Para realizar un prototipo simplemente se debe de dar al usuario una idea de la apariencia de la aplicacin, esto es como un 'esqueleto' no funcional, para facilitar esto es recomendable hacer uso de alguna herramienta de constmccion de interfases de usuario, tal como Visual C++, o en nuestro caso "form design", de xforms. 3.6 Anlisis de clases. Otro paso fundamental dentro de la etapa de anlisis del sistema es la de la realizacin de un diagrma de clases 'inicial', en realidad este diagrama retoma las tarjetas CRC que se realizaron anteriormente, tomando en cuenta su disposicin, as como el estudio de los casos de uso y finalmente el estudio a nivel generalizado del comportamiento en el tiempo de los objetos instanciados a partir de las clases, como veremos adelante. 3.6.1 Determinacin de las clases. Lo que se hace para pasar de las tarjetas a clases, es tomar cada tarjeta, y crear una clase para ella. Los atributos y responsabilidades de la clase se encuentran a partir de las responsabilidades de la tarjeta CRC. Las relaciones entre clases aparecen a partir de los colaboradores. En este momento tambin pueden descubrirse atributos comunes entre abstracciones y en ese caso es conveniente pensar en alguna abstraccin a nivel superior de la cual hereden las clases que compartan atributos. En nuestro caso podemos pensar que el Volumen 3D, el Stack de Imgenes y el Hstograma son todos colecciones de datos, que comparten responsabilidades tales cmo el desplegarse, cargar datos y almacenarlos. Por ello desde un principio decidimos reagruparlos al hacerlos heredar de una clase abstracta llamada Coleccion de Datos. Esto permitir posteriormente simplificar el estudio de las instancias de esta clase, por ejemplo al realizar el digrama de secuencia de cargado de datos, pues todas las clases hijas lo realizarn de la misma manera. A continuacin se mencionan las clases propuestas con detalle. 3.6.2 Diccionario de datos de las clases. El diccionario de datos de las clases simplemente detalla cada una de las clases que se han descubierto, se muestra el nombre de la clase (que por convencin se hace con un 'C-' y el nombre con mayusculas en sus letras iniciales y sin espacios), sus atributos y sus operaciones. No se da an un tipo de dato para los atributos pues esto es parte del diseo. (Esto se hizo siguiendo un ejemplo de la Universidad de Munich.) Nota: Dentro de las operaciones no se muestran aquellas que permiten tener acceso a los atributos, se supondr que para cada atributo hay operaciones que realizan dicha tarea. Otra cosa importante es que C Punto y C Color no habian sido descubiertas como abstracciones originalmente, pero dado que el vzmen y echistograma son clases instanciadas a partir de CColeccionDeDatos, necesitan hacer uso de otra clase para su instancia, por ello se incluyen en el diccionario. La aplicacin es una abstraccin general del sistema y es conveniente representarla desde el inicio. Nombre: otras). Atributos: Datos Un arreglo de datos de tipos variados. Operaciones: CargaDatos Carga los datos a partir del disco. GuardaDatos Guarda los datos en el disco. CambiaDatos Cambia los datos. DespliegaDatos Despliega los datos. Configura Configura la coleccin si es necesario. C - ColeccionDeDatos Una coleccin de datos (es una clase abstracta de donde se derivan Nombre: Atributos: C-StackDeImagenes Una coleccin de imgenes. Hereda de C-ColeccionDeDatos. NumeroDeImagenes El nmero total de imgenes del stack. TamanoDeImagen El tamao de la imagen (en puntos). DistanciaEntreImagenes La distancia entre dos cortes (en mm). DatosDelPaciente Pequeo texto para datos tiles. TamanoDelPixel Tamao de un pixel (en mm). TamanoDelDato Formato de imgen (bytedpixel). Nombre: C Imagen Una imagen. Atributos: Operaciones: DatosDeImagen Informacin que define la imgen NumeroDeImagen Un nmero que identifica la imgen dentro del stack. Copia copia los datos de la imagen a otra o desde otra. Nombre: Atributos: C volumen3D Una coleccin de puntos en el espacio 3D. umeroDePuntos El nmero de puntos del que se compone el volmen. Orientacin La orientacin del volmen en el espacio. Normales Las normales a los puntos. Operaciones: Cambiaorientacin cambia la orientacin del volumen3D Nombre: Atributos: CoordX La coordenada X CoordY La coordenada Y CoordZ La coordenada Z C-Punto Un punto en el espacio tridimensional. Nombre: Atributos: Operaciones: C-Histograma La informacin de una imagen representada como histograma. ImagenFuente La imagen a la cual se le calcula el histograma. Calcula Calcula el histograma para la imagen dada. Nombre: Atributos: C Color Un color definido como tres niveles, R, G y B. ivelR La componente roja del color. NivelG La componente verde del color. NivelB La componente azul del color. Nombre: Atributos: Operaciones: CProcesadorDeImagenes Se encarga de aplicar procesos sobre colecciones de datos. TipoDeProceso Identifica el tipo de proceso que se va a aplicar. AplicaProceso Aplica un algoritmo o proceso determinado. SeleccionaProceso Selecciona uno de los posibles procesos a aplicar. Configura Asigna los parmetros necesarios al proceso. Nombre: Atributos: Operaciones: Abreventana Abre una ventana. C VistaGrafica Se encarga de toda la interaccion visual. TipoDeDespliegue Define el tipo de interfase a presentar. EsperaInteraccion Recibe la interaccion. EnviaDatosAVentanaGrafica Despliega datos de la coleccion. Nombre: C-Aplicacion Operaciones: Inicia Inicia la aplicacin. 3.6.3 Diagramas de secuencia. Hemos definido las abstracciones iniciales para la aplicacin, pero debemos encontrar cual ser el tipo de relacin que existe entre estas abstracciones. Una herramienta til para aclarar este punto son los diagramas de secuencia. Estos diagramas muestran los mensajes que se intercambian las instancias de las clases durante el tiempo. Desde un principio intentamos aclarar qu tipo de relacin existe entre las abstracciones. (Vanse algunos conseios). Una aproximacin uti1 es de realizar un diagrama de secuencia por cada caso de uso o que sea representativo de cada uno de estos. En nuestro caso vamos a escojer los siguientes: Cargar o Guardar una coleccin de datos (de Transferencia de Datos). 12 Interaccin y despliegue de los datos . Aplicar un proceso (involucra Seleccionar Parametros y Procesar Datos). Normalmente los mensajes que se ven en los diagramas de secuencia deben corresponder estrechamente con las operaciones disponibles para cada clase, pero en esta etapa en la que an se est buscando comprender bien el problema, pueden aparecer mensajes textuales que posteriormente sern refinados y corresponderan a funciones concretas de cada clase. Se presenta primeramente un diagrama 'general' de la aplicacin que muestra de manera global la interaccin entre el actor y la aplicacin y enseguida se muestran los dems. Los diagramas de secuencia son los siguientes: R : Usuario I I I I I I I I I I I I "Pide datos del stack" I I "Abre un archivo" Abreventana( ) --. /- I I n- I CargaDatos( 1 'r' I I 7 I DespliegaDatos( 1 I I I I I I I I I I I I I I I I I I I I I I I I 13 Diagrama de secuencia Cargar/ Guardar Datos. Vista: C Vista R : Usuario I I I I I I I I I I I I I I I I I Esperalnteraccion( ) U I I I I I I I I I C ColeccinD eDatos I I I I I I I I I I I I CambiaDatos( ) \ i EnviaDatosAVentanaGrafica( ) I I I I I I I I I I I I Diagrama de secuencia: Interactuar y desplegar datos. 14 A Delmaqenes : Usuario I I I "Aplica Proceso" \ .-- I Abreventana( ) \ I I Espe,ralnteraccion( 1 I SeieccionaProceSo( I \ I I I "Introduce Parametros" I Configura( I I rP I I I J I I I I I I I I I I I :plicaPjoceso( ) I CambiaDatos() I I I I I I I I I I I I I I I I I IP I I I I I I I I I I I I I I I I I EnviaDatosAVentanaGrafica( ) 'u 1 I I I I I I I Diagrama de secuencia: Procesar Datos. 3.6.4- Diagrama de Clases Terminamos la etapa de anlisis con un diagrama de clases que muestra las abstracciones mnimas propuestas para la resolucin del problema, as como las relaciones que existen entre ellas. El diagrama es el siguiente. 15 ^--" - -- -- , '*, '< 3.7 Conclusin del anlisis. El anlisis es una etapa fundamental dentro de la realizacin de una aplicacin, esta etapa se puede resumir en una sola fiase: Entender el problema. Cuando terminamos el anlisis tenemos ya una comprensin mayor del problema, sabemos cuales son las abstracciones claves, y empezamos a estudiar como se desenvuelve la aplicacin en el tiempo. Es aconsejable documentar esta etapa incluyendo en la documentacin los varios resultados como los que obtuvimos aqu. La etapa siguiente es la del diseo, cuyo objetivo principal es de construir un diagrama de clases mas detallado, refinado y orientado a la implementacin partiendo del diagrama de clases de anlisis, y es la que se ver a continuacin. 4.- Diseo del sistema. Comenzaremos la parte del diseo citando a G. Booch : "El propsito del diseo es de crear una arquitectura para la naciente implementacin, [ .. .] el diseo arquitectura1 slo puede comenzar una vez que el equipo tenga un entendimiento razonable de los requerimientos del sistema. [...I El diseo, como el anlisis, nunca termina realmente hasta que el sistema final es entregado. Durante esta fase, se alcanza un cierto grado de culminacin al poner en su 16 lugar la mayora de las decisiones estratgicas de diseo y al establecer polticas para diversos problemas tcticos. [...I El diseo se enfoca en la estructura, esttica y dinmica, su propsito principal es de crear el 'esqueleto' concreto del sistema sobre del cual todo el resto de la implementacin se basa." Estas palabras definen claramente qu es el diseo, la creacin de la estructura bsica del sistema es la tarea clave, aunque tambin se buscan otras cosas, en particular patrones que simplifiquen el diseo y posibilidades de reuso entre otras. Durante la etapa de diseo vamos a refinar las partes fundamentales para la aplicacin. Para lograrlo, es conveniente comenzar a buscar patrones de diseo, a continuacin describimos esto de manera ms detallada. 4.1 Patrones de diseo. De acuerdo con el libro 'Design Patterns' , un patrn es una "solucin simple y elegante a problemas especficos dentro del diseo de aplicacines orientadas a objetos, los patrones capturan soluciones que han sido desarrolladas y han evolucionado a lo largo del tiempo, de ah que normalmente no son el tipo de soluciones que se tienden a generar de manera inicial, reflejan el trabajo de los desarrolladores que han luchado por obtener una mayor posibilidad de reuso y flexibilidad en su software. Los patrones de diseo capturan estas soluciones de una manera fcil de aplicar." Una vez que se ha terminado con el anlisis, conviene detenerse a estudiar el resultado principal de esa etapa, es decir el diagrama de clases de anlisis. Es importante buscar que partes pueden ser mejoradas mediante el uso de algn patrn de diseo. Para ello es til consultar algun catlogo de patrones y mediante sus descripciones tratar de encontrar alguno que se ajuste o que provea alguna solucin al problema que se tiene. En nuestro caso particular, buscamos en el libro 'Design Patterns' y al leer las descripciones nos encontramos con la siguiente: Estrategia (315) Define una familia de algoritmos, encapsula cada uno, y los hace intercambiables. La estrategia permite que los algoritmos varien independientemente de los clientes que los utilizan. Al mirar de manera ms detallada su descripcin, vemos que se recomienda aplicar este patrn entre otras cosas cuando: Varias clases relacionadas difieren slo en su comportamiento. La estrategia provee una forma de configurar una clase con uno o ms comportamientos. Se necesitan multiples variantes de un algoritmo. Un algoritmo usa datos que los clientes no deben conocer. El patrn puede ser utilizado para evitar exponer complejas estructuras de datos especficas al algoritmo. Si recordamos los requerimientos de la aplicacin, nos viene a la mente el hecho de que es importante poder aplicar algoritmos diversos, y se deben poder agregar ms posteriormente. Este patrn parece ofrecer una solucin adecuada al problema que se nos presenta. Continuemos estudiandolo con ms detalle. El diagrama de clases del patrn es el siguiente: 17 , I Contexto --. Estrategia InteifaseDelConte~o()I I lnteraseDelAlgoritmo() I A lnterfaseDelAlgoritmo() r I lnterfaseDelAlgoritmo() I I lnterfaseDelAlgoritmo() I I EstrategiaConcretaA I I EstrategiaConcretaB I I EstrategiaConcretaC I Los participantes son: Estrategia - Declara una interfase comn a todos los algoritmos soportados. El Contexto usa esta Estrategiaconcreta - Implementa el algoritmo usando la interfase de estrategia. Contexto - Se configura con un objeto Estrategiaconcreta, mantiene una referencia al objeto Estrategia y puede definir una interfase que permita que Estrategia tenga acceso a sus datos. interfase para llamar al algoritmo definido por una Estrategiaconcreta. La colaboraciones son: Estrategia y Contexto interactuan para implementar el algoritmo deseado. Un contexto puede pasar todos los datos requeridos por el algoritmo a la Estrategia cuando el algoritmo es llamado. De manera alternativa, el contexto se puede enviar a si mismo como argumento a las operaciones de Estrategia, esto permita que la Estrategia llame al Contexto cuando lo requiera. Un contexto pasa las peticiones de sus clientes a su estrategia. Los clientes normalmente crean y pasan un objeto Estrategiaconcreta al Contexto; de ah que los clientes interactuen con el contexto exclusivamente. Normalmente hay una familia de clases Estrategiaconcreta de las cuales un cliente puede escoger. Funcionamiento : Este patrn funciona de la manera siguiente: Al crear la instancia del contexto, este instancia a su vez alguna de las EstrategiasConcretas. Ahora cuando se llama a InterfaseDeContexto, esta a su vez llamara a InterfaseDeAlgoritmo y automticamente se seleccionar la interfase deseada, sin necesidad de recurrir a sentencias condicionales (switch-case) para la seleccion del algoritmo correcto. usos: Este patrn se adapta bien al problema de aplicar mltiples algoritmos. Tambin puede ser utilizado para la creacin de ventanas. Problemas: La desventaja que presenta este patrn para el problema que se nos presenta es que este patrn se limita a la seleccin de una sola de las estrategias que queda intimamente asociada al objeto Contexto. En nuestro caso en particular, no deseamos que slo se pueda crear un algritmo que se quede instanciado durante toda la aplicacin. Sin embargo, la idea de presentar una interfaz comn a todos los clientes es muy interesante, as que proponemos una ligera modificacin al patrn, cuyo diagrama de 18 clases se muestra a continuacin: Estrategia ----- lnterfaseDelContexto() lnterfaseDelAlgoritmo() A [-terfaseDelAlgoritmo() 1 1 I nterfaseDeiAlgoritmo() I [InterfaseDelAlgoritmo() 1 Como podemos apreciar, ahora la relacin que existe entre el Contexto y la Estrategia ya no es una agregacin, sino una relacin de uso. Esto sucede por que en la operacion InterfaseDelContexto se crea la instancia de la Estrategia, y esta se destruye al terminar la operacin, de ah que sea una relacin de uso. El Cliente tiene una referencia del Contexto y as puede acceder a su InterfaseDelContexto. Cuando un cliente hace uso de esta interfase, pasa una referencia de s mismo de tal forma que el Contexto a su vez se la transmita a la Estrategia al instanciarla. El resultado es que cualquier Estrategiaconcreta conoce a su cliente y puede acceder a sus operaciones. A diferencia del patrn Estrategia convencional, este es ms flexible, pues el Contexto se instancia una sola vez (probablemente por la aplicacin), y este se encarga de crear y destruir las instancias de Estrategiaconcreta que cree, pero se pueden solicitar las diversas estrategias cuantas veces sea necesario, y el cliente puede ser cualquiera que tenga una referencia al contexto. 4.2 Aplicacin de los patrones. Una vez que hemos encontrado soluciones aplicables al problema que estamos tratando de resolver las tenemos que incorporar al modelo resultante del anlisis. Si estudiamos el digrama de clases propuesto en la parte de anlisis, notamos que existen tres 'partes' principales en el problema; estas son: La coleccin de datos y las clases que se derivan de ella. La vista grfica que se encarga de la interaccin con el usuario y el despliegue. El procesador de imgenes que se encarga de la modificacin de los datos. Primeramente estudiaremos cmo se aplica el patrn descrito anteriormente en la vista grfica y en el procesador de imgenes, afortunadamente fue posible aplicar el mismo patrn para resolver dos problemas aparentemente distintos como se describe a continuacin. 4.2.1 El maneiador de ventanas. 19 Uno de los puntos que recalcamos desde el inicio del anlisis fue el de tener una abstraccin para la vista que llamamos VistaGrafica. La ventaja de hacer una abstraccin de la parte interactiva es que podemos separarla de las dems clases, y sobre todo, podemos aislar el cdigo que depende de la plataforma, puesto que normalmente las interfases de usuarios son una de las partes ms dependientes de la plataforma que hay en la aplicacin. Basndonos en el patrn estrategia, que 'define una familia de algoritmos, encapsula cada uno y los hace intercambiables de tal forma que los algoritmos varien de manera independiente de los clientes que los usan', realizamos una interfase comn a todas las ventanas, esta interfase la provee la clase 'ManejadorDeVentanas'. A continuacin se muestra el diagrama de las clases que involucran esta solucin. Podemos ver que se tiene la misma situacin que se describi anteriormente en el patrn Estrategia modificado. La aplicacin crea la instancia del manejador, que ser nico en la aplicacin. Cualquier clase que necesite algun tipo de interaccin por parte del usuario tiene que conocer al manejador de ventanas, la aplicacin se puede encargar de proveer una referencia a este. Se muestra aqui que la C ColeccionDeDatos tiene una referencia al manejador, as, cualquier clase instanciada a partir de esta podr pedir interaccion. La interfase comn del manejador es la funcin Seleccionaventana(), a travs de esta funcin cualquier objeto puede pedir que se cree una ventana. Aunque no se muestra aqu, la ventana tiene una referencia de la clase cliente, de tl forma que pueda comunicarse con l. Una vez que se llama a SeleccionaVentana(), el manejador sigue siempre una serie de pasos idnticos: 1 .- Instanciar la ventana, dandole a conocer a su cliente. 2.- Abrir ventana 3.- Activarla (entrar al ciclo de espera de eventos y recibir interaccin por parte del usuario). 4.- Cerrar la ventana. 5 .- Destruir la instancia. 20 Al activarse la ventana, esta espera interaccin por parte del usuario, y dado que tiene una referencia a un cliente, puede modificar atributos de la clase cliente. Una ventaja de esta solucin es que un cliente puede pedir varias ventanas diferentes, otra es que el cdigo especfico de las ventanas se queda dentro de la implementacin de la ventana y el cliente no tiene ningn conocimiento de cmo se realiza esto. C-ProcesadorDelmagenes 9 --- Asig naM anejador () Se1 eccionaProceso() C-ProcesadorDelmagenes() 4.2.2 El procesador de imgenes. C-Proceso Asignacliente() AsignaManejadorO inicializa() EjecutaProceso() C-Proceso() Otra parte en donde el patrn expuesto anteriormente facilit una solucin elegante fue en la aplicacin de algoritmos. De la misma manera que para las ventanas, es necesario poder crear diversas instancias de los algoritmos y aplicarlas a clientes distintos. El diagrama de clases que muestra como qued esta solucin es el siguiente: C-Aplicacion Y I En este digrama la relacin entre dos procesos que tienen como cliente al Stack de imgenes, pero debemos recordar que el cliente no forzosamente es de un tipo nico. De igual forma que el ManejadorDeVentanas sigue unos pasos establecidos al instanciar una ventana, el ProcesadorDeImagenes tambin sigue una serie de pasos cuando se le solicita algn proceso a travs de SeleccionaProceso(), estos son: 21 1 .- Instanciar el proceso. 2.- Darle a conocer su cliente. 3.- Darle a conocer el manejador de ventanas. 4.- Inicializar el proceso. 5.- Ejecutarlo. 6.- Destruir la instancia del proceso. Es interesante notar que los procesos normalmente requieren interaccin por parte del usuario, es por ello que se necesita 'darles a conocer' al manejador de ventanas, para que puedan solicitar una ventana. En lo que se refiere a patrones, esto es todo lo que se empleo durante el diseo. Esto no significa que no se puedan encontrar ms patrones utiles para la aplicacin, y de hecho, se debe tratar de emplear la mayor cantidad posible de ellos, pues como ya mencionamos anteriormente, son soluciones ya probadas y de ah que sea ventajosa su utilizacin. 4.3 El rea grfica. Hemos visto en el punto anterior como se ha ampliado la abstraccin relacionada con la vista. Sin embargo, hay dos aspectos distintos en lo que concierne a las vistas, el primero son las ventanas a travs de las cuales se recibe interaccin por parte del usuario, pero dentro de estas puede encontrarse un rea en donde se desplieguen grficas. Puesto que desde un principio se penso aprovechar el hecho de que la plataforma en la que se deseaba implementar la aplicacin posee hardware de aceleracin de grficas, y pensando tambin en aspectos de portabilidad a futuro, es conveniente separar todo lo relacionado a la graficacin en una nueva abstraccin. Esta abstraccin encapsula todos los comandos que se encarguen de realizar grficas. Otra ventaja de hacer esto es que se pueden cambiar las librerias de grficas o de interaccin sin que se afecten mutuamente. Es interesante notar que normalmente las librerias de interfases con el usuario no tienen la capacidad de dibujar grficas de alto rendimiento. De ah que hayamos decidido tener una clase llamada C-AreaGrafica. Esta clase se encarga de administrar todo lo que aparece dentro de las reas de dibujo. Todas las ventanas que necesiten desplegar grficas tendrn una instancia de esta clase (o varias si es necesario). La coleccin de datos tambin tendr una referencia a esta clase, as cualquier objeto instanciado a partir de una de las clases derivadas de esta podr pedir ser desplegado. El rea grfica deber tener operaciones que permitan desplegar los diversos tipos de objetos, as, podr desplegar un volmen, una imagen, un histograma, etc.. . Tambin tendr posibilidades de realizar algunas 'primitivas' grficas, cmo dibujo de lineas y puntos por ejemplo. A continuacin se muestra un diagrama de clases donde se detalla lo descrito anteriormente. 22 _ _ - - - - _ 4.4 Refinamientos de la coleccin de datos. En el punto anterior hemos hecho nfasis en el mejoramiento de las abstracciones concernientes al manejo de la interaccin y de l os procesos. Esto consituye dos de las partes principales dentro del diagrama de clases de anlisis, sin embargo, tambin debemos refinar la parte de la coleccin de datos, que es en cierta forma el hucleo' de la aplicacin. 23 Veamos de nuevo cmo se defini esta parte en el diagrama de clases de anlisis. I f I f i f f f f / i' i f J f En esta propuesta inicial se reagrupo el Stack, el Volumen y el Histograma, dado que todos son en el fondo un arreglo de distintos tipos de dato, se penso que podian ser todos instancias de la clase CColeccionDeDatos, sin embargo, durante la etapa de diseo se cuestiono nuevamente la necesidad de que el Histograma formase parte de las clases derivadas de la coleccin de datos. Varios puntos revelan que esto no es totalmente necesario. En particular se pueden mencionar: No es necesario cargar y guardar datos de un histograma ya que estos se calculan rpidamente y dependen de una imagen. El guardar el histograma y la imagen juntos no es algo muy prctico. No es necesario que las imagenes siempre tengan un histograma calculado, pues esto podra utilizar memoria inutilmente. Normalmente slo se van a emplear histogramas para imgenes con tonos de gris, por lo que el tipo de dato que compone su arreglo ser ms probablemente alguno de los tipos 'nativos' (int, char), esto permite hacer objetos de un tamao menor y no es tan necesario instanciar la clase abstracta con uno de estos tipos de datos, es ms sencillo implementar un arreglo 'comn y corriente'. El histograma se puede entonces simplificar y ya no es necesario instanciar esta clase a partir de la C ColeccinDeDatos. Esto no invalida de ninguna manera la razn de existir de la CColeccionDeDatos. Simplemente ser empleada para clases que necesiten las caracteristicas que provee. El volmen y el stack sern por el momento las nicas clases que se instancien a partir de ella, pero existe la posibilidad de crear otras clases posteriormente. Entonces el nuevo diagrama de clases de la coleccin de datos es el siguiente: r--- ,Dato I I J C- CoieccbnDeDafosT / /-- / \ \ \ \ \ \ C-Imagen ? 2 5 C-Histograma C Punto En este detalle podemos ver como quedaron las diversas clases. Es importante notar que las clases C Punto y CI magen heredan a partir de C-DatoDeColeccion. La razn por la cual sucede esto es por qi e la C-ColeccinDeDatos delega varias de las responsabilidades a los objetos que componen su 25 arreglo y estas pueden no ser forzosamente necesarias. El heredar de C-DatoDeColeccion garantiza que al ser llamadas estas funciones por la clase instanciada no se producira un error debido a que no estan declaradas. Las operaciones que declara C-ColeccionDeDatos son las siguientes: ReservaMemoriaO LiberaMemoriaO CargaDatosO GuardaDatosO 4.4.1 El arreglo como lista ligada. En la parte de anlisis de la aplicacin se menciono que la Coleccin de datos era una clase que representaba un arreglo de datos de tipo diverso. No se menciono nada sobre la forma en que se almacenaban estos datos. Una solucin al problema fue emplear una estructura de datos para almacenar los elementos. As la coleccin recibe los mensajes tales como las peticiones de datos, y los pasa a la estructura de datos que se encarga de hacer la bsqueda. La ventaja de esto es que la estructura de datos queda encapsulada y puede ser cambiada sin repercusiones para el resto de la aplicacin. Otra ventaja es que la estructura puede llevar el control sobre la memoria que se esta empleando y se evita perder memoria que no se libere. La estructura elegida fue una lista ligada pues la coleccin representa en cierta forma un arreglo 'linear' de datos. La coleccin tiene entonces una lista ligada agregada. A continuacin se muestra la coleccin junto con la lista ligada. riato n I 4.5 Diagramas de secuencia. Hemos terminado de estudiar los refinamientos que se hicieron sobre las abstracciones. En esta etapa, las clases tienen ya definidas las operaciones que en la parte de anlisis eran slo 'frases'. A continuacin se presentan nuevos diagramas de secuencia en donde se aplican las modificaciones que acabamos de realizar. Para empezar, se muestra el diagrama de inicio de la aplicacin. 26 A ~ G Z Z I ~ I ~ 1 ~ 1 ~ 1 De lrna genes P ri n ci I) a I StackDelrna enes : Usuario niciaAplicacion0 StackDelrnagenesO ' -Aplica cin0 I Abreventanao Acti vl Vent. n. U 7 "Recibe interaccin por el usuario" IP En este diagrama podemos ver como la aplicacin crea las instancias del manejador, del procesador y del stack con el que se va a trabajar. Enseguida, la aplicacin le pide al manejador que se cree la ventana correspondiente, y esta entra en su ciclo de espera. Cuando la aplicacin termina, se ve como se destruyen los objetos. Diagrama Cargar Datos: 27 P Cambi aNombreDel Archi voO / . : Ci erravent anao Abrevent anao j Adi vaVe nt anao o Sei ecci onavent anaoi " Pi de pa r m etrod' ,"Inserta parmetrod' : U ' / : ConfiguraFormatoO . u- ' Ci erravent anao >- En este diagrama vemos como la instancia de alguna de las clases derivadas de la coleccin, al recibir el mensaje de carga de datos, pide una ventana (recordemos que la ColeccionDeDatos tiene una referencia al manejador), a travs de la cual obtendr el nombre del archivo de donde se cargaran los datos. No vamos a presentar el diagrama de Guardar Datos, ya que se trata esencialmente de la misma situacin. Diagrama: Aplicacin de un proceso. 28 En este diagrama podemos ver cmo se selecciona el algoritmo, se instancia el proceso, se pide una ventana para llenar los parmetros y finalmente se aplica. 4.6 Diagrama de clases. De la misma manera que se cerro el ciclo de anlisis, se termino la etapa de diseo con los diagramas de secuencia y con un diagrama de clases ms completo que se presenta a continuacin. 29 ~~~ ~ 4.7 Conclusin de la etapa de diseo. Al terminar la etapa de diseo, hemos refinado suficientemente el diagrama de clases y las relaciones entre estas. Tambin conocemos mejor los mensajes que se intercambian los objetos para realizar las tareas necesarias. Durante la siguiente etapa nuevamente entraremos en otro ciclo para mejorar algunos detalles que se hacen visibles slo al momento de la implementacin. 5 .- L a implementacin. - La etapa que normalmente se espera ms dentro de la creacin de una aplicacin es la de la implementacin, sin embargo es importante haber llegado a un buen avance de las partes que la preceden para evitar 'improvisar' el cdigo. Normalmente no se debe crear una aplicacin desde cero, se puede utilizar alguna herramienta que escriba el cdigo a partir de los diagramas de clases (por ej. Rose), o bien un entorno de desarrollo que cree un 'esqueleto' de la aplicacin (ej. Visual C++) . Por desgracia en nuestro caso en particular, disponiamos solamente de una herramienta para la creacin de ventanas llamada fdesign. Durante la etapa de implementacin, se hizo nfasis en los siguientes puntos principalmente: 30 Crear clases en la 'punta' de la jerarquia para permitir paso de referencias a los objetos. Encapsular la libreria de interfase con el usuario dentro del modelo. Optimizar el despliegue de grficos. Permitir el uso de multiples formatos de imgenes. Aprovechar la estructura de datos en los lugares donde se requerian arreglos. Permitir que la configuracin del stack organizara el despliegue de este. Vamos a ver con detenimiento cada uno de los puntos mencionados y explicar cmo se lleg a una solucin. 5.1 Las clases C Ob-ietoInteractivo y C Ob-ietoModificable. En la etapa de diseo definimos la estructura de clases que se acerca a lo que podemos llamar 'definitivo'. Sin embargo, existen algunos problemas que surgen en el momento de la implementacin a nivel del paso de referencias a objetos. Si recordamos el funcionamiento del manejador de ventanas, este es capaz de instanciar ventanas para diversos tipos de clientes, pero a nivel de cdigo, esto puede presentar alguna dificultad. Para resolverla, se decidi crear una nueva clase, de la cual hereda cualquier objeto que pretenda hacer uso del manejador, su nombre es C-ObjetoInteractivo. De esta forma, el manejador recibe una referencia a C-ObjetoInteractivo y as, cualquier objeto que haya heredado de esta clase entra en la categora. Aprovechando esta clase, se le incluy una referencia a C-Ventana, de igual forma que lo mencionado anteriormente, cualquier ventana puede entrar dentro de esta categora, adelante veremos cuando se utiliza esta referencia. Finalmente, la clase tiene tambien un identificador a la ventana que se tiene asociada. A continuacin se muestra la declaracin de esta clase. cl ass C- Obj et oI nt er act i vo t pr ot ect ed: i d - vent I dvent ana; C - Vent ana *Vent anaAsoci ada; i d - vent LeeI dVent anaO {r et ur n I dvent ana; } voi d Asoci aVent ana( C- Vent ana *ApVent ) {Vent anaAsoci ada=ApVent ; } publ i c: 1; Esta misma estrategia se empleo para el paso de referencias dentro del procesador de imgenes, para ello se emplea otra clase llamada C-ObjetoModificable. Hay que notar que un objeto interactivo no es necesariamente modificable por algun proceso y viceversa. El objeto modificable slo contiene un identificador de la clase cliente. 5.2 Encapsulando la interfase de ventanas. Un problema dificil con el cual nos topamos durante la implementacin fue el de encapsular la librera de interfase de ventanas dentro del modelo. A continuacin, se muestra un diagrama que muestra el procedimiento a seguir para obtener interaccin por parte del usuario, se trata del diagrama de secuencia de la interaccin con la ventana principal. 31 m VentanaAotual : C I VentanaPrinciDai 1 8 Interaccion ... s las acciones ms impotiantesya que hay comunicacion co n otros objetos. C-VentanaPrincipal() : . Asi gnaAr eaGr af i ca( C- Ar eaGr af i ca) i c .. .- . .- DespachaCallbadQ) - / I Menupesplie g u e(int) U' / Men+Procesa<int) u- u- / Me nb Arch iuo(int) J : Fin de interaccioh ... : -C-Apiicacin() i U? CanuasHandlei() I i I i On-MENU-DE SPLIE GUE( ) On-M ENU-PRO CESAR( ) On-MENUARCHIVO() RefrescaAreaGrafica( ) - I I I I Callbackse encarga de llamar a las funciones atribuidas a cada objeto de la intetfaz de usuario. Nos e han detallado todas, slo aquellas que a su vez llaman alguna funcin de I I En este diagrama podemos ver cuales son los pasos que debe seguir un objeto que desea interaccin por parte del usuario. Primero, debe llamar a la funcin SeleccionaVentana() del manejador, le envia dos parmetros, un identificador de la ventana que desea abrir (definidos en el archivo General.h), y una referencia al objeto que va a ser el cliente, en este caso se trata de si mismo, por eso se envia 'this' (puede ser una referencia a otro objeto que a si mismo). Del lado del manejador, se procesan las peticiones de la manera siguiente: bool CManej ador DeVent anas: : Sel ecci onaVent ana( i d- vent sel ecci on, C- Obj et oI nt er act i vo* Cl i ent e) { C- Vent ana *Vent anaAct ual ; bool Ret Val ; despues de que se ci er r a. swi t ch( se1ecci on) I // El val or que r egr esa l a vent ana case I DV - APLI CACI ON: CApl i caci on: : I ni ci a( ) // LLamada r eal i zada por Vent anaAct ual =new C- Vent anaPr i nci pal ( C1i ent e) ; 32 Cl i ent e- >Asoci aVent ana( Vent anaAct ual ) ; br eak; case I DV- SEL- ALGORI TMO: CApl i caci on: : Menu- Pr ocesar ( ) vent anas) / / Asoci a l a vent ana act ual / / LLamada r eal i zada por (<- Aqui van ot r as l neas de ot r as Vent anaAct ual - >Abr event ana( ) ; / / Abr e l a vent ana. Vent anaAct ual - >Act i vavent ana( ) ; // Ent r a al ci cl o de esper a de event os Ret Vai =Vent anaAct ual - >Ci er r avent ana( ) ; // Ci er r a l a vent ana. del et e Vent anaAct ual ; // Li ber a l a memor i a ... r et ur n Ret Val ; Como vemos, el manejador instancia la ventana, enseguida la asocia al objeto cliente (esto esta garantizado pues se deriva de C-ObjetoInteractivo). El manejador invoca la operacin Abreventanao en donde se realizan inicializaciones y despus invoca Activaventanao que bsicamente es la entrada al ciclo de espera de eventos. Enseguida se cierra la ventana, se destruye el objeto y se regresa un valor que da la ventana. Regresando al diagrama de secuencia, vemos que al recibir interaccin, la ventana llama a ciertas operaciones de la aplicacin. El control esta entonces del lado de la ventana, sin embargo puede aparecer la necesidad de que durante una de las operaciones del objeto cliente se necesite realizar alguna notificacin al usuario, eso se realiza gracias a que el cliente tiene una referencia de su ventana, y a travs de ella puede acceder a las operaciones pblicas de esta. Todas las ventanas tienen entonces que tener como mnimo las operaciones que se declaran en Ventana.h por ello, se derivan todos de esta clase, garantizando que el manejador no intentar llamar operaciones inexistentes. cl ass C - Vent ana I pr ot ect ed: bool Ret Val ; // Val or de event ual r et or no voi d I ni ci al i za0 {; } // Posi bl es I ni ci al i zaci ones. publ i c : C - Vent ana ( ) {Ret Val =TRUE; 1 vi r t ual bool Abr eVent ana( ) =O; // Abr e una vent ana, r eci be r ef er enci a de l a cl ase vi r t ual bool Act i vaVent ana( ) =O; // Reci be ent r ada de l a vent ana vi r t ual bool Ci er r aVent ana( ) =O; // Ci er r a l a vent ana que i nvoco al manej ador ! 33 La ventaja de esta solucin es que se pueden emplear diversas librerias para implementar la interaccin con el usuario, ya que casi siempre se sigue una secuencia similar de pasos a seguir para mostrar una ventana en los diversas libreras de interfases que existen. Tambin mostramos a continuacin cmo se implementa del lado de una ventana el llamado a las operaciones de su cliente. En el caso de la librera que empleamos, hubo que implementar un despachador de mensajes, pero esto puede no ser necesario para otras librerias de GUI (interfase grfica con el usuario). voi d C- Vent anapr i nci pal : : Despacha- Cal l back( 1ong par am) I swi t ch ( dat a) { case( CB- MENUARCHI VO) : Cl i ent e- >OnMenuAr chi vo( ) ; br eak; case( CB - MENU - PROCESAR) : Cl i ent e- >OnMenuPr ocesar ( ) ; br eak; case( CBMENU- DESPLI EGUE) : Cl i ent e- >OnMenuDespl i egue( ) ; br eak; case ( CB - MENU- AYUDA) : Cl i ent e- >OnMenuAyuda( ) ; br eak; case ( CB - BOTON - ARRI BA) : case ( CB - BOTON - ABAJ O) : case ( CB - BOTON- I ZQ) : case ( CB- BOTON- DER) : Cl i ent e- >PonCur sor ( COLOR- MARCO) ; Cl i ent e- >MueveCur sor ( par a) ; Cl i ent e- >PonCur sor ( COLOR- CURSOR) ; br eak; case( CB - BOTON - ZOOM) : Cl i ent e- >OnBot onZoom( ) ; br eak; Nota: En xforms, no se puede tener acceso directamente a los atributos de la clase desde una de sus operaciones si esta es llamada como 'callback' pues en ese caso hay que declarar a esta operacin de tipo 34 'static'. Es por ello que el archivo manejador.cpp difiere un poco del cdigo mostrado arriba. Posteriormente se tratar este punto con mayor profundidad. En todas las ventanas se siguen pasos similares a los de la ventana principal, con excepcin de los dilogos que no necesitan las funciones de Abreventanao y Cierraventana(), en los dilogos estas estn implementadas como funciones vacas. 5.3 Meioras en el rea grfica. El rea grfica es fundamental para esta aplicacin, de ah que sea necesario un buen desempeo de su parte. Un punto importante que discutiremos es que la clase implementa operaciones que permiten el despliegue de los diversos objetos. Esto puede parecer erroneo pues normalmente uno esperara que los objetos instanciados a partir de los derivados de CColeccionDeDatos y algunos otros pudieran 'saber' como desplegarse, dado que tienen una operacin llamada DespliegaDatos(). Sin embargo, debemos recordar que uno de los objetivos del diseo de la aplicacin fue de separar las partes con riesgo de ser dependientes de la plataforma en clases aparte. De esta manera, ninguna de las clases centrales al modelo contiene comandos que no sean estndares al lenguaje de programacin estndar. Si por ejemplo un StackDeImagenes incorpora comandos grficos dentro de su operacin DespliegaDatos(), se pierde la posibilidad de portar sin modificaciones los archivos que definen esta clase a otra plataforma. Otra posibilidad sera que la clase tuviera todas las primitivas grficas encapsuladas en sus operaciones, y los objetos centrales a la aplicacin llamarn a estas primitivas para desplegarse. Desgraciadamente, esto traera otro problema pues los objetos tambin tendran que encargarse de que el despliegue se este realizando de manera correcta (inicializar el despliegue, colores, etc. ..). Es por ello que se decidi que el rea grfica no encapsulara todas las primitivas ms bsicas de la graficacin, sino que pudiera desplegar tambin los objetos que se tienen definidos, aunque para acceder a los datos de los objetos que se quieren desplegar tendria que obtenerlos a travs de sus operaciones. Esto permite que el rea grfica se encargue de 'administrar' el despliegue para que se realice de manera correcta y no se rompen las reglas de encapsulamiento. Otro punto importante tiene que ver con el hecho de que el rea grfica debe ser capaz de aceptar diversas libreras de primitivas grficas, en nuestro caso empleamos OpenGL, pero en teora se podria emplear alguna otra (DirectX por ejemplo). Existen algunas funciones que estan implementadas en una librera y que en otra podrian no estarlo, por ejemplo, el uso de doble buffer para el dibujo. El rea grfica se encarga de hacer 'transparente' esto para los objetos de la aplicacin, y ellos slo tienen que solicitar el tipo de despliegue que se desee (2D/3D) y lo dems se realiza de manera automtica. Algunas dificultades apareciern por el uso de OpenGL, sern discutidas ms adelante. 5.4 Meioras en la clase C Imagen. Una pregunta puede surgir al estudiar el diseo de la aplicacin y es Por qu la clase C-Imagen no se deriva de CColeccionDeDatos, si se trata bsicamente de un arreglo ? La respuesta es que C-Imagen se usa para instanciar la clase C-StackDeImagenes y si se derivara de la coleccin, tendra que existir una clase ms bsica para poder instanciar a C-Imagen y sera algo inutil. En vez de eso, C-Imagen encapsula un arreglo de elementos de tamao variable. Sin embargo esto no 35 se realiz con una clase parametrizada, pues C-Imagen debe ser capaz de manejar tipos de dato no estndares como por ejemplo 3 bytes por dato. La solucin propuesta fue que el arreglo de elementos fuera de tipo 'void *'. Este tipo de datos prefiere evitarse normalmente, pero las ventajas que proporciono en nuestro caso justifico claramente su utilizacin. Un problema que surge con tipos de dato no estndares es que no se puede declarar una funcion LeeDato() que regrese un void *. Lo que se hizo es que para tipos de dato menores a 3 bytes, se emplea la funcin LeeDato que regresa un entero (tipo de dato en el cul caben 1 o 2 bytes sin problema). Para 3 bytes o ms, se emplea la funcion LeeDatoComoArreglo() que regresa un arreglo de yt bytes. Es as como se puede manejar cualquier tipo de dato por la imgen. Esto permite que en el futuro se puedan procesar otros tipos de informacin, para ejemplificarlo, la aplicacin permite desplegar archivos de 3 bytes de informacin por pixel (1 byte por componente R, G y B) y que tiene como resultado el despliegue de imgenes a color. 5.5 Meioras Y otros usos para la lista ligada. El uso de una estructura de datos para manejar el arreglo de datos de cualquier tipo dentro de la coleccin de datos es una idea til. La clase C ListaLiaada declara una lista de referencias a objetos. La razn por la cual la lista no contiene las instancias es por que la lista se pretende emplear en algunos momentos como un 'vehiculo' para enviar parmetros. Es por ello que no debe contener las instancias de los objetos, de lo contrario, estos serian destruidos junto con la lista. De ah que la responsabilidad de creacin de los objetos no es de la lista ligada, sin embargo, se le puede pedir que destruya a los objetos que referencia antes de destruirse. Dadas las caracteristicas de la lista ligada, se le encontraron otros usos dentro de la aplicacin, por ejemplo dentro de la aplicacin, se tena un stack original y uno de trabajo, pero que sucede si se aplican varios procesos, donde se guarda la referencia a los stacks resultantes de los procesos? Una solucin elegante fue emplear una lista ligada para contener todos los Stacks con los que trabaja la aplicacin, esto permite tener una cantidad variable sin limite de tamao. Otro empleo que se le dio a la lista ligada fue para la clase C Volumen pues un volumen no es slo una coleccin de puntos en el espacio tridimensional, sino que cada uno de esos puntos tiene una normal que define su orientacin respecto a las fuentes de luz, y un color. Hubiera sido posible crear una clase derivada de C-ColeccionDeDatos para el manejo de las normales, pero las normales no pueden 'existir' como objeto individual de un volmen, y no hay posibilidad de desplegarlas. Por todo ello, mejor se emplearon dos listas ligadas dentro de C Volumen, una de puntos para contener las normales y una de colores. Es interesante notar que un volumen no necesita forzosamente que estas listas contengan datos para poder desplegarse satisfactoriamente. Otros lugares donde se emplean listas ligadas es para los algoritmos. Por ejemplo, la aplicacin necesita pasar dos stacks distintos al proceso de reconstruccin, el stack original (niveles de gris) y el segmentado. Estos se introducen a una lista ligada que se pasa al proceso. A partir de los stacks que recibe, el proceso de reconstruccin crea un nuevo stack, el de contornos, y lo aade a la lista que se le envio, as al terminar el proceso, la aplicacin tiene acceso al nuevo stack. Para poder emplear listas ligadas de las diversas clases, se han definido varias instancias de la clase C-ListaLigada, en particular podemos mencionar: C-ListaColores definida en Co1or.h C-Listapuntos definida en Punt0.h C-Listastacks definida en Stack.h 36 Es posible crear otras listas ligadas si es necesario. Un problema que surgio al emplear listas ligadas de gran tamao fue que el acceso a sus datos se volvi lento. Esto es debido a que la lista se recorre desde el inicio cuando se le pide uno de sus elementos. Para mejorar el tiempo de acceso, se decidi que la lista mantuviera un arreglo de apuntadores a sus nodos, as no se tiene que recorrer toda la lista para llegar a un nodo dado. Para ello se incluy la operacin ActualizaTablaO. Como su nombre lo indica, esta funcin actualiza la tabla de apuntadores a los nodos y cambia una bandera de la lista que indica que la lista esta actualizada. De esta forma, cuando se invoca al mtodo LeeDato(DatoNum), la lista utiliza automticamente su tabla. La actualizacin se invalida tambin de manera automtica cuando se inserta o se borra un elemento a la lista. AI copiarse la lista, se actualiza la tabla de la lista fuente para optimizar la velocidad. El resultado de utilizar una lista fue una mejora en todos los aspectos de la aplicacin. 5.6 La configuracin del stack Y sus usos. Hemos explicado ampliamente los puntos importantes que conciernen al stack de imgenes. Sin embargo, los requerimientos de la aplicacin pedian la posibilidad de interactuar con el despliegue, por ejemplo, de ver detalladamente una imgen o de variar la manera en que se despliega un stack. Esto es claramente algo fuera de las responsabilidades del stack, sin embargo, tambin est fuera de las responsabilidades del rea grfica, que se limita a proveer a lo mximo un rea grfica con ciertas carcteristicas. Si por ejemplo queremos desplegar todo el stack, o solo una parte, quien debe responsabilizarse de realizar la distribucin de las imgenes en la pantalla ? La solucin empleada fue la de crear una nueva abstraccin, la llamamos C StackConfiq y est asociada al C-StackDeImagenes. Si observamos sus atributos, encontramos que contiene todo lo necesario para poder desplegar un stack en un rea rectangular de la pantalla, desde la escala a la cual se despliegan las imgenes, hasta la franja que existe de espacio entre imgenes. Tambin contiene una referencia al rea grfica en la que se despliega el stack. Existe una redundancia al tener una referencia al rea grfica en el Stack y en su configuracin. Esto se debe a que la configuracin a pesar de tener una referencia a un stack, no puede conocer el rea grfica en que este se despliega, pues esto no es parte de las operaciones que tiene la coleccin. Por ello el Stack le d a conocer su rea grfica a su configuracin. La utilidad de tener esto es que ante un cambio de tamao del rea de despliegue, la configuracin puede actualizar la distribucin de las imgenes en la pantalla, as como el tamao mximo de despliegue. Otro uso de la configuracin apareci posteriormente con la posibilidad de ver una ampliacin de una imgen en la pantalla principal, esto se logra simplemente ajustando la escala actual a la mxima posible, pero esto lo realiza automticamente la configuracin, y es posible despues regresar al tamao original. La configuracin puede ser utilizada para desplegar una sla imagen en la pantalla, se debe crear un stack de una imgen, y esto automticamente le crear una configuracin. Esto es til para mostrar imgenes centradas o escaladas. El uso de la configuracin del stack permiti tener mucha flexibilidad en el despliegue de las imgenes dentro de la aplicacin. 5.7 Diagramas de secuencia. Para finalizar la etapa de implementacin, mostraremos ,al igual que en las dems etapas, los 37 diagramas de secuencia que muestran las modificaciones que presentamos en los puntos anteriores. Diagrama: Inicio de aplicacin. inejadot eVeniana5 rocesadorDelm agenes1 : -StackD elmagenes( ) i 7 AsignaManejador( ) :iaJ ' VentanaP rincipal( ) - ikntana(id-vent, Reft ______51 Selec iaVentana(C -Veniani &reVeniana( ) A inicializa( ) I LeeStacki )legado( ) &sign( I- eaGrafica(C -#reaGrafqa) . ActivaVentana( ) RelrescahaGrafica( : P . ?satiint) D espliegaDaios( 1 u; Dibuja!magen(int, int, int, C -1 3' allback[ I Esto se mue stra coi detalle en lo demas diagramas. e--- L MenuP iw(int) . Menu, , MenuDi egue(int) . C ierra%ntana( ) :I A INICIO DE APLICAC~ION )IAGRPMADE SECL 38 Diagrama: Carga de un stack. I 5 ei ecci onaventana$u- vent, Hetemnci a-I) 1 C Dialoq#rchko(C * Obieiolnier ' U *- ' Abi.eVeitaiia() ! _ . i Activaventana() CombiaNoml I :I< conti gura() ! ! ! ! tk0 *. ni) \ ! Arc hiv o(c hor *) I . . ! jc Veni anaconmac #j 1'1- I . I 39 Diagrama: Aplicacin del algoritmo de segmentacin por umbral. Leek t d: argadd.21 SeleccionaM nianq I vent Reerencia-D. c ibiaSeIeccionAlgori1 co i s ertaNod C-Dato') i . r SeleccbnaProces o() Selecc&aMntan&id-ven C-Vent aLknian 1 ikniang ) BcCegU mbra[R efere! 3 Diagrama: Configuracin de parmetros del despliegue: 40 a Selec cionaVentana(id-\ it, Referencia-I) C-VentanaConfStackD I - Abreventana( ) - ActivaVentana( ) .-- Cierraventana( ) ( L S tac kconfig( r inicializa( ) I Copia(C-Sac kConl / Despac hac allbac k a Cam bialm agenlnici; .-- Cam biaEscala() C amb i al nte ns idad(; \ / 6 Copia(C- LeeConfiguracion( ) Estas son las modificaciones que se realizan configuracin. :ac kconfig) F 1 Diagrama: Interaccin con la ventana principal. 41 A I - VentanaAotual : C 1 1 I ADlicacion Mane'adorDeV ntanas MpneiadorjC Aplicacion : C : usuario " I : seleccionaventana u j Interaccion ... M : Fin de inteiac i -CAplicacin() 1 impottantesya que c p P L i CACI ON.this) C-ventanaPrincipai() Abreventana() CanvasHandleO i l l Asi g n a Are a G raf i ca(C-Are a G iaf i ca) > sp lieg ue(int) Despacha Call b a y ) On-M EN U-D E S P LI E G U E( ) On-M ENU-PRO CESAR( ) 'rooesar(int) On-MENU-ARCHIVO() 4rchivo(int) RefrescaAieaGrafica() Callbad<se encarga de llamar a las funciones atribuidas a cada objeto de la interfrz de usuario. Nos e han detallado todas, slo aquellas que a su vez llaman alguna funcin de 1, a p I i ca ci n Diagrama: Despliegue del stack actual. 42 s elec cion aVentana( id-' Abreventana( ) L it, Referencia-I) C-VentanaConfStackC Activaventana( ) Cierraventana( ) )CStackConfig( ) 'u inicializa( ) I ; LeeConfiguracion( ) j C op ia ( C-Sta c kC o nf i$ ) DespachaCallbaclQ i) 'u Cam bialntensidad( : XI C opia(C-dac kconfig) \ I / 5.8 Diagramas de clases. A continuacin se muestran diversos diagramas de clases definitivos para la versin que se entreg. Diagrama de clases global: 43 . .. li i- \ / \ \ k-9 O O - / uso de las clases de ventanas: C-VentanaPrincipal : Ventana principal de la aplicacin, donde se muestran los stacks. C-VentanaSelAlgoritmo : Ventana para seleccionar el algoritmo a aplicar. C-VentanaConfStack : Ventana para configurar el stack al cargarlo. C-VentanaConfStackDisp: Ventana para configurar el despliegue del stack. C-VentanaConfSegUmbral: Ventana para aplicar el algoritmo de segmentacin por umbral. C-VentanaReconstruccion: Ventana para aplicar el algoritmo de reconstruccin. C - DialogoArchivo: Dialogo para explorar el directorio y teclear un nombre de archivo. Diagrama de clases : Detalle de relaciones entre la aplicacin y la ventana principal. Diagrama de clases : Detalle del proceso de segmentacin por umbral. 45 Diagrama de clases: Detalle de proceso de reconstruccin. 46 c Y \ 5.8.1.- Detalles de las clases. Algunas clases se pueden ver con mayor detalle: C-Aplicacin C-AreaGrafica C-ColeccionDeDatos C Histograma Climagen CListaLigada C-Stackconfig C-StackDeImagenes C-Ventana C-VentanaPrincipal diagrama - cabecera diagrama - cabecera diagrama - cabecera diagrama - cabecera diagrama - cabecera diagrama - cabecera diaprama - cabecera diagrama - cabecera diagrama - cabecera diagrama - cabecera 47 C-Volumen diagrama - cabecera 5.9 Conclusin. Hemos llegado finalmente a la etapa terminal de la creacin de una aplicacin. En este capitulo mostramos las soluciones que se emplearon para llevar a cabo de manera exitosa la propuesta del diseo. El resultado 'fisico' fue exitoso, la aplicacin funciona correctamente, y sobre todo es sencilla de modificar y de extender. Posteriormente se muestran algunas imgenes del resultado. 6.- Aspectos Tcnicos. En esta seccin se discuten algunos aspectos tcnicos muy especficos al desarrollo de la aplicacin con la librera xforms, opengl, y la herramienta 'make'. 6.1 Recuperacin del apuntador 'this' dentro de xforms. La librera xforms es una coleccin de objetos grficos que permiten la interaccin con el usuario. Est escrita en lenguaje 'C' y posee una herramienta que permite la creacin de ventanas de manera 'interactiva' y posteriormente la escritura del cdigo para esas ventanas de manera automtica. Sin embargo, nosotros enfrentamos un problema cuya solucin no fue muy evidente, el problema fue cmo encapsular la librera en C dentro del modelo?. Cuando fdesign escribe el cdigo correspondiente a una forma o ventana, escribe una cabecera (archivo .h) y una parte del cdigo del programa (archivo .c). A continuacin se muestra un ejemplo de estos archivos. Cabecera: #i f ndef FD - ventana-h - Pri nci pal #def i ne FD - ventana _ - h Pri nci pal / * Header f i l e generated wi th f desi gn. */ / **** For ms and Obj ects ****/ typedef struct { FL - FORM *ventana; FL - OBJ ECT *MENU - ARCHI VO; FL - OBJ ECT *MENU - PROCESAR; FL - OBJ ECT *MENU - DESPLI EGUE; FL - OBJ ECT *canvas; FL - OBJ ECT *BOTON - SALI R; FL - OBJ ECT *MENU - AYUDA; FL - OBJ ECT *CAMPO - TEXTO; FL - OBJ ECT *BOTON - I ZQ; FL OBJ ECT *BOTON ABAJ O; - - 48 FL - OBJ ECT *BOTON - ARRI BA; FL - OBJ ECT *BOTON - DER; FL - OBJ ECT *CAMPO - STATUS; FL OBJ ECT *CAMPO NUM I MAGEN; FL - OBJ ECT *BOTON - ZOOM; voi d *vdat a; l ong l dat a; - - - } FD- vent ana - Pr i nci pal ; #endi f /* FD vent ana h */ - - - Cuerpo del programa (se muestra slo una parte): / * For mdef i ni t i on f i l e gener at ed wi t h f desi gn. */ #i ncl ude " f or ms. h" #i ncl ude " f or m- - V pr i nci pal . h" FD - vent ana *cr eat e- f or m- vent ana( voi d) I FL - OBJ ECT *obj ; FD - vent ana *f dui = ( FD - vent ana *) f l - cal l oc( 1, si zeof ( FD- vent ana) ) ; f dui - >vent ana = f l - bgn- f or m( FL - - NO BOX, 1220, 940) ; obj = f l - - add box( FL - - UP BOX, O, O, l 220, 940, ' ") ; obj = f l - - add f r ame ( FL - ENGRAVED- FRAME, 10, 10, 260, 80, ; f dui - >MENU - ARCHI VO = obj = f l - - add menu( FL - PULLDOWN - MENU, 50, 900, 110, 30, " Ar chi vo" ) ; f l - - set obj ect - boxt ype ( obj , FL - FRAME - BOX) ; f l - - set obj ect - l st yl e( obj , FL - BOLD - STYLE) ; f l - - set obj ect - cal l back( obj , Despacha - Cal l back, CB - MENU - ARCHI VO) ; f dui - >canvas = obj = f l - - add canvas ( FL - NORMAL - CANVAS, 10, 100, 1200, 780, " " ) ; f dui - >MENU - AYUDA = obj = f l - - add menu( FL - PULLDOWN - MENU, 360, 900, 100, 30, "Ayuda") ; f l - - set obj ect - boxt ype ( obj , FL - FRAME - BOX) ; f l - - set obj ect - l st yl e( obj , FL - BOLD - STYLE) ; f l - - set obj ect - cal l back( obj , Despacha - Cal l back, CB - MENU - AYUDA) ; f dui - >BOTON - ZOOM = obj = f l - - add but t on( FL - PUSH - BUTTON, 150, 50, 110, 30, "Zoom") ; f l - - set obj ect - l si ze( obj , FL - MEDI UM- SI ZE) ; f l - - set obj ect - l st yl e( obj , FL - BOLD - STYLE) ; f l - - set obj ect - cal l back( obj , Despacha - Cal l back, CB - BOTON - ZOOM) ; f l end f or m( ) ; - - r et ur n f dui ; I 49 Cmo realiza la interaccin con el usuario xforms ? La librera provee los objetos grficos, y permite que se asocie una funcin a cada uno de ellos, esta se denomina callback y se asocia por medio de la funcin fl-set-object-callback(). Debemos prestar atencion a la funcin fl-set-object-callback(). En ella se envian tres parmetros, el primero es una referencia al objeto, el segundo es un apuntador a la funcin que se debe llamar en caso de recibir interaccin y el tercero es un parmetro. El problema que aparece es que el callback NO PUEDE SER CUALQUIER FUNCION! Si intentamos poner alguna de las operaciones de una clase dentro del fl-set-object-callback, la operacin ser llamada de manera exitosa, sin embargo una vez ah ocurriran problemas. El primero es que el parmetro que se enva parece tener un valor totalmente distinto al que pensabamos enviar. El segundo es que ya no tenemos acceso a los atributos de la clase de manera normal. Este problema parece originarse debido a que la librera esta creada en lenguaje IC'. La solucin es que la funcin que se llama como callback debe ser declarada como 'static' en la declaracin de la clase. Sin embargo, si declaramos una funcin de tipo 'static', una vez que llegamos a ella, no podemos emplear el apuntador 'this', ni tener acceso a los atributos del objeto, sin embargo, el parmetro enviado se recibe correctamente. Parece no haber solucin al problema, pero lo que se debe hacer es 'recuperar el apuntador this'. 'Recuperar el apuntador this', significa que debemos almacenarlo en algun lugar al que se pueda acceder dentro de la funcin esttica. Recordemos que los atributos del objeto no son candidatos para esto pues contienen valores aparentemente erroneos ... el nico candidato son los parmetros que se reciben correctamente. Al leer la documentacin de xforms, hemos encontrado que los autores planearon un apuntador 'libre' para que el usuario pudiera emplearlo para cualquier cosa necesaria. Es ese apuntador es el que vamos a emplear. As que dentro de la funcion Abreventanao tendremos que 'almacenar' el apuntador, esto es al inicializar la ventana. A continuacin se muestra un ejemplo de ello: Primero, vemos parte del archivo de cabecera de la ventana, donde se declara de manera esttica la funcin DespachaCallback(). #i ncl ude ' l . . / FORMS/ f or ms. h" #i ncl ude " FORMS/ f or m_ - V pr i nci pa1. h" [. . . I #i ncl ude "Vent ana. h" // De est a her eda cl ass C- Vent anaPr i nci pa1: publ i c C- Vent ana I pr ot ect ed: // *** Enums l ocal es. *** // / / Los I dent i f i cador es de Cal l backs 50 enum { CB - MENU - ARCHI VO=l , CB - MENU - PROCESAR,CBMENU-DESPLI EGUE,CB - MENU - AYUDA, CB - MENU - RECONSTRUI R, CB - BOTON - ARRI BA, CBBOTON- ABAJ 0, CB - BOTON - I ZQ, CB - BOTON - DER, CB - BOTON - ZOOM}; C - Apl i caci on *Cl i ent e; / / Est a vent ana cor r esponde a l a cl ase C- Apl i caci on. C- Ar eaGr af i ca Pant al l a; // El ar ea gr af i ca -> Agr egaci on. / / *** Met odos *** // // Her edada voi d I ni ci al i za ( ) ; // I ni ci al i zaci ones di ver sas. // x- f or ms excl usi vament e ! FD - vent ana- Pr i nci pal *f or ma; // La f or ma voi d CanvasHandl er O; // Manej ador del ar ea gr af i ca. / / Cal l backs . . . static void Despacha-Callback(n - OBJECT *ob,long data); // Despachador ... voi d OnMenuDespl i egue( ) ; voi d OnMenuPr ocesar O; voi d OnMenuAr chi vo( ) ; voi d OnMenuAyuda ( ) ; voi d OnBot onZoom( ) ; // Funci ones que son l l amadas dependi endo // de l as acci ones. // Las f unci ones si gui ent es no son par t e del model o especi f i cament e si no de / / x- f or ms! st at i c i nt Reci beEvent o( FL - OBJ ECT *ob, Wi ndow wi nt i nt w, i nt h, XEvent *xev, voi d FD - vent ana- Pr i nci pal *cr eat e - f or m- vent ana( voi d) ; *Ud) ; // Ot r as. . . [. . . I publ i c: // Const r uct or . C - Vent anaPr i nci pal ( Ref er enci a- I Cl i Ref ) {Cl i ent e=( C- Apl i caci on *) Cl i Ref ; } // Funci ones Her edadas 51 boo Abr event ana ( ) ; bool Act i vavent ana( ) ; bool Ci er r avent ana( ) ; Enseguida vemos cmo se guarda el apuntador a this (archivo VentanaPrincipal.cpp). bool C- Vent anapr i nci pal : : Abr event ana( ) f or ma=cr eat e- f or mavent ana( ) ; // Cr eaci on de l a f or ma forma->ventana->u-vdata =this; // Sal va el t hi s, par a que l o usen l os cal l backs. I ni ci al i za ( ) ; / / I ni ci al i za pant al l a. f l - show- f or m( f or ma- >vent ana, FL - PLACE - CENTERI FL- FREE_SI ZE, FL_FULLBORDER, "pr i nci pal l ' ) ; / / Muest r a l a f or ma. DEBUGMSG ( "C- Vent anapr i nci pal : : Abr event ana ( ) \ n" ) ; r et ur n TRUE; / / Si empr e. I Ahora se muestra cmo se recupera el apuntador a this en la funcin DespachaCallback() voi d C - Vent anaPr i nci pa1: : Despacha - Cal l back( FL - OBJ ECT *ob, l ong dat a) t C-Ventanaprincipal *ApTemp; / / Apunt ador t empor al ApTemp=(C-VentanaPrincipal *)ob->form->u-vdata; // Rescat a el t hi s i f ( ApTemp- >EsPr i mer aVez==TRUE) ApTemp- >Bor r aI nt r o( ) ; swi t ch ( dat a) t case ( CB - MENU - ARCHI VO) : ApTemp- >OnMenuAr chi vo( ) ; br eak; case ( CB- MENU- PROCESAR) : ApTemp- >OnMenuPr ocesar ( ) ; br eak; // Ahor a si ; ej ecut a cal l back! case( CB - MENU- DESPLI EGUE) : ApTemp- >OnMenuDespl i egue( ) ; 52 br eak; case( CB - MENU - AYUDA) : ApTemp- >OnMenuAyuda( ) ; br eak; case( CB - BOTON - ARRI BA) : case ( CB - BOTON - ABAJ O) : case( CB - BOTON - I ZQ) : case ( CB - BOTON - DER) : ApTemp- >PonCur sor ( COLOR- MARCO) ; ApTemp- >MueveCur sor ( dat a) ; ApTemp- >PonCur sor ( COLOR - CURSOR) ; br eak; case ( CB - BOTON- ZOOM) : ApTemp- >OnBot onZoom( ) ; br eak; La nica manera de recuperar el 'this' es a partir de una fuente 'confiable' pero ya vimos que los miembros del objeto no lo son, slo los parmetros pueden emplearse. Podemos apreciar que los callbacks en xforms siempre estn definidos de la manera siguiente: voi d Nombr eDel Cal l back( F' L - OBJECT *Obj et oQueLl ama, l ong Par amet r o) No es posible enviar el apuntador a this como parmetro (que es de tipo long), pero el objeto que llama a la funcin es la va por la cual se recupera. Si prestamos atencin a la declaracin de la clase, podemos notar que DespachaCallback no es l a nica funcin declarada cmo 'static', sino que tambin existe otra: st at i c i nt Reci beEvent o( FL - OBJ ECT *ob, Wi ndow wi nl i nt w, i nt h, XEvent *xev, voi d *Ud) ; Lo que sucede es que DespachaCallback es la funcin que se llama cada que se interactua con las ventanas, pero RecibeEvento es un callback que se asocia al rea grfica, y se llama de manera automtica cuando el rea grfica recibe algun evento. Es por ello que RecibeEvento se tiene que declarar como static, y dentro de ella hay que rescatar el this de manera idntica. Cmo vemos estas situaciones que aparecen de 'rescate de this' no facilitan en nada el encapsulamiento de la librera dentro del modelo, pero el resultado con esta aproximacin es satisfactorio. 53 6.2 Pasos a segur para implementar una nueva ventana. Puesto que el programa puede requerir nuevas formas de interaccin con el usuario, a continuacin se muestra como agregar una nueva ventana. Para agregar una nueva ventana a la aplicacin, tenemos que seguir una serie de pasos. El primero es crear la forma con fdesign. A continuacin se muestra una imagen de fdesign en accin la parte de abajo muestra la ventana aue estamos creando. Nota: Siempre tendremos que llamar a la forma 'ventana' (esto facilita tomar el cdigo de otra ventana y adaptarlo), a todos los objetos se les tiene que asociar cmo callback la funcin 'DespachaCallback', tambin se debe de establecer el parmetro que identifique el objeto dentro de la forma y finalmente se les tiene que poner un nombre. La imagen a continuacin muestra cmo se ve la pantalla de configuracin de un objeto cuando se le aplican estas modificaciones. 54 Cuando se guarda la forma, fdesign genera dos archivos, el primero es el encabezado que es similar al siguiente: #i f ndef FD- vent ana - h- #def i ne FD- vent ana- h- / * Header f i l e gener at ed wi t h f desi gn. */ /**** Cal l back r out i nes ****/ ext er n voi d DespachaCallback(FL-OBJECT * I l ong) ; / **** For ms and Obj ect s ****/ t ypedef st r uct { FL - FORM *vent ana; voi d *vdat a; l ong l dat a; } FD - vent ana; ext er n FD- vent ana * cr eat e - f or m- vent ana( voi d1; #endi f / * FD - vent ana- h- */ Para poder incluir la ventana dentro de nuestra aplicacin, se deben hacer algunas modificaciones que se muestran resaltadas a continuacin. #i nde FD- vent ana- Depr ueba- h- <- (1) #def i ne FD- vent ana- Depr ueba- h- <- (1) / * Header f i l e gener at ed wi t h f desi gn. */ /**** Cal l back r out i nes ****/ // ext er n voi d DespachaCal l back( FL- OBJ ECT l ong) ; <- (2) 55 / A * * * For ms and Obj ect s ****/ t ypedef st r uct { FL - FORM *vent ana; voi d *vdat a; l ong l dat a; } FD - vent ana- DePr ueba; <- (3) // ext er n FD- vent ana * cr eat e- f or m- vent ana( voi d) ; <- ( 4) #endi f /* FD- vent ana - - h */ (1) Es importante cambiar las lineas del #ifndef sino al incluir otros archivos de cabecera apareceran errores al ya estar definido FD-ventana-h-. (2) Hay que comentar la(s) declaracin(es) de DespachaCallback(), ya que esta funcin ser redeclarada posteriormente como operacin dentro de la forma. (3) Tambin hay que cambiar el nombre de la estructura, ya que siempre se llama FD-ventana al ser escrito el cdigo, hay que ponerle algun extra que la diference. (4) Finalmente hay que comentar la declaracin de create-form-ventana() pues de igual forma de DespachaCallback(), ser declarada dentro de la clase correspondiente. La cabecera esta lista para ser incluida dentro del archivo en donde se declara la clase correspondiente a la ventana. El paso siguiente es retomar el cdigo en C que escribe xforms y 'encapsularlo' dentro de la clase. A continuacin se muestra el cdigo escrito por fdesign para el ejemplo mostrado arriba. / * For mdef i ni t i on f i l e gener at ed wi t h f desi gn. */ #i ncl ude " f or ms. hff #i ncl ude " pr ueba. h" FD - vent ana *cr eat e - f or m- vent ana( voi d) I FL - OBJ ECT *obj ; FD- vent ana *f dui = ( FD- vent ana *) f l - cal l oc( 1, si zeof ( FD - vent ana) ) ; f dui - >vent ana = f l - bgn- f or m( FL- NO- BOX, 600, 250) ; obj = f l - - add box( FL - - UP BOX, 0, 0, 600, 250, " f f ) ; obj = fl - - add f r ame ( FL - ENGRAVED- FRAME, 480, 20, 110, 220, "") ; obj = f l - - add but t on( FL - NORMAL - BUTTON, 490, 190, 90, 40, " Bot onl " ) ; f l - - set obj ect - l si ze( obj , FL - MEDI UM- SI ZE) ; f l - - set obj ect - cal l back( obj , DespachaCal l back, CB - BOTONl ) ; 56 obj obj = f l - - add menu( FL - PULLDOWN~MENU, 1O, 210, 100, 30, "Ar chi vof ~) ; obj = f l - - add canvas ( FL - NORMAL - CANVAS, 10, 60, 460, 140, "") ; obj = f l - - add f r ame ( FL - ENGRAVED - FRAME, 10, 210, 460, 30, f ' f v) ; obj = f l - - add but t on( FL - NORMAL - BU T T ON , 490, 120, 90, 40, " Bot on2" ) ; obj obj = f l - - add t ext ( FL - NORMAL - TEXT, 290, 20, 180, 20, " For ma de pr ueba. = f l - - add sl i der ( FL - - HOR SLI DER, 20, 20, 260, 20, " I f ) ; f l - set - obj ect boxt ype( obj , FL - FLAT - BOX) ; f l - - set obj ect - l si ze( obj , FL - MEDI UM- SI ZE) ; f l - - set obj ect - l si ze( obj , FL - MEDI UM- SI ZE) ; f l - - set obj ect - boxt ype( obj , FL- DOWN - BOX) ; f l - - set obj ect - col or ( obj , FL - WHI TE, FL - MCOL) ; = f l - - add but t on( FL - NORMAL - BUTTON, 490, 50, 90, 40, " Bot on3" ) ; f l end f or m( ) ; - - I f ) ; r et ur n f dui ; Este cdigo tiene que quedar encapsulado dentro de la funcin: FD - vent ana - DePr ueba *cr eat e - f or m- vent ana( voi d) ; De la manera siguiente (nuevamente, se resaltan las modificaciones): FD - vent ana- DePr ueba * C - Vent anaDePr ueba: : cr eat e - f or m- vent ana( voi d) <- (1) I // PEGAR LO QUE CREA XFORMS AQUI FL - OBJ ECT *obj ; FD vent ana DePrueba *f dui = <- (2) - - ( FD- vent ana- DePr ueba *) f l - cal l oc( 1, si zeof ( FD - vent ana- DePr ueba) ) ; <- (2) f dui - >vent ana = f l - bgn- f or m( FL- NO- BOX, 600, 250) ; obj = f l - - add box( FL - - UP BOX, 0, 0, 600, 250, f r f ' ) ; obj = f l - - add f r ame ( FL - ENGRAVED - FRAME, 480, 20, 110, 220, ' I f f ) ; ob] = f l - - add but t on( FL - NORMAL - BUTTON, 490, 190, 90, 40, " Bot onl " ) ; f l - - set obj ect - l si ze( obj , FL - MEDI UM- SI ZE) ; f l - set - obj ect - cal l back( obj , DespachaCal l back, CB - BOTON1) ; obj = f l - - add sl i der ( FL - - HOR SLI DER, 20, 20, 260, 20, "") ; obj obj = f l - add- gl canvas ( FL - NORMAL - CANVAS, 10, 60, 460, 140, " ' I ) ; <- (3) obj obj obj = f l - - add menu( FL - PULLDOWN - MENU, 10, 210, 100, 30, " Ar chi vo" ) ; f l - set - obj ect - boxt ype( obj , FL - FLAT - BOX) ; = f l - - add f r ame ( FL - ENGRAVED - FRAME, 10, 210, 460, 30, "") ; = f l - - add but t on( FL- NORMAL - BUTTON, 490, 120, 90, 40, "Bot 0n2~I ) ; = f l - - add but t on ( FL - NORMAL - BUTTON, 490, 50, 90, 40, f f B~t ~n3f ' ) ; f l - - set obj ect - l si ze( obj , FL- MEDI UM- SI ZE) ; f l - - set obj ect - l si ze( obj , FL- MEDI UM- SI ZE) ; 57 obj = f l - - add t ext ( FL - NORMAL - TEXT, 290, 20, 18Or 20, " For ma de pr ueba. . . " ) ; f l - set - obj ect - boxt ype( obj , FL - DOWN - BOX) ; f 1 - - set obj ect - col or ( obj FLWHI TE, FL - MCOL) ; f l end f or m( ) ; - - (1) La funcin tiene que ser definida como parte de la clase FD-ventana-DePrueba. (2) Hay que cambiar todas las referencias a FD-ventana por FD-ventana-Nombre en donde Nombre es el nombre de la ventana en este caso es 'Deprueba'. (3) Si se planea emplear OpenGL,el 'canvas' tiene que ser cambiado por 'glcanvasl. Finalmente esta parte queda lista para ser incorporado dentro del archivo de definicin de la clase (.cpp). Los pasos siguientes son los que hay que seguir para declarar la nueva clase. Supongamos que el cliente de la aplicacin es una clase llamada IC-ClientePrueba'. // Est e es el ar chi vo Vent anaPr i nci pa1. h #i f ndef VENTANADEPRUEBA - H #def i ne VENTANADEPRUEBA - H // I ncl udes ... #i ncl ude " Gener al . h" <- (1) #i ncl ude " f or ms. h" <- (2) #i ncl ude " Vent ana. h" <- (3) #i ncl ude " FORMS/ f or m- _ V pr ueba. h" <- ( 4) #i ncl ude " Cl i ent ePr ueba. h" <- (5) // Def i nes . . . cl ass C- Vent anaDePr ueba: publ i c C- Vent ana { pr ot ect ed: / / *** Enums l ocal es. *** // enum {CB-BOTON-SELECCION1=lrCB - BOTON - SELECCI C / / *** At r i but os *** / / J2}; <- C - Cl i ent ePr ueba *Cl i ent e; // Ref er enci a al cl i ent e <- ( 7 ) 58 FD - vent ana- DePr ueba *f or ma; <- ( 8 ) // *** Met odos *** / / // Cal l backs st at i c voi d Despacha- Cal l back( FL- OBJ ECT *ob, l ong dat a) ; / / Despachador de mensaj es <- (9) / / X- f or ms FD- vent ana- DePr ueba *cr eat e - f or m- vent ana( voi d) ; <- (10) / / Ot r as voi d Funci onExt r al ( ) ; <- (11) voi d Funci onExt r a20; publ i c: <- (12) C - Vent anaDePr ueba( C- Obj et oI nt er act i vo* Cl i Ref ) {Cl i ent e=( C- Cl i ent epr ueba *) Cl i Ref ; } / / Est as son her edadas. bool Abr event ana ( ) ; <- (13) bool Act i vavent ana( ) ; bool Ci er r avent ana( ) ; #endi f (1) Siempre incluir el archivo 'Genera1.h' que contiene declaraciones necesarias. (2) Incluir 'f0rms.h' que son los includes de la librera. (3) Incluir 'Ventanah' que es donde se declara la clase de donde heredan todas las ventanas. (4) Incluir el archivo de cabecera creado por fdesign y modificado posteriormente. (5) Incluir el archivo donde se declara la clase cliente. (6) Crear los enums que identifican a los objetos. (7) Tener una referencia al objeto cliente. (8) Tener un apuntador a la forma. Esto es necesario para las funciones de xforms. (9) Declarar la funcin de despacho de callbacks. (1 0)Declarar la funcin createform-ventana() que contiene el cdigo que crea la ventana y que genera fdesign. (1 1)Poner funciones extra que sean necesarias. (1 2)El constructor de la ventana simplemente recibe la referencia al cliente y la guarda en la que se declaro en (7). (1 3)Las funciones heredadas a partir de C-Ventana y que detallaremos a continuacin. 59 Una vez que se ha declarado la clase correctamente, tememos que pasar a su implementacin. Existen algunas hci nes que sern identicas para todas las ventanas, estas son Abreventanao y Cierraventanao sern como sigue: bool C - VentanaDePrueba::AbreVentana() I f or ma=cr eat e- f or m- vent anao ; f or ma- >vent ana- >u- vdat a = t hi s; cal l backs . . . // Cr eaci on de l a f or ma / / Sal va t hi s par a uso de I ni ci al i za ( ) ; // I ni ci al i za pant al l a f l - show - f or m( f or ma- >vent ana, FL- PLACE - CENTER,FL-FULLBORDER,"Ventana de pr ueba" ) ; / / Muest r a Vent ana r et ur n TRUE; 1 bool C - Vent anaDePr ueba: : Ci er r aVent ana( ) f l - hi de - f or m( f or ma- >vent ana) ; // Ci er r a l a vent ana r et ur n Ret Val ; 1 El siguiente paso es definir las funciones Activaventanao y DespachaCallback(). bool C- Vent anaDePr ueba: : Act i vavent ana( ) I FL - OBJ ECT " mensaj e; whi l e ( TRUE) i mensa j e=f 1- do- f or ms ( ) ; i f ( mensaj e==f or ma- >BOTON- APLI CAR) { Ret Val =TRUE; / / Esper a OK. r et ur n TRUE; 1 i f ( mensaj e==f or ma- >BOTON- CANCELAR) I Ret Val =FALSE; r et ur n FALSE; i 60 Notese que para el ciclo de espera de eventos checamos el objeto recibido mediante su nombre, en despacha callback usaremos los enums definidos en la declaracin de la clase. // SI GUEN LAS DEFI NI CI ONES DE LOS CALLBACKS voi d C- Vent anaDePr ueba: : Despacha- Cal l back( FL- OBJ ECT *ob, l ong dat a) { C - Vent anaSel Al gor i t mo *ApTemp; ApTemp=( C- Vent anaDePr ueba *) ob- >f or m- >u- vdat a; // Rescat a t hi s. // Apunt ador t empor al swi t ch ( dat a) { case( CB- BOTON - SELECCI ON1) : ApTemp- >Funci onExt r al ( ) ; br eak; case( CB- BOTON- SELECCI ON2) : ApTemp- >Funci onExt r a2( ) ; br eak; Nuestra ventana est lista para ser incluida al programa. Ahora tenemos que poder pedir su instancia. Hay que seguir algunos pasos sencillos. 1 .- Dar un identificador a la ventana dentro del archivo Genera1.h (se muestra slo la parte importante.) [ . . . I / / Los si gui ent es son l os i dent i f i cador es de l as vent anas ( I DV) . 1001- >1999 #def i ne I DVAPLI CACI ON 1001 / / Vent ana pr i nci pal #def i ne I DV- SEL- ALGORI TMO 1004 // La sel ecci on del al gor i t mo #def i ne I DV- CONF- STACK 1005 // La conf i gur aci on del st ack #def i ne I DV- CONF- STACK- DI SP 1006 // Conf i gur aci on del despl i egue pr i nci pal #def i ne I DV- CONF- SEG- UMBRAL 1007 umbr al #def i ne I DV- RECONSTRUCCI ON 1008 // Vent ana de l a r econst r ucci on. #defi ne IDV-PRUEBA 1009 // Ventana de prueba. // Conf i gur aci on del al gor i t mo seqment aci on por / / Los si gui ent es son i dent i f i cador es de di al ogo ( I DD) 2001- >2999 #def i ne I DD- CARGAR 2001 // Di al ogo car gar #def i ne I DD- GUARDAR 2002 / / Di al ogo guar dar 61 2.- Incluir la declaracin de la clase dentro del archivo de definicin del manejador / / Est e es el ar chi vo Manej ador . cpp que cont i ene l a def i ni ci on de l a cl ase // Manej ador DeVent anas. AQUI HAY CODI GO ESPECI FI CO A XFORMS! #i ncl ude " Manej ador . h" #i ncl ude " Vent ana. h" #i ncl ude " Vent anaPr i nci pal . h" #i ncl ude " Vent anaSel Al gor i t mo. h" #i ncl ude " Di al ogoAr chi vo. h" #i ncl ude " Vent anaConf St ack. h" #i ncl ude " Vent anaConf St ackDi sp. h" #i ncl ude " Vent anaConf SegUmbr al . h" #i ncl ude "Vent anaReconst r ucci on. h" #i ncl ude " Vent anaAcer caDe . h" #include VentanaDePrueba . hff [ . . . I 3 .- Incluir tambin el la operacin SeleccionaVentana() el cdigo que se encargue de instanciar esta ventana. case I DV - RECONSTRUCCI ON: Vent anaAct ual =new C- Vent anaReconst r ucci on( C1i ent e) ; Cl i ent e- >Asoci aVent ana( Vent anaAct ual ) ; br eak; case IDV-PRUEBA: VentanaActual=new C-VentanaDePrueba(C1iente); Cliente->AsociaVentana(VentanaActual) ; <- (1) break ; / / -- Di al ogos -- // case I DD- CARGAR: [ . - . I (1) esta lnea slo es necesaria si necesitamos que el cliente pueda comunicarse con su ventana una vez que esta invoca a alguna de sus operaciones pblicas(de1 cliente). En este caso tambin es necesario incluir el archivo de la declaracin de la clase VentanaDePrueba dentro del archivo de definicin de la clase cliente. 62 4.- Finalmente, podemos utilizar nuestra ventana. Desde el cliente slo basta con incluir la siguiente lnea (notese que el cliente tiene que tener una referencia al manejador). Mane] ador - >Sel ecci onaVent ana( I DV- PRUEBA, t hi s) ; // Pi de su vent ana, est a t oma el cont r ol . Y listo! Estos pasos se tienen que repetir siempre que se quieran agregar nuevas ventanas, de ah que podra ser til una herramienta que automatizara este proceso. 6.3 Cambios de contexto para mltiples reas grficas. El punto que trataremos a continuacin tiene que ver con el empleo de la librera grfica OpenGL dentro del ambiente de ventanas que crea xforms. La librera xforms permite emplear reas especiales dentro de las formas o ventanas llamadas 'canvas'. Estas reas relegan al programador la tarea de manejar la interaccin. Existe un tipo de rea en particular llamado glcanvas que permite el despliegue de grficas a partir de la librera OpenGL. OpenGL es una libera portable que hace uso de los recursos de hardware para crear grficas de alto rendimiento. Consiste de un conjunto de funciones que permiten desplegar 'primitivas' grficas, tales como puntos, lneas, poligonos y tambin permite iluminar y mover una cmara. Se trata, al igual que xforms, de una librera de funciones en lenguaje C. El problema con el que nos enfrentamos al utilizar estas dos libreras juntas fue en el momento en que quisimos tener varias reas grficas dentro de una misma forma. El problema ocurre pues cada rea grfica tiene un 'rendering context' y es necesario activar cada contexto antes de dibujar algo en el. Para mayor informacin sobre los contextos en openGL, vase "OpenGL graphics with the X window system. Version 1.3 por Paula Womack y J ohn Leech". La solucin fue tener una operacin llamada Activa() dentro del rea grfica. boo1 C- Ar eaGr af i ca: : Act i va( Di spl ay *dpy, GLXDr awabl e dr awl voi d *ct x) { r et ur n gl XMakeCur r ent ( dpy, dr aw, ( GLXCont ext ) ct x) ; Del lado de las ventanas que tienen el rea grfica, se tiene que llamar a esta funcin desde RecibeEventoO, la funcin que aparte de DespachaCallback() se declara 'static' y que es el callback asignado a los eventos que ocurren en el rea grfica. (Ejemplo tomado de C-VentanaPrincipal) 63 i nt C- Vent anaPr i nci pal : : Reci beEvent o( FL - OBJ ECT *ob, Wi ndow wi n, i nt w, i nt h, XEvent *xev, voi d *Ud) { C - Vent anapr i nci pal *ApTemp; // Apunt ador t empor al ApTemp=( C- Vent anapr i nci pal *) ob- >f or m- >u- vdat a; / / Rescat a el t hi s ApTemp- >Pant al l a. Act i va( f l di spl ay, wi n, ApTemp- >f or ma- >canvas- >u vdat a) ; ApTemp- >Pant al l a. Cambi aTamZno ( w, h) ; ApTemp- >Ref r escaAr eaGr af i ca( ) ; // Envi a- act ual i zaci ones a l a pant al l a r et ur n O; Es necesario llamar a la operacin Activa desde aqui, ya que slo RecibeEventoO recibe los parmetros necesarios. Si se tienen mltiples reas grficas, se resuelve teniendo dentro de la clase un atributo que indique cual de las tres reas debe ser activada. 6.4 Desplegando imgenes con OpenGL. La aplicacin que hemos desarrollado consiste principalmente del despliegue de imgenes en areas de dos dimensiones. Aunque la librera OpenGL permite dibujar en 3D, hemos trabajado con formato de enteros (OpenGL permite trabajar mltiples formatos), con la esquina superior izquierda como origen (0,O). Sin embargo, al querer desplegar imgenes, OpenGL resulto no ser tn rapido como se esperaba. Aunque dispone de funciones que permiten desplegar un arreglo de puntos (en particular glDrawPixels()), estas funciones resultaron ser identicas en velocidad que el despliegue de la imagen 'punto por punto'. Finalmente fue ms til el despliegue punto a punto pues permitio el uso de funciones de escalado de imgenes. 6.5 Implementacin de itoa en una clase de funciones externas. Al querer mostrar un nmero en xforms, muchas veces es necesario desplegarlo como cadena. Sin embargo, la funcin 'itoa()' que cambia un entero a caracteres ASCII, no es una funcin 'estndar'. Para implementarla se creo una clase 'exclusiva' para ella, se llama CExterns. Est declarada como sigue: #i f ndef Ext er ns - C #def i ne Ext er ns- C cl ass C- Ext er ns I publ i c : 64 voi d i t oa( i nt , char *) ; // Convi er t e ent er o a asci i 1; #endi f As cuando se necesita llamar a la funcin, se hace uso de un objeto instanciado a partir de esta clase. Esta solucin es poco elegante, sin embargo, permite respetar el modelo. 6.6 Uso de 'make' para compilar la aplicacin. Para compilar la aplicacin hemos hecho uso de la herramienta 'make'. A continuacin se muestra el archivo 'makefile' que se empleo para la primera versin. # Makef i l e de l a apl i caci on de r econst r ucci on 3D por # Humber t o Cer vant es par a el pr oyect o t er mi nal 1998. # OBJ ECTS es una macr o que i ndi ca t odos l os obj et os de l os cual es depende # l a apl i caci on par a compi l ar se de maner a exi t osa. OBJ ECTS=Mai n. o Ap1i caci on. o Manej ador . 0 Vent anaPr i nci pa1. o Vent anaSe1Al gor i t mo. o St ack. 0 Di a1ogoAr chi vo. o 1magen. o Co1or . o Ar eaGr af i ca. 0 Vent anaConf St ack. ~ Vent anaConf St ackDi sp. 0 St ackConf i g. 0 Ext er ns C. 0 Co1ecci on. o Pr ocesador . 0 Pr ocSegUmbr a1. 0 Vent anaConf SegUmbr a1. 0 Hi st o5r ama. o Vent anaReconst r ucci on. ~ Pr ocReconst r ucci on. ~ Punt o. 0 Li st aLi gada. 0 Vo1umen. o Vent anaAcer caDe. 0 # A cont i nuaci on apar ecen macr os que i ndi can l as l i br er i as con l as cual es se # debe l i gar l a apl i caci on LI BFORMS=- L . . / FORMS - 1f or ms LI BOGL=- l X11 - l Xm- l GL # I NCXFORMS es una macr o que i ndi ca que di r ect or i os buscar par a i ncl ui r l os # ar chi vos de cabecer a de xf or ms. I NCXFORMS=- I . . / FORMS # VENTANAS es una macr o que i ndi ca t odos l os ar chi vos de l os cual es depende el # manej ador . VENTANAS=Vent ana. h Vent anaPr i nci pa1. h Vent anaSel A1gor i t mo. h Di a1ogoAr chi vo. h Vent anaC0nf St ack. h Vent anaConf SegUmbr a1. h Vent anaReconst r ucci on. h Vent anaAcer caDe. h #WARNI NGS si est a def i ni do como =- w no se most r ar an war ni ngs a l a hor a de compi l ar . . . WARNI NGS=- f ul l war n - 03 65 # - APLI CACI ON DE MANERA GLOBAL - Mai n: ${OBJ ECTS} CC - o $@ ${OBJ ECTS} SI LI BFORMS} St LI BOGL} - 1m # - I NDEPENDI ENTES DE SI STEMA DE VENTANA Y GRAFI COS - Mai n. ~: Mai n. cpp Ap1i caci on. h CC ${WARNI NGS} - c Mai n. cpp Ap1i caci on. o: Apl i caci on. cpp Ap1i caci on. h 0bj et oI nt . h Manej ador . 0 St ack. 0 Pr ocesador . 0 Li st aLi gada. 0 CC ${WARNI NGS} - c Apl i caci on. cpp Co1ecci on. o: Col ecci on. cpp Co1ecci on. h 0bj et oI nt . h 0bj et oModi f i cabl e. h Ar eaGr af i ca. 0 CC ${WARNI NGS} - c Col ecci on. cpp St ack. 0: St ack. cpp St ack. h Co1ecci on. o 1magen. o St ackConf i g. 0 Li st aLi gada. 0 CC ${WARNI NGS} - c St ack. cpp St ackConf i g. 0: St ackC0nf i g. h St ackConf i g. cpp CC ${WARNI NGS} - c St ackConf i g. cpp 1magen. o: 1magen. cpp 1magen. h Gener a1. h Li st aLi gada. 0 Dat oDeCo1ecci on. h CC ${WARNI NGS} - c 1magen. cpp Co1or . o: Col or . cpp Co1or . h Gener a1. h Li st aLi gada. 0 CC ${WARNI NGS} - c Col or . cpp Pr ocesador . ~: Pr ocesador . cpp Pr ocesad0r . h Pr oces0. h CC ${WARNI NGS} - c Pr ocesador . cpp Pr ocSegUmbr a1. 0: Pr ocSegUmbr al . cpp Pr ocSegUmbr a1. h Pr oces0. h CC ${WARNI NGS} - c Pr ocSegUmbr al . cpp Pr ocReconst r ucci on. ~: Pr ocReconst r ucci on. cpp Pr ocReconst r ucci on. h Pr oces0. h Vol umen. o CC ${WARNI NGS} - c Pr ocReconst r ucci on. cpp Hi st ogr ama. 0 : Hi st ogr ama. cpp Hi st 0gr ama. h 1magen. o CC ${WARNI NGS} - c Hi st ogr ama. cpp Punt o. 0 : Punt o. cpp Punt 0. h Gener a1. h Li st aLi gada. 0 Dat oDeCo1ecci on. h CC ${WARNI NGS} - c Punt o. cpp Li st aLi gada. 0 : Li st aLi gada. cpp Li st aLi 9ada. h Gener a1. h 66 CC ${WARNI NGS} - c Li st aLi gada. cpp Vo1umen. o : Vol umen. cpp Vo1umen. h Gener a1. h Punt o. 0 Co1or . o CC ${WARNI NGS} - c Vol umen. cpp # - EXTERNOS DE C- Ext er ns- C. o: Ext er ns- C. h Ext er ns- C. cpp CC ${WARNI NGS} - c Ext er ns- C. cpp # - CONTI ENEN COMANDOS DE XFORMS- Manej ador . 0: Manej ador . cpp Mane1ador . h 0bj et oI nt . h ${VENTANAS} CC ${I NCXFORMS} ${WARNI NGS} - c Manej ador . cpp Vent anaPr i nci pa1. 0: Vent anaPr i nci pal . cpp Vent anaPr i nci pa1. h Gener a1. h Vent ana. h Ap1i caci on. o Ar eaGr af i ca. 0 Col or . 0 CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaPr i nci pal . cpp Vent anaSe1Al gor i t mo. o: Vent anaSel Al gor i t mo. cpp Vent anaSel A1gor i t mo. h Gener a1. h Vent ana. h Ap1i caci on. o CC ${I NCXFORMS} ${WARNI NGS} - C Vent anaSel Al gor i t mo. cpp Vent anaConf St ack. 0: Vent anaConf St ack. cpp Vent anaC0nf St ack. h Gener a1. h Vent ana. h St ack. h CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaConf St ack. cpp Vent anaConf St ackDi sp. o: Vent anaConf St ackDi sp. cpp Vent anaC0nf St ackDi sp. h Gener a1. h Vent ana. h St ack. 0 St ackConf i g. ~ CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaConf St ackDi sp. cpp Vent anaConf SegUmbr a1. 0: Vent anaConf SegUmbr al . cpp Vent anaConf SegUmbr a1. h Gener a1. h Vent ana. h St ack. 0 St ackConf i g. 0 Ar eaGr af i ca. 0 Hi st ogr ama. 0 CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaConf SegUmbr al . cpp Di a1ogoAr chi vo. o: Di al ogoAr chi vo. cpp Di a1ogoAr chi vo. h Gener a1. h 0bj et oI nt . h Vent ana. h St ack. 0 CC ${I NCXFORMS} ${WARNI NGS} - c Di al ogoAr chi vo. cpp Vent anaReconst r ucci on. ~: Vent anaReconst r ucci on. cpp Vent anaReconst r ucci on. h Gener a1. h Vent ana. h Ar eaGr af i ca. 0 St ack. 0 Pr ocReconst r ucci on. ~ CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaReconct r ucci on. cpp Vent anaAcer caDe. 0: Vent anaAcer caDe. cpp Vent anaAcer caDe. h Gener a1. h St ack. h CC ${I NCXFORMS} ${WARNI NGS} - c Vent anaAcer caDe. cpp # - CONTI ENEN COMANDOS DE OPENGL- Ar eaGr af i ca. 0: Ar eaGr af i ca. cpp Ar eaGr af i ca. h Gener a1. h Co1or . o 1magen. o CC ${WARNI NGS} - c Ar eaGr af i ca. cpp 67 Notese que estan separados los archivos que se pueden compilar independientemente de las librerias, los que conciernen a xforms y finalmente aquellos que conciernen a openGL. 7.- Conclusiones. A raz del desarrollo de esta aplicacin, se obtuvo principalmente experiencia en el anlisis y desarrollo de aplicaciones orientadas a objetos. Se pudo comprobar que la metodologa propuesta por Booch es efectiva pues al final se llego a una aplicacin que cumpli los requerimientos propuestos. Algunas cuestiones que surgen a partir de esta experiencia son: La necesidad de hacer uso de las herramientas que generan cdigo: El hacer uso de la herramienta Rational Rose de manera incompleta impidio acelerar el proceso de desarrollo. Es importante pues tratar de aprovechar este tipo de herramientas que ahorran mucho trabajo, Los problemas de encapsular una libera de interfase de usuario dentro del modelo: La libera xforms es muy til. Sin embargo los problemas que surgieron tuvieron que ser resueltos de maneras poco 'elengantes', pues tener que escribir las funciones que despachan mensajes es algo de muy 'bajo' nivel que quita tiempo. Los 'trucos' para rescatar el apuntador 'this' y el contexto de OpenGL hacen que el cdigo no sea completamente claro. La solucin a esto sera emplear una librera orientada a objetos que no tenga problemas con el despliegue de grficos de OpengGL. La flexibilidad del lenauaie I C++' : El desarrollo de esta aplicacin permitio comprobar que el lenguaje I C++' es un lenguaje muy flexible y poderoso. Puede resultar complicado, pero se obtienen resultados buenos con su uso. Aun quedan algunos aspectos por probar de esta aplicacin. En particular, el poder comprobar si en verdad se puede adaptar a cualquier tipo de procesamiento que se necesite, y si se puede portar sin muchas dificultades. Estos dos puntos estn fuera del alcance de este proyecto, sin embargo esperamos algun da verlos llevados a cabo. 68 Bibliografa. Scott W. Ambler: The Object-Oriented Modeling Process: An Architecture Driven Approach. 30/07/97 www.ambysoft.com/ooModelingProcess.pdf The Unified Modeling Languakge V1.1 & Beyond: The techniques of O0 www.ambysoft.com/umlAndBeyond.pdf Modeling. 20/09/97 Bergner,Rausch,Sihling del Technishe Universitat Munchen. "Using UML for Modeling a Distributed J ava Application". TUM-I9735 J ulio 1997 Booch, Grady : Anlisis y diseo orientado a objetos con aplicaciones. Addison Wesley (c) 1996 Object Solutions. Managing the Object Oriented Project Addison Wesley (c) 1996 Gamma, Helm, J ohnson, Vlissides : "Design Patterns - Elements of reusable Object Oriented Software" (c) 1995, Addison Wesley. Neider, Davis, Woo : OpenGL programming guide - The official guide to learning OpenGL rel. 1 A. Wesley (c) 1993 Wiegers. : Software Development Magazine p50-55, Marzo de 1997 www.sdmagazine.com 69 Versin 1.0 Dara UNl X Gua del Usuario POR Humbeno Cervantes Maceda 3DOo Versin 1.0 : Gua del usuario. Indice: 1 .- Instalando y ejecutando 3Doo ......................................................... 1 2.- Cargar un archivo ............................................................................ 2 4.- Aplicando un proceso. ..................................................................... 5 4.1 - Segmentacin por Umbral ................................................. 5 4.2 - Reconstruccion.. ................................................................ .7 5.- Extras ............................................................................................... 8 3 .- Modificacin del despliegue. .......................................................... 4 ., 1.- Instalando y ejecutando 3Doo. El programa 3D00 esta diseado para correr en computadoras con ambiente grfico. La versin para UNIX emplea una librera llamada xforms que facilita la creacin de interfaces grficas, y que emplea el protocolo Xwindow. Para poder correr el programa 3Doo se necesita tener las libreras xforms y OpenGL disponibles. Si estas ya se encuentran instaladas, es necesario configurar una variable de ambiente con la ruta de las libreras xforms, el nombre de la variable es: LD - LIBRARY - PATH Para ksh el comando para configurar esto es: $ LDLIBRARYPATH=/directorio $ export $LD-LIBRARY-PATH Para csh el comando para configurar esto es: YO setenv LD-LIBRARY-PATH /directorio La instalacin del programa 3Doo es sencilla. Basta con tener el programa ejecutable en el directorio deseado y correrlo. $ Main Aparece entonces una ventana vaca que presenta un men en la parte superior: 1 Las opciones del men son: 0 Archivo Proceso Despliegue Ayuda En este momento esta listo el programa para ser utilizado. A continuacin se explica cmo cargar un archivo. 2.- Carpar un archivo. Presionar sobre el men archivo y enseguida sobre la opcin Cargar, aparece entonces una ventana de seleccin de archivos: 2 Nota: La versin 1 .O slo soporta archivos tipo crudo, es decir que contienen nicamente la informacin de las imgenes. Los de 1 y 2 bytes deben contener informacin de tonos de gris. Los de 3 bytes deben contener triadas (rojo, verde, azul) y permiten el despliegue de imgenes de color. La extensin no es importante. Una vez que se ha seleccionado el stack de imgenes a cargar, aparece la ventana de configuracin del archivo: Se deben introducir de forma obligatoria el nmero de imgenes, el tamao de la imagen, y los bytes por pixel. Los otros campos son optativos en esta versin y no afectan el uso del programa. Cuando se han introducido los datos correctamente, el programa comienza a cargar y si esta operacin se realiza de manera exitosa, debe aparecer en la parte inferior derecho un pequeo cuadro verde que dice ok, y en el rea de comentarios debe aparecer la lnea listo. A continuacin se muestra una conjunto de imgenes que han sido cargados correctamente: 3 3.- Modificacin del despliepue. Una vez que hemos cargado un conjunto de imgenes, estas se muestran al 100 % de su tamao original, y posiblemente no aparezcan todas las imgenes que componen al stack, podemos modificar ciertos parmetros de despliegue que nos permitirn apreciar con mayor claridad alguna imagen en particular o el conjunto de las imgenes. Si queremos ver una imagen en particular, nos podemos mover mediante las flechas de la parte inferior izquierda hasta esa imagen y entonces presionar sobre el boton de zoom. La imagen en particular aparecer sola en la pantalla y la aplicacin tratar de ajustarla al mximo tamao posible sin distorsionarla. En la parte inferior derecha, el status pasara a zoom y el color de fondo del aviso ser azul (cyan). A continuacin se muestra una imagen en modo zoom. En este modo se puede recorrer todo el stack mediante las flechas de posicin del cursor. Sin embargo, puede resultar lento recorrer el stack de esta forma, para ver todo el stack en su conjunto, debemos presionar en el men despliegue y enseguida seleccionar la opcin configurar. Nos debe aparecer una ventana como la siguiente: 4 En esta ventana de configuracin del stack, se puede seleccionar la imagen inicial a desplegar. Por omisin este valor es igual a 1. La escala de despliegue tambin se puede configurar y al mover el control concerniente a este valor, la lnea que dice con esta escala se desplegaran ... imgenes se actualizar automticamente para mostrar la cantidad de imgenes que aparecern en el despliegue. Es posible configurar tambin la intensidad con que se despliegan las imgenes, el valor por omisin de este parmetro es igual a 100%. En la versin 1 .O, las imgenes siempre aparecen con marco, y su numeracin aparece en el lado inferior izquierdo de la ventana principal, por lo cual los botones de poner marco y numerar imgenes no cumplen ninguna funcin. Cuando se presiona listo, el control regresa a la ventana principal, y esta debe reflejar los cambios que se hayan seleccionado. 4.- Aplicando un proceso. Para aplicar un proceso, este debe ser seleccionado primero. Para ello presionar en el men proceso la opcin seleccionar proceso, debe aparecer una ventana como la siguiente: 4.1 Segmentacin por umbral. En la versin 1.0 slo aparecen dos tipos de procesos: La segmentacin por umbral y la reconstruccin. Para realizar el segundo, se debe primero hacer una segmentacin. Si se selecciona la opcin de segmentacin por Umbral, aparecer la ventana de configuracin del algoritmo, similar a la siguiente: 5 Podemos ver que esta ventana muestra dos imgenes, un histograma y varios controles. La imagen a la izquierda es con la que se est trabajando. Se puede cambiar de imagen mediante el control de la parte inferior que dice imagen actual. Al cambiar de imagen, el histograma se actualiza de manera automtica. La imagen segmentada muestra el resultado de la segmentacin por umbral de la imagen actual de acuerdo a los limites establecidos dentro del histograma. Para actualizar esta imagen, se debe presionar sobre segmentar actual. Para mover los limites dentro del histograma, basta mover los dos controles de seleccin. El superior corresponde al limite izquierdo, y el inferior al derecho. Los limites aparecen dentro del histograma como lneas amarillas que de un lado dejan ver el histograma y del otro reducen todos los valores a cero. Si se desea ver algun detalle del histograma, se pueden hacer agrandamientos de los valores, esto al presionar los botones [+I y [-I del zoom para X o para Y. Una vez que se esta conforme con los limites seleccionados, basta presionar aplicar, y en la esquina inferior izquierda aparecer un contador que muestra la progresin del algoritmo. Cuando este llegue a 100% estar terminado. La ventana de configuracin desaparece y el control regresa a la ventana principal, sin embargo ahora se muestra el resultado de la segmentacin, es posible efectuar cambios en el despliegue de este stack de la misma forma que para el stack original. 6 Si se desea volver al stack original, en el men despliegue habr aparecido que dice stack #1. El stack #O corresponde al original, el #1 al segmentado. A continuacin se muestra un stack segmentado: una lnea extra 4.2 Reconstruccin. Si ahora deseamos realizar una reconstruccin, seleccionamos de nuevo proceso, pero esta vez seleccionamos Contorno/Reconstruccin. Cuando seleccionamos este proceso, aparece la ventana apropiada. En este proceso no se necesitan configurar parmetros, al aparecer la ventana, comienza el calculo de contornos y despus el de normales. Cuando termina este proceso aparece la reconstruccin. A continuacin se muestra la ventana correspondiente a este proceso: 7 En esta ventana aparecen tres reas grficas. Las dos de la izquierda muestran los cortes originales y sus contornos correspondientes. Es posible recorrer el conjunto de imgenes con el control. En el recuadro junto a la palabra Contorno aparece el nmero de imagen que se est desplegando. En el rea grfica principal, aparece el resultado de la reconstruccin. Al centro se muestra el origen con ejes de tres colores, el eje X se muestra de color rojo, Y en verde y Z en azul. Del lado derecho se puede controlar la rotacin, la translacin y el zoom de la imagen. Los campos que muestran los valores pueden ser modificados directamente para evitar tener que presionar muchas veces sobre los controles +y -. Cuando uno decide salir de la reconstruccin aparece en la ventana principal el conjunto de contornos, que puede ser manipulado de igual forma que el segmentado. 5. Extras. Para salir de la aplicacin basta presionar el botn marcado con una X La opcin ayuda del men principal nos muestra una opcin acerca de que al ser seleccionada hace aparecer la ventana siguiente: La versin 1 .O no tiene una ayuda formal. Sin embargo se puede consultar todo lo referente al programa en la siguiente direccin de internet. htip://itzamna.uam.m~umberto~OCUMENTACION/Indice. html Cualquier comentario es bienvenido a la direccin de correo siguiente: hcc(u,h~9000al .uam.mx 8